/** * Pass: module-side-effect (CWE-829, category: security) * * Pattern pass — flags dangerous side effects executed at **module load / * install / build time**, where no taint flow is involved (the bad behavior * is hard-coded by an attacker, not user-driven). This is the canonical * delivery vector for supply-chain droppers: shai-hulud-style TruffleHog * harvesters in npm `postinstall`, Python `__init__.py` credential POST, * Go `init()` exfil, Rust `build.rs` exec. * * Detection per language: * JavaScript / TypeScript: * - module-level call (`in_method == null`) to a high-risk API: * `child_process.{exec,spawn,execSync,spawnSync}`, * `https.request`, `http.request`, * `fetch` / `axios.*` whose args reference `process.env` or `os.homedir`. * - `package.json` source-text scan (when `meta.file` ends with * `package.json`): a `scripts.(pre|post)?install` value that invokes a * shell (`curl`, `wget`, `node -e`, `sh -c`, `eval`). Benign install * scripts (`node-gyp rebuild`, `prebuild-install`, `husky install`, * `patch-package`) are allowlisted. * * Python: * - module-level call (`in_method == null`) to a high-risk API: * `requests.{post,put}`, `urllib.request.urlopen`, * `socket.{connect,create_connection}`, `subprocess.run`, `os.system`. * - The call must reference an "env / secret" signal in any argument * expression: `os.environ`, `pwd.getpw`, `glob.glob('/.../id_rsa`, * `~/.ssh`, `/etc/passwd`, `home`, `pathlib.Path.home`. This keeps the * FP rate near zero on benign module-level network setup. * * Go: * - call inside a function named `init` (`in_method === 'init'`) whose * callee is `exec.Command`, `http.Post`, `http.Get`, `net.LookupTXT`, * `os.Setenv`. * * Rust: * - file is a build script (`meta.file` ends with `build.rs`) AND callee * is `Command::new` / `std::process::Command::new` / `reqwest::*`. * `println!("cargo:...")` directives are the only intended `build.rs` * side effect — those produce no IR call. * * Closes: cognium-dev #93 (npm postinstall dropper), #96 L47 (Python import- * time harvest), #98 (Go init() + Rust build.rs install-time harvest). */ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js'; export interface ModuleSideEffectResult { findings: Array<{ line: number; language: string; pattern: string; api: string; }>; } export declare class ModuleSideEffectPass implements AnalysisPass { readonly name = "module-side-effect"; readonly category: "security"; run(ctx: PassContext): ModuleSideEffectResult; private detectCall; /** * Scan a package.json file for dangerous install-lifecycle scripts. * Best-effort regex extraction — package.json is not a JS source per se but * the analyzer routes it through the JS pipeline. */ private scanPackageJson; private fixFor; } //# sourceMappingURL=module-side-effect-pass.d.ts.map