diff --git a/sast-engine/graph/callgraph/builder/stdlib_e2e_test.go b/sast-engine/graph/callgraph/builder/stdlib_e2e_test.go index dad89a65..3838d2e8 100644 --- a/sast-engine/graph/callgraph/builder/stdlib_e2e_test.go +++ b/sast-engine/graph/callgraph/builder/stdlib_e2e_test.go @@ -22,7 +22,7 @@ import ( func TestStdlibReturnTypeChaining_EndToEnd(t *testing.T) { // Use absolute path to ensure graph.Initialize and BuildCallGraphFromPath // use consistent file paths (module registry converts to absolute internally). - projectPath, err := filepath.Abs("../../../../test-fixtures/querytype-poc") + projectPath, err := filepath.Abs("../../../test-fixtures/python/stdlib_chaining") require.NoError(t, err) // Build code graph from the fixture diff --git a/sast-engine/graph/callgraph/builder/type_inference_evidence_test.go b/sast-engine/graph/callgraph/builder/type_inference_evidence_test.go index 2210b147..fa49e26a 100644 --- a/sast-engine/graph/callgraph/builder/type_inference_evidence_test.go +++ b/sast-engine/graph/callgraph/builder/type_inference_evidence_test.go @@ -15,7 +15,7 @@ import ( // resolves the full chain: sqlite3.connect() → Connection → .cursor() → Cursor → .execute(). // Requires CDN data regenerated with typeshed overlay (PR-00) for C builtin return types. func TestTypeInference_StdlibChaining(t *testing.T) { - projectPath, err := filepath.Abs("../../../../test-fixtures/querytype-poc") + projectPath, err := filepath.Abs("../../../test-fixtures/python/stdlib_chaining") require.NoError(t, err) codeGraph := graph.Initialize(projectPath, nil) @@ -117,7 +117,7 @@ func TestTypeInference_StdlibChaining(t *testing.T) { // resolves: requests.get() → Response → .json() → dict. func TestTypeInference_ThirdPartyChaining(t *testing.T) { t.Skip("Requires third-party CDN data (requests, flask) — skip until CDN is available in CI") - projectPath, err := filepath.Abs("../../../../test-fixtures/querytype-poc") + projectPath, err := filepath.Abs("../../../test-fixtures/python/stdlib_chaining") require.NoError(t, err) codeGraph := graph.Initialize(projectPath, nil) diff --git a/test-fixtures/querytype-poc/app.py b/sast-engine/test-fixtures/python/stdlib_chaining/app.py similarity index 100% rename from test-fixtures/querytype-poc/app.py rename to sast-engine/test-fixtures/python/stdlib_chaining/app.py diff --git a/test-fixtures/querytype-poc/rules.py b/test-fixtures/querytype-poc/rules.py deleted file mode 100644 index 4acd1b58..00000000 --- a/test-fixtures/querytype-poc/rules.py +++ /dev/null @@ -1,55 +0,0 @@ -"""QueryType PoC rules — SQL injection and weak hash detection.""" - -from codepathfinder import rule, QueryType, Or, lt, gt, lte, gte, regex, missing -from codepathfinder.dataflow import flows -from codepathfinder.matchers import calls - - -# --- QueryType definitions --- - -class DBCursor(QueryType): - fqns = ["sqlite3.Cursor", "mysql.connector.cursor.MySQLCursor"] - patterns = ["*Cursor"] - match_subclasses = True - - -class WebRequest(QueryType): - fqns = ["flask.Request", "django.http.HttpRequest"] - match_subclasses = True - - -class Hashlib(QueryType): - fqns = ["hashlib"] - - -class OSModule(QueryType): - fqns = ["os"] - - -# --- Rules --- - -@rule(id="SQL-INJECTION-POC", severity="critical", cwe="CWE-89") -def sql_injection_poc(): - return flows( - from_sources=WebRequest.method("get", "args"), - to_sinks=DBCursor.method("execute"), - ) - - -@rule(id="SQL-INJECTION-FALLBACK", severity="critical", cwe="CWE-89") -def sql_injection_fallback(): - """Same rule but with fallbackMode=name to catch without type inference.""" - return flows( - from_sources=calls("request.args.get"), - to_sinks=calls("cursor.execute"), - ) - - -@rule(id="WEAK-HASH-POC", severity="medium", cwe="CWE-327") -def weak_hash(): - return Or(Hashlib.method("md5"), Hashlib.method("sha1")) - - -@rule(id="OVERLY-PERMISSIVE-FILE", severity="high", cwe="CWE-732") -def overly_permissive(): - return OSModule.method("chmod").arg(1, "0o7*")