CWE-74: Injection (Generic)
Overview
Injection vulnerabilities occur when untrusted data is sent to an interpreter as part of a command or query without proper validation, sanitization, or parameterization. This generic category encompasses various injection types including SQL injection, command injection, LDAP injection, NoSQL injection, and expression language injection. Attackers exploit these vulnerabilities by manipulating input to break out of data context and execute arbitrary commands, queries, or code within the interpreter, potentially compromising confidentiality, integrity, and availability of the entire system.
OWASP Classification
A05:2025 - Injection
Risk
Critical: Injection vulnerabilities can lead to complete system compromise, including unauthorized data access, data modification or deletion, privilege escalation, remote code execution, and denial of service. Injection remains one of the most dangerous and prevalent vulnerability classes, consistently ranking in OWASP Top 10.
Remediation Steps
Core principle: Never concatenate untrusted input into commands, queries, or executable expressions; use parameterized APIs, prepared statements, and safe libraries that treat user data as data only, never as executable code.
Identify the Injection Point
Review the vulnerability report to locate:
- Source: Where untrusted input enters (HTTP parameters, headers, cookies, file uploads, external APIs)
- Sink: The interpreter receiving the tainted data (database, OS shell, LDAP server, expression evaluator)
- Data flow: How user input reaches the interpreter (direct concatenation, string formatting, template rendering)
- Injection type: SQL, command, LDAP, NoSQL, XML, expression language, etc.
Use Parameterized Queries/Safe APIs (Primary Defense)
Replace string concatenation with parameterized interfaces:
SQL Injection → Prepared Statements:
# VULNERABLE
query = f"SELECT * FROM users WHERE id = {user_id}"
# SECURE
query = "SELECT * FROM users WHERE id = ?"
cursor.execute(query, (user_id,))
Command Injection → Safe APIs:
# VULNERABLE
os.system(f"ping {hostname}")
# SECURE
subprocess.run(["ping", "-c", "4", hostname], check=True, capture_output=True)
LDAP Injection → Escaped Parameters:
# VULNERABLE
filter = f"(uid={username})"
# SECURE
filter = f"(uid={ldap.filter.escape_filter_chars(username)})"
Input Validation (Defense in Depth)
Even with parameterization, validate all input:
- Type validation: Ensure integers are integers, dates are valid dates
- Format validation: Email addresses, phone numbers, UUIDs match expected patterns
- Allowlist validation: For enumerated values, check against allowed list
- Length limits: Prevent DoS via excessively long inputs
- Character restrictions: Reject special characters when not needed
Important: Input validation is NOT sufficient as sole defense against injection.
Apply Least Privilege
Limit blast radius if injection occurs:
- Database: Use accounts with minimum required permissions (SELECT-only for read operations, no DROP/ALTER rights)
- OS: Run processes with minimal privileges, not as root/administrator
- API keys: Scope tokens to specific operations only
Use ORM/Framework Security Features
Leverage framework protections:
- ORMs: Use Django ORM, Hibernate, Entity Framework with parameterized queries
- Template engines: Auto-escape by default (Jinja2, Razor, JSP with JSTL)
- Query builders: Use Knex.js, SQLAlchemy, LINQ with parameter binding
Monitor and Test
- Log all security-relevant operations (authentication, authorization, data access)
- Implement Web Application Firewall (WAF) rules for common injection patterns
- Regular penetration testing for injection vulnerabilities
- Code review focusing on data flow from untrusted sources to interpreters
Dynamic Scan Guidance
For guidance on remediating this CWE when detected by dynamic (DAST) scanners:
- Dynamic Scan Guidance - Analyzing DAST findings and mapping to source code