This commit is contained in:
Eli Peter 2026-06-05 10:16:30 -05:00 committed by GitHub
parent 55247b7fcd
commit 991c84a1eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
1464 changed files with 225448 additions and 1985 deletions

View file

@ -0,0 +1,28 @@
// Phase 04 fixture: Express route handler is a named function bound at
// `app.post`; it calls a helper that holds the sink. The callgraph-aware
// spec-derivation path must rewrite the harness entry to the route
// handler `runCommand`, not the helper `execHelper`.
//
// `runCommand` reads `req.body.cmd` into a local before dispatching to
// `execHelper`. Threading the local through gives the JS callee
// extractor a clean call shape (bare identifier in argument position)
// so the call-graph picks up the `runCommand → execHelper` edge.
const express = require("express");
const { exec } = require("child_process");
const app = express();
function execHelper(cmd) {
exec(cmd); // sink: command injection
}
function runCommand(req, res) {
const cmd = req.body.cmd;
execHelper(cmd);
res.send("ok");
}
app.post("/run", runCommand);
module.exports = app;

View file

@ -0,0 +1,21 @@
# Phase 04 fixture: sink in a helper function called only from a Flask
# route handler. The callgraph-aware spec-derivation path must rewrite
# the harness entry to the route handler `run_command` (entry-point
# ancestor with `entry_kind = FlaskRoute`), not the helper `_execute`
# where the sink physically lives.
from flask import Flask, request
app = Flask(__name__)
def _execute(cmd):
import os
os.system(cmd) # sink: command injection
@app.route("/run", methods=["POST"])
def run_command():
cmd = request.form.get("cmd", "")
_execute(cmd)
return "ok"

View file

@ -0,0 +1,13 @@
# Phase 04 follow-up regression fixture: the sink lives in a class method
# that has no callers in the whole-program callgraph. The reverse-edge BFS
# in `find_entry_via_callgraph` must miss (helper is inside a class, so
# `is_entry_point`'s zero-in-degree heuristic does not apply), and the
# strict `derive_from_callgraph_walk_only` pre-step must defer to the
# strategy ladder so the substring `.http.` rule-id fallback does NOT
# short-circuit the more precise `FromFlowSteps` strategy.
class Stuff:
def helper(self, arg):
import os
os.system(arg) # sink: command injection

View file

@ -0,0 +1,23 @@
// Phase 04 fixture: Spring controller method calls a helper that holds
// the sink. The callgraph-aware spec-derivation path must rewrite the
// harness entry to the controller method `runCommand`, not the helper
// `execHelper`.
package fixture;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SinkController {
private void execHelper(String cmd) throws Exception {
Runtime.getRuntime().exec(cmd); // sink: command injection
}
@PostMapping("/run")
public String runCommand(@RequestBody String cmd) throws Exception {
execHelper(cmd);
return "ok";
}
}