mirror of
https://github.com/elicpeter/nyx.git
synced 2026-07-03 20:41:00 +02:00
Dynamic (#77)
This commit is contained in:
parent
55247b7fcd
commit
991c84a1eb
1464 changed files with 225448 additions and 1985 deletions
|
|
@ -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;
|
||||
21
tests/dynamic_fixtures/callgraph_entry/flask_route_sink.py
Normal file
21
tests/dynamic_fixtures/callgraph_entry/flask_route_sink.py
Normal 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"
|
||||
13
tests/dynamic_fixtures/callgraph_entry/orphan_helper_sink.py
Normal file
13
tests/dynamic_fixtures/callgraph_entry/orphan_helper_sink.py
Normal 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
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue