| name | taint-instrumentation-assistant |
| description | Instruments code to track the flow of untrusted or sensitive data at runtime, enabling detection of injection vulnerabilities, data leaks, and privilege violations. Use when users need to: (1) Track untrusted input propagation through code, (2) Detect SQL injection, XSS, or command injection vulnerabilities, (3) Identify sensitive data leaks, (4) Monitor privilege escalation paths, (5) Perform dynamic taint analysis for security testing. Supports Python, Java, JavaScript, and C/C++ with configurable taint sources and sinks. |
Taint Instrumentation Assistant
Instrument code to track untrusted and sensitive data flow for security vulnerability detection.
Workflow
Follow these steps to add taint tracking instrumentation:
1. Identify Taint Sources and Sinks
Define what data to track and where violations occur:
Taint sources (untrusted/sensitive data origins):
- User input (HTTP parameters, form data, command-line args)
- File reads (configuration files, user uploads)
- Database queries (user-provided data)
- Network input (API responses, socket data)
- Environment variables
Taint sinks (dangerous operations):
- SQL queries (SQL injection risk)
- System commands (command injection risk)
- HTML output (XSS risk)
- File operations (path traversal risk)
- Eval/exec statements (code injection risk)
- Network output (data leak risk)
2. Instrument Taint Sources
Mark data from untrusted sources as tainted:
def mark_tainted(value, source):
"""Mark a value as tainted from a specific source"""
if hasattr(value, '__taint__'):
value.__taint__ = source
return value
user_input = request.GET['username']
user_input = mark_tainted(user_input, source="HTTP_PARAM")
3. Propagate Taint Through Operations
Track taint as data flows through the program:
def tainted_concat(str1, str2):
result = str1 + str2
if hasattr(str1, '__taint__') or hasattr(str2, '__taint__'):
result.__taint__ = getattr(str1, '__taint__', None) or getattr(str2, '__taint__', None)
return result
4. Check Taint at Sinks
Detect when tainted data reaches dangerous operations:
def execute_query(query):
if hasattr(query, '__taint__'):
print(f"TAINT VIOLATION: Tainted data from {query.__taint__} used in SQL query")
print(f"Query: {query}")
5. Generate Instrumented Code
Produce code with complete taint tracking:
- Instrumented source code with taint tracking
- Taint policy configuration (sources and sinks)
- Violation report format
- Usage instructions
Language-Specific Patterns
Python
class TaintedStr(str):
"""String wrapper that carries taint information"""
def __new__(cls, value, taint_source=None):
instance = super().__new__(cls, value)
instance.taint_source = taint_source
return instance
def __add__(self, other):
result = TaintedStr(super().__add__(other))
result.taint_source = self.taint_source or getattr(other, 'taint_source', None)
return result
def get_user_input():
user_data = input("Enter username: ")
return TaintedStr(user_data, taint_source="USER_INPUT")
def execute_sql(query):
if isinstance(query, TaintedStr) and query.taint_source:
print(f"[TAINT VIOLATION] SQL Injection risk!")
print(f" Source: {query.taint_source}")
print(f" Query: {query}")
raise SecurityError("Tainted data in SQL query")
username = get_user_input()
query = TaintedStr() + username + TaintedStr()
execute_sql(query)
Java
class TaintedString {
private String value;
private String taintSource;
public TaintedString(String value, String taintSource) {
this.value = value;
this.taintSource = taintSource;
}
public String getValue() { return value; }
public String getTaintSource() { return taintSource; }
public boolean isTainted() { return taintSource != null; }
public TaintedString concat(TaintedString other) {
String newValue = this.value + other.value;
String newSource = this.taintSource != null ? this.taintSource : other.taintSource;
return new TaintedString(newValue, newSource);
}
}
TaintedString getUserInput() {
Scanner scanner = new Scanner(System.in);
String scanner.nextLine();
(input, );
}
{
(query.isTainted()) {
System.err.println();
System.err.println( + query.getTaintSource());
System.err.println( + query.getValue());
();
}
}
JavaScript
class TaintedString {
constructor(value, taintSource = null) {
this.value = value;
this.taintSource = taintSource;
}
concat(other) {
const newValue = this.value + (other.value || other);
const newSource = this.taintSource || other.taintSource;
return new TaintedString(newValue, newSource);
}
toString() {
return this.value;
}
}
function getUserInput() {
const input = prompt("Enter username:");
return new TaintedString(input, "USER_INPUT");
}
function executeSQL(query) {
if (query instanceof TaintedString && query.taintSource) {
console.error();
.();
.();
();
}
}
Common Vulnerability Patterns
SQL Injection Detection
def login(username, password):
query = f"SELECT * FROM users WHERE name='{username}' AND pass='{password}'"
return db.execute(query)
def login(username, password):
username = TaintedStr(username, "HTTP_PARAM:username")
password = TaintedStr(password, "HTTP_PARAM:password")
query = TaintedStr(f"SELECT * FROM users WHERE name='") + username + TaintedStr("' AND pass='") + password + TaintedStr("'")
if isinstance(query, TaintedStr) and query.taint_source:
print(f"[TAINT VIOLATION] SQL Injection detected!")
print(f" Tainted input: {query.taint_source}")
print(f" Query: {query}")
return db.execute(str(query))
XSS Detection
def render_greeting(name):
return f"<h1>Hello, {name}!</h1>"
def render_greeting(name):
name = TaintedStr(name, "HTTP_PARAM:name")
html = TaintedStr("<h1>Hello, ") + name + TaintedStr("!</h1>")
if isinstance(html, TaintedStr) and html.taint_source:
print(f"[TAINT VIOLATION] XSS risk detected!")
print(f" Tainted input: {html.taint_source}")
print(f" HTML: {html}")
return str(html)
Command Injection Detection
def process_file(filename):
os.system(f"cat {filename}")
def process_file(filename):
filename = TaintedStr(filename, "USER_INPUT:filename")
command = TaintedStr("cat ") + filename
if isinstance(command, TaintedStr) and command.taint_source:
print(f"[TAINT VIOLATION] Command Injection risk!")
print(f" Tainted input: {command.taint_source}")
print(f" Command: {command}")
os.system(str(command))
Taint Policy Configuration
TAINT_SOURCES = {
"HTTP_PARAM": ["request.GET", "request.POST", "request.args"],
"USER_INPUT": ["input()", "sys.stdin.read()"],
"FILE_READ": ["open().read()", "Path.read_text()"],
"ENV_VAR": ["os.getenv()", "os.environ"],
}
TAINT_SINKS = {
"SQL_QUERY": ["db.execute()", "cursor.execute()"],
"SYSTEM_CMD": ["os.system()", "subprocess.call()"],
"HTML_OUTPUT": ["render_template()", "HttpResponse()"],
"FILE_WRITE": ["open().write()", "Path.write_text()"],
"EVAL": ["eval()", "exec()"],
}
TAINT_ENABLED = True
REPORT_FORMAT = "detailed"
Output Format
Taint Violation Report
## Taint Analysis Report
**File**: app.py
**Analysis Date**: 2024-02-17
### Violations Detected
#### Violation 1: SQL Injection Risk
- **Severity**: HIGH
- **Location**: app.py:45
- **Taint Source**: HTTP_PARAM:username
- **Taint Sink**: db.execute()
- **Data Flow**:
1. User input from HTTP parameter 'username' (line 42)
2. String concatenation in query building (line 44)
3. Passed to db.execute() without sanitization (line 45)
- **Recommendation**: Use parameterized queries
#### Violation 2: XSS Risk
- **Severity**: MEDIUM
- **Location**: app.py:78
- **Taint Source**: HTTP_PARAM:comment
- **Taint Sink**: render_template()
- **Data Flow**:
1. User input from HTTP parameter 'comment' (line 75)
2. Embedded in HTML template (line 78)
- **Recommendation**: Use HTML escaping
### Summary
- Total violations: 2
- High severity: 1
- Medium severity: 1
- Low severity: 0
Best Practices
- Comprehensive source marking: Mark all untrusted input sources
- Complete propagation: Track taint through all operations
- Strict sink checking: Verify all dangerous operations
- Minimal false positives: Use precise taint rules
- Performance consideration: Optimize for production use
- Clear reporting: Provide actionable violation reports
Advanced Features
Sanitization Tracking
def sanitize_sql(value):
"""Remove taint after sanitization"""
if isinstance(value, TaintedStr):
sanitized = value.replace("'", "''")
return str(sanitized)
return value
username = TaintedStr(user_input, "HTTP_PARAM")
safe_username = sanitize_sql(username)
query = f"SELECT * FROM users WHERE name='{safe_username}'"
Multi-Level Taint
class TaintLevel:
UNTAINTED = 0
LOW = 1
MEDIUM = 2
HIGH = 3
class TaintedStr(str):
def __init__(self, value, taint_level=TaintLevel.UNTAINTED):
self.taint_level = taint_level
public_data = TaintedStr(data, TaintLevel.LOW)
user_input = TaintedStr(input, TaintLevel.HIGH)
Constraints
- Preserve semantics: Taint tracking shouldn't change program behavior
- Minimal overhead: Keep performance impact low
- Complete coverage: Track all taint propagation paths
- Accurate detection: Minimize false positives and negatives