VNX-1123: Excessive Use of Self-Modifying Code
Reports code that rewrites itself at run time: a Python or Node.js program writing to its own source file (__file__, sys.argv[0], __filename, process.argv[1], import.meta.url), replacing a function's __code__, or building or patching code objects. Reading one's own source and exec(compile(...)) of another file are not reported.
| Field | Value |
|---|---|
| Rule ID | VNX-1123 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | Python, JavaScript / TypeScript |
| CWE | CWE-1123 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C |
| Tags | self-modifying-code cwe-1123 |
| Source | internal/sast/rules/vnx-1123.rego |
Overview
VNX-1123 maps to CWE-1123: Excessive Use of Self-Modifying Code. It reports:
Python
- opening the program’s own source for writing:
open(__file__, "w")(also"a","r+","x", themode=keyword,sys.argv[0], and a call broken over lines),Path(__file__).write_text(...)/write_bytes(...),os.open(__file__, os.O_WRONLY ...); - replacing a function’s bytecode:
fn.__code__ = other.__code__; - building or patching code objects:
types.CodeType(...),code.replace(co_code=...).
JavaScript / TypeScript
fs.writeFile,writeFileSync,appendFile,appendFileSyncorcreateWriteStreamon__filename,process.argv[1]orfileURLToPath(import.meta.url).
Not reported: reading one’s own source (open(__file__, "rb"), a common test-fixture idiom), exec(compile(f.read(), "__version__.py", "exec")) of another file (setup.py version loading), writes to other paths such as __filename + ".bak", comparisons of __code__, and the patterns inside comments or strings.
Why This Matters
Code that rewrites itself cannot be reviewed, signed or integrity-checked: what runs tomorrow is not what was reviewed today. It is also a hallmark of droppers and persistence implants, which append a payload to the script that loaded them so it survives an update.
What Gets Flagged
def self_update(new_source):
with open(__file__, "w") as fh: # FLAGGED
fh.write(new_source)
fn.__code__ = other.__code__ # FLAGGED
fs.writeFileSync(__filename, src + extra); // FLAGGED
fs.writeFileSync(path.join(__dirname, 'out.json'), '{}'); // NOT FLAGGED
Remediation
- Ship updates through the package manager or a signed release, never by rewriting the running file.
- Keep generated code in separate, generated files that a build step produces and review covers.
- Replace bytecode patching with ordinary composition (wrappers, decorators, dependency injection).
References
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-1123
// nosec vnx-1123
Or record an ignore rule: vulnetix ignore add --rule vnx-1123 --reason "...". See Suppressing findings.