coretrace-python-analyzer 0.1.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 +4 -0
- coretrace_python/__main__.py +4 -0
- coretrace_python/abstract/__init__.py +45 -0
- coretrace_python/abstract/constants.py +226 -0
- coretrace_python/abstract/heap.py +252 -0
- coretrace_python/abstract/ranges.py +285 -0
- coretrace_python/abstract/values.py +56 -0
- coretrace_python/analysis/__init__.py +31 -0
- coretrace_python/analysis/manager.py +165 -0
- coretrace_python/analysis/provider.py +73 -0
- coretrace_python/bundled/dependency/dependency_policy/dependency_policy.py +46 -0
- coretrace_python/bundled/dependency/dependency_policy/plugin.toml +9 -0
- coretrace_python/bundled/dependency/reachable_vulnerability/plugin.toml +9 -0
- coretrace_python/bundled/dependency/reachable_vulnerability/reachable_vulnerability.py +56 -0
- coretrace_python/bundled/dependency/sample_advisories/plugin.toml +9 -0
- coretrace_python/bundled/dependency/sample_advisories/sample_advisories.py +109 -0
- coretrace_python/bundled/dependency/vulnerable_dependency/plugin.toml +9 -0
- coretrace_python/bundled/dependency/vulnerable_dependency/vulnerable_dependency.py +43 -0
- coretrace_python/bundled/models/cli/cli_models.py +35 -0
- coretrace_python/bundled/models/cli/plugin.toml +9 -0
- coretrace_python/bundled/models/credentials/credential_models.py +43 -0
- coretrace_python/bundled/models/credentials/plugin.toml +9 -0
- coretrace_python/bundled/models/django/django_models.py +123 -0
- coretrace_python/bundled/models/django/plugin.toml +9 -0
- coretrace_python/bundled/models/fastapi/fastapi_models.py +29 -0
- coretrace_python/bundled/models/fastapi/plugin.toml +9 -0
- coretrace_python/bundled/models/flask/flask_models.py +53 -0
- coretrace_python/bundled/models/flask/plugin.toml +9 -0
- coretrace_python/bundled/models/http_clients/http_client_models.py +43 -0
- coretrace_python/bundled/models/http_clients/plugin.toml +9 -0
- coretrace_python/bundled/models/python_stdlib/plugin.toml +9 -0
- coretrace_python/bundled/models/python_stdlib/python_stdlib.py +68 -0
- coretrace_python/bundled/models/sqlalchemy/plugin.toml +9 -0
- coretrace_python/bundled/models/sqlalchemy/sqlalchemy_models.py +47 -0
- coretrace_python/bundled/secrets/config_secrets/config_secrets.py +38 -0
- coretrace_python/bundled/secrets/config_secrets/plugin.toml +9 -0
- coretrace_python/bundled/secrets/hardcoded_secrets/hardcoded_secrets.py +19 -0
- coretrace_python/bundled/secrets/hardcoded_secrets/plugin.toml +9 -0
- coretrace_python/bundled/security/command_injection/command_injection.py +17 -0
- coretrace_python/bundled/security/command_injection/plugin.toml +9 -0
- coretrace_python/bundled/security/insecure_deserialization/insecure_deserialization.py +17 -0
- coretrace_python/bundled/security/insecure_deserialization/plugin.toml +9 -0
- coretrace_python/bundled/security/open_redirect/open_redirect.py +17 -0
- coretrace_python/bundled/security/open_redirect/plugin.toml +9 -0
- coretrace_python/bundled/security/path_traversal/path_traversal.py +17 -0
- coretrace_python/bundled/security/path_traversal/plugin.toml +9 -0
- coretrace_python/bundled/security/plaintext_credentials/plaintext_credentials.py +21 -0
- coretrace_python/bundled/security/plaintext_credentials/plugin.toml +9 -0
- coretrace_python/bundled/security/sql_injection/plugin.toml +9 -0
- coretrace_python/bundled/security/sql_injection/sql_injection.py +17 -0
- coretrace_python/bundled/security/ssrf/plugin.toml +9 -0
- coretrace_python/bundled/security/ssrf/ssrf.py +17 -0
- coretrace_python/bundled/security/xss/plugin.toml +9 -0
- coretrace_python/bundled/security/xss/xss.py +17 -0
- coretrace_python/bundled/syntax/dangerous_eval/dangerous_eval.py +19 -0
- coretrace_python/bundled/syntax/dangerous_eval/plugin.toml +9 -0
- coretrace_python/bundled/syntax/flask_debug/flask_debug.py +63 -0
- coretrace_python/bundled/syntax/flask_debug/plugin.toml +9 -0
- coretrace_python/bundled/syntax/missing_timeout/missing_timeout.py +51 -0
- coretrace_python/bundled/syntax/missing_timeout/plugin.toml +9 -0
- coretrace_python/bundled/syntax/weak_crypto/plugin.toml +9 -0
- coretrace_python/bundled/syntax/weak_crypto/weak_crypto.py +19 -0
- coretrace_python/cache.py +310 -0
- coretrace_python/cfg/__init__.py +46 -0
- coretrace_python/cfg/builder.py +589 -0
- coretrace_python/cfg/dominance.py +183 -0
- coretrace_python/cfg/model.py +166 -0
- coretrace_python/cli.py +216 -0
- coretrace_python/dataflow/__init__.py +29 -0
- coretrace_python/dataflow/lattice.py +78 -0
- coretrace_python/dataflow/solver.py +96 -0
- coretrace_python/dependency/__init__.py +44 -0
- coretrace_python/dependency/advisories.py +168 -0
- coretrace_python/dependency/correlation.py +87 -0
- coretrace_python/dependency/graph.py +274 -0
- coretrace_python/dependency/policy.py +65 -0
- coretrace_python/dependency/sbom.py +65 -0
- coretrace_python/engine.py +688 -0
- coretrace_python/findings/__init__.py +13 -0
- coretrace_python/findings/coverage.py +45 -0
- coretrace_python/findings/model.py +49 -0
- coretrace_python/findings/refutation.py +427 -0
- coretrace_python/frontend/__init__.py +18 -0
- coretrace_python/frontend/ast_adapter.py +447 -0
- coretrace_python/frontend/parser.py +23 -0
- coretrace_python/hir/__init__.py +5 -0
- coretrace_python/hir/nodes.py +584 -0
- coretrace_python/hir/visitors.py +36 -0
- coretrace_python/interprocedural/__init__.py +49 -0
- coretrace_python/interprocedural/callgraph.py +291 -0
- coretrace_python/interprocedural/modulegraph.py +218 -0
- coretrace_python/interprocedural/summaries.py +463 -0
- coretrace_python/ir/__init__.py +5 -0
- coretrace_python/ir/defuse.py +74 -0
- coretrace_python/ir/lowering.py +575 -0
- coretrace_python/ir/model.py +481 -0
- coretrace_python/ir/printer.py +201 -0
- coretrace_python/ir/ssa.py +277 -0
- coretrace_python/plugins/__init__.py +58 -0
- coretrace_python/plugins/api.py +153 -0
- coretrace_python/plugins/detectors.py +114 -0
- coretrace_python/plugins/loader.py +84 -0
- coretrace_python/plugins/manifest.py +112 -0
- coretrace_python/plugins/registry.py +34 -0
- coretrace_python/plugins/secrets.py +330 -0
- coretrace_python/reporters/__init__.py +22 -0
- coretrace_python/reporters/json_format.py +48 -0
- coretrace_python/reporters/report.py +23 -0
- coretrace_python/reporters/sarif.py +70 -0
- coretrace_python/reporters/text.py +24 -0
- coretrace_python/semantic/__init__.py +9 -0
- coretrace_python/semantic/identity.py +39 -0
- coretrace_python/semantic/imports.py +131 -0
- coretrace_python/semantic/scopes.py +473 -0
- coretrace_python/semantic/symbols.py +87 -0
- coretrace_python/source/__init__.py +13 -0
- coretrace_python/source/manager.py +81 -0
- coretrace_python/source/model.py +57 -0
- coretrace_python/taint/__init__.py +55 -0
- coretrace_python/taint/engine.py +800 -0
- coretrace_python/taint/models.py +317 -0
- coretrace_python/taint/routes.py +99 -0
- coretrace_python_analyzer-0.1.0.dist-info/METADATA +74 -0
- coretrace_python_analyzer-0.1.0.dist-info/RECORD +126 -0
- coretrace_python_analyzer-0.1.0.dist-info/WHEEL +4 -0
- coretrace_python_analyzer-0.1.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""Dependency policies (architecture §26).
|
|
2
|
+
|
|
3
|
+
A ``coretrace-policy.toml`` at the project root, or the file passed with ``--policy``,
|
|
4
|
+
denies packages, requires pinned versions and lists the advisories a project accepts,
|
|
5
|
+
whose findings are dropped whatever produced them.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import tomllib
|
|
11
|
+
from collections.abc import Iterable
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
from coretrace_python.dependency.advisories import AdvisoryFileError
|
|
17
|
+
from coretrace_python.dependency.graph import normalize
|
|
18
|
+
from coretrace_python.findings import Finding
|
|
19
|
+
|
|
20
|
+
POLICY_FILE = "coretrace-policy.toml"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(frozen=True)
|
|
24
|
+
class Policy:
|
|
25
|
+
deny: tuple[str, ...] = ()
|
|
26
|
+
require_pinned: bool = False
|
|
27
|
+
ignore: tuple[str, ...] = ()
|
|
28
|
+
|
|
29
|
+
def denies(self, package: str) -> bool:
|
|
30
|
+
return normalize(package) in {normalize(name) for name in self.deny}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def load_policy(path: Path) -> Policy:
|
|
34
|
+
try:
|
|
35
|
+
data = tomllib.loads(path.read_text(encoding="utf-8"))
|
|
36
|
+
dependencies = data.get("dependencies", {})
|
|
37
|
+
advisories = data.get("advisories", {})
|
|
38
|
+
return Policy(
|
|
39
|
+
_strings(dependencies.get("deny", []), "dependencies.deny"),
|
|
40
|
+
_boolean(dependencies.get("require_pinned", False), "dependencies.require_pinned"),
|
|
41
|
+
_strings(advisories.get("ignore", []), "advisories.ignore"),
|
|
42
|
+
)
|
|
43
|
+
except AdvisoryFileError as error:
|
|
44
|
+
raise AdvisoryFileError(f"{path}: {error}") from error
|
|
45
|
+
except (OSError, tomllib.TOMLDecodeError, AttributeError) as error:
|
|
46
|
+
raise AdvisoryFileError(f"{path}: {error}") from error
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _strings(value: Any, key: str) -> tuple[str, ...]:
|
|
50
|
+
if not isinstance(value, list) or not all(isinstance(item, str) for item in value):
|
|
51
|
+
raise AdvisoryFileError(f"{key} must be a list of strings")
|
|
52
|
+
return tuple(value)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _boolean(value: Any, key: str) -> bool:
|
|
56
|
+
if not isinstance(value, bool):
|
|
57
|
+
raise AdvisoryFileError(f"{key} must be true or false")
|
|
58
|
+
return value
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def apply_policy(policy: Policy, findings: Iterable[Finding]) -> tuple[Finding, ...]:
|
|
62
|
+
"""The findings minus those about an advisory the policy accepts."""
|
|
63
|
+
|
|
64
|
+
ignored = set(policy.ignore)
|
|
65
|
+
return tuple(f for f in findings if f.metadata.get("advisory") not in ignored)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""CycloneDX software bill of materials from the dependency graph (architecture §26)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from collections.abc import Iterable
|
|
7
|
+
|
|
8
|
+
from coretrace_python.dependency.graph import Advisory, DependencyGraph, Requirement
|
|
9
|
+
|
|
10
|
+
SPEC_VERSION = "1.5"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def purl(requirement: Requirement) -> str:
|
|
14
|
+
base = f"pkg:pypi/{requirement.name}"
|
|
15
|
+
if requirement.pinned is None:
|
|
16
|
+
return base
|
|
17
|
+
return f"{base}@{'.'.join(str(part) for part in requirement.pinned.parts)}"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _component(requirement: Requirement) -> dict[str, object]:
|
|
21
|
+
reference = purl(requirement)
|
|
22
|
+
component: dict[str, object] = {"type": "library", "bom-ref": reference, "name": requirement.name}
|
|
23
|
+
if requirement.pinned is not None:
|
|
24
|
+
component["version"] = ".".join(str(part) for part in requirement.pinned.parts)
|
|
25
|
+
component["purl"] = reference
|
|
26
|
+
properties: list[dict[str, str]] = []
|
|
27
|
+
if requirement.specifier:
|
|
28
|
+
properties.append({"name": "coretrace:specifier", "value": requirement.specifier})
|
|
29
|
+
if requirement.optional:
|
|
30
|
+
properties.append({"name": "coretrace:optional", "value": "true"})
|
|
31
|
+
if properties:
|
|
32
|
+
component["properties"] = properties
|
|
33
|
+
return component
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def render_sbom(
|
|
37
|
+
dependencies: DependencyGraph, advisories: Iterable[Advisory], tool_name: str, tool_version: str
|
|
38
|
+
) -> str:
|
|
39
|
+
"""A CycloneDX JSON document: one component per requirement, and the advisories
|
|
40
|
+
affecting them as vulnerabilities. Deterministic for a given graph."""
|
|
41
|
+
|
|
42
|
+
requirements = dependencies.requirements
|
|
43
|
+
vulnerabilities: list[dict[str, object]] = []
|
|
44
|
+
for advisory in sorted(advisories, key=lambda a: a.id):
|
|
45
|
+
affected = [purl(r) for r in requirements if advisory.affects(r)]
|
|
46
|
+
if affected:
|
|
47
|
+
vulnerabilities.append(
|
|
48
|
+
{
|
|
49
|
+
"id": advisory.id,
|
|
50
|
+
"description": advisory.summary,
|
|
51
|
+
"ratings": [{"severity": advisory.severity.value}],
|
|
52
|
+
"affects": [{"ref": reference} for reference in affected],
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
document = {
|
|
56
|
+
"bomFormat": "CycloneDX",
|
|
57
|
+
"specVersion": SPEC_VERSION,
|
|
58
|
+
"version": 1,
|
|
59
|
+
"metadata": {
|
|
60
|
+
"tools": {"components": [{"type": "application", "name": tool_name, "version": tool_version}]}
|
|
61
|
+
},
|
|
62
|
+
"components": [_component(requirement) for requirement in requirements],
|
|
63
|
+
"vulnerabilities": vulnerabilities,
|
|
64
|
+
}
|
|
65
|
+
return json.dumps(document, indent=2) + "\n"
|