Files
Open_Ultra_SAST/tests/test_variants.py
T
Marius CiepluchandClaude Fable 5.1 4d56b3c76e feat(corpus-seeded-mechanisms): structural shapes derived from labeled pairs
Task 1.1 (Req 2.1-2.4). Spec approved by the maintainer in session.

- semantic/variants.py: Shape (language, sink trailing name, arity,
  source positions and kinds, closed guard kind, mechanism id) with a
  stable text-free key; derive_shape finds the labeled sink call site in
  the vulnerable FileIR, traces argument identifiers through binds to a
  fact source, a parameter or a container read, and classifies the guard
  the fixed side added from the labeled function's added statements
  against a closed set (none when unknown). No path, line or literal
  enters a shape; a constant-only call teaches nothing.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
2026-09-05 14:27:33 +02:00

77 lines
3.4 KiB
Python

"""corpus-seeded-mechanisms: structural shapes derived from pairs and matched on trees (offline, stdlib ast)."""
from __future__ import annotations
from openultrasast.semantic.facts import load_facts
from openultrasast.semantic.ir import parse_file
VULN = "from flask import request\nimport os\n\n\ndef run():\n cmd = request.args.get('cmd')\n os.system(cmd)\n"
FIXED = (
"from flask import request\nimport os\n\nALLOWED = {'ls', 'date'}\n\n\ndef run():\n cmd = request.args.get('cmd')\n"
" if cmd not in ALLOWED:\n return None\n os.system(cmd)\n"
)
def _derive(vuln: str = VULN, fixed: str = FIXED, **overrides: object):
from openultrasast.semantic.variants import derive_shape
kwargs: dict[str, object] = {"function": "run", "sink": "os.system", "line": None, "mechanism": "source_reaches_sink"}
kwargs.update(overrides)
return derive_shape(
parse_file("app.py", vuln, "python"),
parse_file("app.py", fixed, "python"),
vuln_text=vuln,
fixed_text=fixed,
facts=load_facts(),
**kwargs,
)
def test_derive_shape_from_a_request_to_os_system_pair_with_an_allowlist_fix() -> None:
from openultrasast.semantic.variants import GUARD_KINDS, SOURCE_KINDS
shape = _derive()
assert shape is not None
assert shape.language == "python" and shape.sink_name == "system" and shape.arity == 1
assert shape.source_positions == (0,) and shape.source_kinds == ("fact_source",)
assert shape.guard == "allowlist_test" and shape.guard in GUARD_KINDS and shape.mechanism == "source_reaches_sink"
assert set(shape.source_kinds) <= set(SOURCE_KINDS)
def test_shape_key_is_stable_and_carries_no_path_line_or_literal() -> None:
a, b = _derive(), _derive()
assert a is not None and b is not None and a.key() == b.key()
key = a.key()
for forbidden in ("app.py", "cmd", "'ls'", "request.args", ":6", ":7"):
assert forbidden not in key
# the same code in another file with different variable names is the same shape
other_vuln = VULN.replace("cmd", "command")
other = _derive(other_vuln, FIXED.replace("cmd", "command"))
assert other is not None and other.key() == key
def test_parameter_and_container_read_sources_are_classified() -> None:
vuln = "import os\n\n\ndef run(payload, cmd):\n target = payload['t']\n os.system(cmd + target)\n"
fixed = (
"import os\n\n\ndef run(payload, cmd):\n target = payload['t']\n if len(target) > 32:\n return None\n"
" os.system(cmd + target)\n"
)
shape = _derive(vuln, fixed)
assert shape is not None
assert shape.source_positions == (0,)
assert shape.source_kinds in {("parameter",), ("container_read",)} # one argument carrying both; the kind is the first found
assert shape.guard == "bounds_test"
def test_unlabeled_or_missing_sink_returns_none_and_guard_defaults_to_none() -> None:
assert _derive(sink="subprocess.run") is None # the label names a sink the function never calls
assert _derive(function="other") is None # no such function
same = _derive(VULN, VULN)
assert same is not None and same.guard == "none" # no statement differs on the fixed side
constant = "import os\n\n\ndef run():\n os.system('ls')\n"
assert _derive(constant, constant) is None # a constant argument carries no source: nothing to learn
def test_parse_failed_side_yields_no_shape() -> None:
assert _derive("def run(:\n", FIXED) is None