coretrace-python-analyzer 0.17.0__py3-none-any.whl → 0.18.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- coretrace_python/__init__.py +1 -1
- coretrace_python/taint/engine.py +15 -4
- coretrace_python/taint/models.py +7 -2
- coretrace_python/taint/templates.py +11 -2
- {coretrace_python_analyzer-0.17.0.dist-info → coretrace_python_analyzer-0.18.0.dist-info}/METADATA +1 -1
- {coretrace_python_analyzer-0.17.0.dist-info → coretrace_python_analyzer-0.18.0.dist-info}/RECORD +10 -10
- {coretrace_python_analyzer-0.17.0.dist-info → coretrace_python_analyzer-0.18.0.dist-info}/WHEEL +0 -0
- {coretrace_python_analyzer-0.17.0.dist-info → coretrace_python_analyzer-0.18.0.dist-info}/entry_points.txt +0 -0
- {coretrace_python_analyzer-0.17.0.dist-info → coretrace_python_analyzer-0.18.0.dist-info}/licenses/LICENSE +0 -0
- {coretrace_python_analyzer-0.17.0.dist-info → coretrace_python_analyzer-0.18.0.dist-info}/licenses/NOTICE +0 -0
coretrace_python/__init__.py
CHANGED
coretrace_python/taint/engine.py
CHANGED
|
@@ -835,7 +835,8 @@ def function_entry_point(
|
|
|
835
835
|
project: SummaryIndex | None = None,
|
|
836
836
|
) -> EntryPoint | None:
|
|
837
837
|
"""The entry point ``function`` is: one of its decorators or, for a method, one of its
|
|
838
|
-
class's bases matching an entry-point model,
|
|
838
|
+
class's bases matching an entry-point model, a registration elsewhere (``routes``), or
|
|
839
|
+
a model naming the function, or its class, by its own project symbol."""
|
|
839
840
|
|
|
840
841
|
owner = _owner(module, function)
|
|
841
842
|
enclosing_function = _enclosing(module, function)
|
|
@@ -843,14 +844,22 @@ def function_entry_point(
|
|
|
843
844
|
# ``app = Flask(__name__)`` inside ``create_app``: routes defined there resolve.
|
|
844
845
|
instances = {**(instances or {}), **local_instances(enclosing_function, scopes, symbols)}
|
|
845
846
|
entry = entry_point_of(function, models, scopes, symbols, owner, instances, project)
|
|
846
|
-
if entry is None
|
|
847
|
+
if entry is None:
|
|
847
848
|
qualified = function.name if owner is None else f"{owner.name}.{function.name}"
|
|
848
|
-
entry =
|
|
849
|
+
entry = _declared(project_symbol(module.name, qualified), models, routes)
|
|
849
850
|
if entry is None and owner is not None:
|
|
850
|
-
entry =
|
|
851
|
+
entry = _declared(project_symbol(module.name, owner.name), models, routes)
|
|
851
852
|
return entry
|
|
852
853
|
|
|
853
854
|
|
|
855
|
+
def _declared(symbol: SymbolId, models: ModelTable, routes: Routes | None) -> EntryPoint | None:
|
|
856
|
+
"""The entry point a project ``symbol`` is: registered as a handler, or named by a
|
|
857
|
+
model."""
|
|
858
|
+
|
|
859
|
+
registered = routes.get(symbol) if routes else None
|
|
860
|
+
return registered if registered is not None else models.entry_point(symbol)
|
|
861
|
+
|
|
862
|
+
|
|
854
863
|
def _owner(module: nodes.Module, function: nodes.Function) -> nodes.Class | None:
|
|
855
864
|
"""The top-level class ``function`` is a method of, if any."""
|
|
856
865
|
|
|
@@ -891,6 +900,8 @@ def parameter_sources(
|
|
|
891
900
|
for index in range(first, len(function.parameters)):
|
|
892
901
|
if index - first < len(roles) and roles[index - first] is not None:
|
|
893
902
|
continue
|
|
903
|
+
if entry.inputs is not None and index - first not in entry.inputs:
|
|
904
|
+
continue
|
|
894
905
|
annotation = function.parameters[index].annotation
|
|
895
906
|
text = (request is not None and index > first) or (
|
|
896
907
|
annotation is not None and _scalar(annotation, symbols, enclosing)
|
coretrace_python/taint/models.py
CHANGED
|
@@ -110,12 +110,17 @@ class Sanitizer:
|
|
|
110
110
|
|
|
111
111
|
@dataclass(frozen=True)
|
|
112
112
|
class EntryPoint:
|
|
113
|
-
"""Functions decorated by ``symbol``,
|
|
114
|
-
|
|
113
|
+
"""Functions decorated by ``symbol``, methods of classes deriving from it, and, when
|
|
114
|
+
``symbol`` names a project function or class, that function or the class's methods
|
|
115
|
+
receive attacker-controlled parameters: those at ``inputs``, by position after
|
|
116
|
+
``self`` for a method, or every parameter when ``inputs`` is None. A deployment
|
|
117
|
+
declaration an integration reads names a Lambda handler this way, whose event is
|
|
118
|
+
input and whose context is not."""
|
|
115
119
|
|
|
116
120
|
symbol: SymbolId
|
|
117
121
|
label: str
|
|
118
122
|
kinds: TaintKind = TaintKind.ALL
|
|
123
|
+
inputs: tuple[int, ...] | None = None
|
|
119
124
|
|
|
120
125
|
|
|
121
126
|
@dataclass(frozen=True)
|
|
@@ -15,7 +15,8 @@ it extends or includes, can output data unescaped:
|
|
|
15
15
|
|
|
16
16
|
Templates are found under the project's ``templates`` directories, by their path below
|
|
17
17
|
one. A template the engine cannot find — named by an expression, under a ``DIRS`` entry
|
|
18
|
-
of another name, shipped by an installed package — is never assumed to
|
|
18
|
+
of another name, shipped by an installed package — or cannot read is never assumed to
|
|
19
|
+
escape.
|
|
19
20
|
|
|
20
21
|
A template applying a filter of Django's own libraries calls the function behind it
|
|
21
22
|
whenever it is rendered, though no Python call names that function: ``{{ bio|striptags }}``
|
|
@@ -149,7 +150,7 @@ def escaped_templates(root: Path) -> frozenset[str]:
|
|
|
149
150
|
local: dict[str, bool] = {}
|
|
150
151
|
requires: dict[str, set[str]] = {}
|
|
151
152
|
for name, paths in found.items():
|
|
152
|
-
verdicts = [
|
|
153
|
+
verdicts = [_verdict(path) for path in paths]
|
|
153
154
|
local[name] = all(safe for safe, _ in verdicts)
|
|
154
155
|
requires[name] = {needed for _, needs in verdicts for needed in needs}
|
|
155
156
|
escaped = {name for name, safe in local.items() if safe}
|
|
@@ -171,6 +172,14 @@ def _read(path: Path) -> str:
|
|
|
171
172
|
return _text(path) or ""
|
|
172
173
|
|
|
173
174
|
|
|
175
|
+
def _verdict(path: Path) -> tuple[bool, set[str]]:
|
|
176
|
+
"""Whether one template file escapes all it prints, and what it needs: a file the
|
|
177
|
+
engine cannot read is not established to escape, like a template it cannot find."""
|
|
178
|
+
|
|
179
|
+
text = _text(path)
|
|
180
|
+
return (False, set()) if text is None else _inspect(text)
|
|
181
|
+
|
|
182
|
+
|
|
174
183
|
def _text(path: Path) -> str | None:
|
|
175
184
|
"""The text of ``path``, or None when it cannot be read."""
|
|
176
185
|
|
{coretrace_python_analyzer-0.17.0.dist-info → coretrace_python_analyzer-0.18.0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: coretrace-python-analyzer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.0
|
|
4
4
|
Summary: Static security analysis infrastructure for Python code
|
|
5
5
|
Project-URL: Homepage, https://github.com/CoreTrace/coretrace-python-analyzer
|
|
6
6
|
Project-URL: Repository, https://github.com/CoreTrace/coretrace-python-analyzer
|
{coretrace_python_analyzer-0.17.0.dist-info → coretrace_python_analyzer-0.18.0.dist-info}/RECORD
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
coretrace_python/__init__.py,sha256=
|
|
1
|
+
coretrace_python/__init__.py,sha256=UXlC7yIk3dOxWBAjttYzugsg0Cacccz_IG6V-LsaqSU,76
|
|
2
2
|
coretrace_python/__main__.py,sha256=V8DnYtRboISK2VCKm7DGHLREKvqLbqApyWlKBOs26wU,65
|
|
3
3
|
coretrace_python/cache.py,sha256=-pZv-ELm4jMCTXQWSZIobHaT9UHIjFu7IlMkOM0i4LI,13607
|
|
4
4
|
coretrace_python/cli.py,sha256=G5jhb6g6RgSRSjjS7DBgziIjUM1vTFwalJGvFHVKxrg,11225
|
|
@@ -144,14 +144,14 @@ coretrace_python/source/__init__.py,sha256=0Y8fvtbkETnNCJR9Zq7RS5TSgF9c22pz3SSk1
|
|
|
144
144
|
coretrace_python/source/manager.py,sha256=JRmMOcWfS1nocbVrdcvfQTqEfIkmnb5JP857TpGywN4,2736
|
|
145
145
|
coretrace_python/source/model.py,sha256=FZnN5mlir3tzbIpWoxnn6YtRi9UcJ_y0sZM60tKr8U4,1727
|
|
146
146
|
coretrace_python/taint/__init__.py,sha256=nKpD33_4IRneAkd3Dt-j7Q-cHl47rDA_eLZFDHZVH28,1827
|
|
147
|
-
coretrace_python/taint/engine.py,sha256=
|
|
148
|
-
coretrace_python/taint/models.py,sha256=
|
|
147
|
+
coretrace_python/taint/engine.py,sha256=BHNdoyUryK9lDOZ-lq235GdTC9SDbeUHquoDH2DDCM8,49457
|
|
148
|
+
coretrace_python/taint/models.py,sha256=pCvE-6dYKYSLK7pylxhLWpeUcMfMyXlh_1VUJbzieo8,20405
|
|
149
149
|
coretrace_python/taint/routes.py,sha256=UAJKXcw_sM9shf58FfDroxVO9bNSm4qrQdZknwUB0lo,6110
|
|
150
|
-
coretrace_python/taint/templates.py,sha256=
|
|
150
|
+
coretrace_python/taint/templates.py,sha256=74y06rKs2F0cCOqRw_jbKwlZ8M4nUgsatOFX5ZWkRNQ,31344
|
|
151
151
|
coretrace_python/taint/urls.py,sha256=kb0-uOT12ww7R3Jzs_lPKg9lFs74JI-bpa9pXX105xM,3166
|
|
152
|
-
coretrace_python_analyzer-0.
|
|
153
|
-
coretrace_python_analyzer-0.
|
|
154
|
-
coretrace_python_analyzer-0.
|
|
155
|
-
coretrace_python_analyzer-0.
|
|
156
|
-
coretrace_python_analyzer-0.
|
|
157
|
-
coretrace_python_analyzer-0.
|
|
152
|
+
coretrace_python_analyzer-0.18.0.dist-info/METADATA,sha256=UknDXxCfvCkshCAt4gMWAGWWGp_SzsiN9laP98Gq9qo,3217
|
|
153
|
+
coretrace_python_analyzer-0.18.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
154
|
+
coretrace_python_analyzer-0.18.0.dist-info/entry_points.txt,sha256=wdozemiraOkbt65g_Y_zgspuZpoLxJdaCVMJt1Ft3c0,72
|
|
155
|
+
coretrace_python_analyzer-0.18.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
156
|
+
coretrace_python_analyzer-0.18.0.dist-info/licenses/NOTICE,sha256=s3VHj5ngV0ozjW_kZJpg_35ne6JwoBK0ysOjbqVtA0w,113
|
|
157
|
+
coretrace_python_analyzer-0.18.0.dist-info/RECORD,,
|
{coretrace_python_analyzer-0.17.0.dist-info → coretrace_python_analyzer-0.18.0.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|