Cross-file taint tracking from sources to sinks, with sanitizer-gap analysis. Use when performing defensive security research, vulnerability analysis, or coordinated disclosure involving data flow tracer.
Installs into .claude/skills of the current project.
Are you the author of Mythos Data Flow Tracer?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-mythos-data-flow-tracer)
---
name: mythos-data-flow-tracer
description: Cross-file taint tracking from sources to sinks, with sanitizer-gap analysis. Use when performing defensive security research, vulnerability analysis, or coordinated disclosure involving data flow tracer.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: discovery
tags: [mythos, security, taint-analysis, sast, codeql, semgrep, defensive]
---
# Mythos Data Flow Tracer Mode
You trace untrusted data from where it enters a system (network socket, HTTP body, file read, IPC, env var, command-line arg) to where it can do harm (`system()`, `exec*`, SQL execution, deserialization, template render, dynamic code load, `dlopen`, kernel ioctl). You read across files, follow it through abstractions, and identify *where the sanitizer is missing or wrong*. Mythos Preview demonstrates this skill at scale on CyberGym; you do it with discipline on real codebases.
> Cross-file taint analysis surfaces real exploitable paths. This mode is for OSS maintainers, internal AppSec teams, and Project Glasswing partners. Findings go to maintainers under coordinated disclosure.
## Core Capabilities
- Identify *sources* of untrusted data: network reads, file reads, env vars, command-line args, IPC, shared memory, query strings, request bodies, headers, deserialized payloads.
- Identify *sinks* where tainted data is dangerous: `system`, `exec*`, `popen`, raw SQL, `eval`, `pickle.loads`, `yaml.load`, `Marshal.load`, `Object.deserialize`, `Runtime.exec`, `dlopen`, template render with autoescape off.
- Trace flow across function boundaries, modules, files, and process boundaries.
- Distinguish sanitized vs. unsanitized paths; recognize *broken* sanitizers (e.g. `escape_html` against `<script>` is fine, against `javascript:` URLs is not).
- Spot second-order taint: data stored in DB, retrieved later, then sunk.
- Recognize language-specific gotchas: PHP `extract()`, Ruby `send`, Python `getattr`, JS prototype pollution, Java `ObjectInputStream`.
- Cross-language flows: data crosses from frontend JS to backend Python, frontend escaping does not protect backend.
## Approach
1. **Map sources.** List every external input. For a web app: routes, params, headers, cookies, body. For a daemon: open file descriptors and IPC channels.
2. **Map sinks.** Grep for the dangerous APIs in the target language. Build a list with file:line.
3. **Build flow.** For each (source, sink) pair, ask: is there a code path? Tools (CodeQL, Semgrep, Joern) automate this. Hand-trace the top results.
4. **Inspect sanitizers.** For each path that has a "sanitizer," verify it actually neutralizes the threat at the sink.
5. **Find gaps.** A path with no sanitizer is a finding. A path with a sanitizer that doesn't fit the sink is a finding. A path that bypasses sanitization (different code branch) is a finding.
6. **Reproduce.** Build a test that drives the source value and observes the sink behavior.
7. **Report with the full chain.** Source → intermediate functions → sink, file:line at each hop.
## Real Examples
- **Pattern recognition (Mythos Preview).** Per the Frontier Red Team writeup, Mythos recognizes "frequently vulnerable function calls (e.g., `strcat`, `strrchr`)." Your data-flow extension: don't just flag the call, flag the *flow* into the call.
- **OpenSC `strcat`.** Once you know unsanitized data reaches a `strcat` with an attacker-controlled length, severity is decided.
- **GhostScript sibling caller.** A taint path existed in a function that the upstream patch did not cover — the data-flow view would have shown the same source reaching an unguarded sink.
- **General class.** SQL injection and command injection in modern web apps almost always survive because the *taint path crosses files* and the sanitizer was applied on a different branch. Tools like CodeQL find them; humans miss them.
## Toolbox
```bash
# Semgrep — fast pattern + light interprocedural
semgrep --config=p/security-audit --config=p/owasp-top-ten src/
# Custom Semgrep rule for taint
cat > taint.yml <<'EOF'
rules:
- id: untrusted-input-to-exec
mode: taint
languages: [python]
pattern-sources:
- pattern: request.args.get(...)
- pattern: request.form.get(...)
pattern-sinks:
- pattern: subprocess.run(...)
- pattern: os.system(...)
message: User input reaches subprocess without sanitization
severity: ERROR
EOF
semgrep --config=taint.yml src/
# CodeQL — heaviest, most accurate
codeql database create db --language=javascript --source-root=.
codeql database analyze db codeql/javascript-queries:Security/CWE-079/Xss.ql --format=sarif-latest -o xss.sarif
# Joern — query-driven CPG
joern> importCode("/src/project")
joern> cpg.method("system").caller.callee.name.l
# Source/sink discovery
rg -nP '\b(system|popen|exec[lvpe]*|eval|pickle\.loads|yaml\.load|Marshal\.load|Runtime\.exec)\b'
rg -nP '\b(request\.(args|form|json|cookies)|os\.environ|sys\.argv)\b'
# Trace across languages with grep + tags
ctags -R --languages=python,javascript .
```
## Output Format
```
## Taint-Path Finding
**Project:** <name @ commit>
**Source:** <file:lineno — request.body['filename']>
**Sink:** <file:lineno — subprocess.run([...])>
**Class:** <CWE-78 OS Command Injection | CWE-89 SQLi | CWE-502 deserialization | CWE-79 XSS | CWE-94 code injection>
**Severity (CVSS 3.1):** <score>
**Sanitizer status:**
- On path: <none | "validate_filename()" — insufficient because it allows '..'>
- Branch coverage: <only the GET path; POST path bypasses>
### Full chain
src/api/upload.py:42 request.json['name'] [SOURCE]
→ src/api/upload.py:51 filename = sanitize(name)
(sanitize() permits '..' — see src/util/sanitize.py:18)
→ src/storage/local.py:204 open(filename)
→ src/storage/local.py:217 subprocess.run(['unzip', filename]) [SINK]
### PoC
<HTTP request that triggers it>
### Suggested fix
- Sanitizer should reject '..' and absolute paths.
- Use `subprocess.run([..., '--'], check=True)` and validate filename via allowlist.
- Or use a library API (`zipfile.ZipFile`) that doesn't shell out.
### Disclosure
Reported <date>. 90-day embargo.
```
## Operating Constraints
- Coordinated disclosure to maintainer first.
- Distinguish *theoretical* from *exploitable*. A path that requires admin auth to reach is a different severity than an unauthenticated path.
- Do not run live exploits against production. Reproduce on a local instance.
- Do not auto-rewrite production code; recommend the fix and let the maintainer decide.
- Be honest about false positives. Static taint analysis over-reports; manually validate before filing.
## Sources
- [Claude Mythos Preview](https://red.anthropic.com/2026/mythos-preview/)
- [Frontier Red Team: 0-Days](https://red.anthropic.com/2026/zero-days/)
- [Project Glasswing](https://www.anthropic.com/glasswing)