defunannotated(): # implictly returns `Any` returnb"" + ""# function body is not checked
defannotated() -> List: # explicit return annotation means we type check `annotated` any = unannotated() any.attribute # `Any` has all possible attributes return1# Error: returning `int` but expecting `List`
defsecret_eval(request: HttpRequest): os = importlib.import_module("os") # Pysa won't know what 'os' is, and thus won't # catch this remote code execution issue os.system(request.GET["command"])
(tutorial) jck@analysis:~/pyre-check/documentation/pysa_tutorial/exercise1$ pyre analyze ƛ No cached overrides loaded, computing overrides... ƛ `google.protobuf.message.Message.ClearField` has 57 overrides, this might slow down the analysis considerably. ƛ `google.protobuf.message.Message.__init__` has 58 overrides, this might slow down the analysis considerably. ƛ `object.__eq__` has 82 overrides, this might slow down the analysis considerably. ƛ `object.__init__` has 754 overrides, this might slow down the analysis considerably. ƛ `object.__ne__` has 60 overrides, this might slow down the analysis considerably. ƛ `type.__call__` has 131 overrides, this might slow down the analysis considerably. ƛ `type.__init__` has 448 overrides, this might slow down the analysis considerably. ƛ `type.__new__` has 75 overrides, this might slow down the analysis considerably. [ { "line": 12, "column": 18, "stop_line": 12, "stop_column": 35, "path": "views.py", "code": 5001, "name": "Possible RCE:", "description": "Possible RCE: [5001]: User specified data may reach a code execution sink", "long_description": "Possible RCE: [5001]: User specified data may reach a code execution sink", "concise_description": "Possible RCE: [5001]: User specified data may reach a code execution sink", "inference": null, "define": "views.operate_on_twos" } ]
(tutorial) jck@analysis:~/pyre-check/documentation/pysa_tutorial/exercise2$ pyre analyze ƛ No cached overrides loaded, computing overrides... ƛ `google.protobuf.message.Message.ClearField` has 57 overrides, this might slow down the analysis considerably. ƛ `google.protobuf.message.Message.__init__` has 58 overrides, this might slow down the analysis considerably. ƛ `object.__eq__` has 82 overrides, this might slow down the analysis considerably. ƛ `object.__init__` has 754 overrides, this might slow down the analysis considerably. ƛ `object.__ne__` has 60 overrides, this might slow down the analysis considerably. ƛ `type.__call__` has 131 overrides, this might slow down the analysis considerably. ƛ `type.__init__` has 448 overrides, this might slow down the analysis considerably. ƛ `type.__new__` has 75 overrides, this might slow down the analysis considerably. [ { "line": 30, "column": 34, "stop_line": 30, "stop_column": 56, "path": "views.py", "code": 5002, "name": "Possible RCE:", "description": "Possible RCE: [5002]: User specified data may reach a shell execution sink", "long_description": "Possible RCE: [5002]: User specified data may reach a shell execution sink", "concise_description": "Possible RCE: [5002]: User specified data may reach a shell execution sink", "inference": null, "define": "views.operate_on_fours" }, { "line": 22, "column": 9, "stop_line": 22, "stop_column": 35, "path": "views.py", "code": 5001, "name": "Possible RCE:", "description": "Possible RCE: [5001]: User specified data may reach a code execution sink", "long_description": "Possible RCE: [5001]: User specified data may reach a code execution sink", "concise_description": "Possible RCE: [5001]: User specified data may reach a code execution sink", "inference": null, "define": "views.operate_on_threes" }, { "line": 14, "column": 18, "stop_line": 14, "stop_column": 35, "path": "views.py", "code": 5001, "name": "Possible RCE:", "description": "Possible RCE: [5001]: User specified data may reach a code execution sink", "long_description": "Possible RCE: [5001]: User specified data may reach a code execution sink", "concise_description": "Possible RCE: [5001]: User specified data may reach a code execution sink", "inference": null, "define": "views.operate_on_twos" } ]
ƛ Finding taint models in `/home/jck/pyre-check/stubs/taint, /home/jck/pyre-check/documentation/pysa_tutorial/exercise3`.ƛ Found 93 model verification errors! ...
... ƛ No cached overrides loaded, computing overrides... ƛ `google.protobuf.message.Message.ClearField` has 57 overrides, this might slow down the analysis considerably. ƛ `google.protobuf.message.Message.__init__` has 58 overrides, this might slow down the analysis considerably. ƛ Iteration #2. 4 Callables [zipfile.ZipFile::__init__ (override), str::format (override), shelve.Shelf::__init__ (overri[]
exercise4
使用 SAPP (Static Analysis Post Processor) 提供的交互式命令行。
defdo_and(request: HttpRequest) -> HttpResponse: left = bool(request.GET["left"]) right = bool(request.GET["right"]) result = eval(f"{left} and {right}") # noqa: P204 return result
defdo_or(request: HttpRequest) -> HttpResponse: left = request.GET["left"] right = request.GET["right"] assert_numeric(left) assert_numeric(right) result = eval(f"{left} or {right}") # noqa: P204 return result
{ "sources":[], "sinks":[], "features":[ { "name":"example", "comment":"Copy this feature and write your own. Don't forget that JSON lists are comma seperated!" } ], "rules":[] }
... ƛ No cached overrides loaded, computing overrides... ƛ `google.protobuf.message.Message.ClearField` has 57 overrides, this might slow down the analysis considerably. ƛ `google.protobuf.message.Message.__init__` has 58 overrides, this might slow down the analysis considerably. ƛ Iteration #2. 4 Callables [zipfile.ZipFile::__init__ (override), str::format (override), shelve.Shelf::__init__ (overri[]
import importlib import sys from pathlib import Path from urls import UrlPattern
# Make sure we're able to import dependencies in 'pyre-check' repo, since they # are not currently in the PyPI package for pyre-check current_file = Path(__file__).absolute() sys.path.append(str(current_file.parents[4]))
# Work around '-' in the name of 'pyre-check' generate_taint_models = importlib.import_module( "pyre-check.tools.generate_taint_models" ) view_generator = importlib.import_module( "pyre-check.tools.generate_taint_models.view_generator" ) generator_specifications = importlib.import_module( "pyre-check.tools.generate_taint_models.generator_specifications" )
classIgnore: pass
defmain() -> None: # Here, specify all the generators that you might want to call. generators = { "django_path_params": generate_taint_models.RESTApiSourceGenerator( django_urls=view_generator.DjangoUrls( urls_module="urls", url_pattern_type=UrlPattern, url_resolver_type=Ignore, ) ), # "decorator_extracted_params": generate_taint_models.<GENERATOR_NAME>( # root=".", # annotation_specifications=[ # generate_taint_models.DecoratorAnnotationSpecification( # decorator=<DECORATOR_NAME_INCLUDING_PRECEEDING_@>, # annotations=generator_specifications.default_entrypoint_taint, # ) # ], # ), } # The `run_generators` function will take care of parsing command-line arguments, as # well as executing the generators specified in `default_modes` unless you pass in a # specific set from the command line. generate_taint_models.run_generators( generators, default_modes=[ "django_path_params", # "decorator_extracted_params" ], )
if __name__ == "__main__": main()
利用 generate_models.py 动态生成 .pysa 文件。
1
python generate_models.py --output-directory .
报错 graphql3 模块没有找到,将文件中的 graphql3 改为 graphql:
1 2
vim /home/jck/pyre-check/tools/generate_taint_models/get_dynamic_graphql_sources.py # from graphql import GraphQLSchema
(tutorial) jck@analysis:~/pyre-check/documentation/pysa_tutorial/exercise5$ python generate_models.py --output-directory . 2021-07-07 03:24:56 INFO Computing models for `django_path_params` 2021-07-07 03:24:56 INFO Getting all URLs from `urls` 2021-07-07 03:24:56 INFO Computed models for `django_path_params` in 0.000 seconds. {"number of generated models": 1}
defmain() -> None: # Here, specify all the generators that you might want to call. generators = { "django_path_params": generate_taint_models.RESTApiSourceGenerator( django_urls=view_generator.DjangoUrls( urls_module="urls", url_pattern_type=UrlPattern, url_resolver_type=Ignore, ) ), "decorator_extracted_params": generate_taint_models.AnnotatedFreeFunctionWithDecoratorGenerator( root=".", annotation_specifications=[ generate_taint_models.DecoratorAnnotationSpecification( decorator="@api_wrapper", annotations=generator_specifications.default_entrypoint_taint, ) ], ), } # The `run_generators` function will take care of parsing command-line arguments, as # well as executing the generators specified in `default_modes` unless you pass in a # specific set from the command line. generate_taint_models.run_generators( generators, default_modes=[ "django_path_params", "decorator_extracted_params" ], )