Files
gh-project-codeguard-rules/skills/software-security/rules/codeguard-0-input-validation-injection.md
2025-11-30 08:48:30 +08:00

4.8 KiB
Raw Blame History

description, languages, alwaysApply
description languages alwaysApply
Input validation and injection defense (SQL/LDAP/OS), parameterization, prototype pollution
c
go
html
java
javascript
php
powershell
python
ruby
shell
sql
typescript
false

rule_id: codeguard-0-input-validation-injection

Input Validation & Injection Defense

Ensure untrusted input is validated and never interpreted as code. Prevent injection across SQL, LDAP, OS commands, templating, and JavaScript runtime object graphs.

Core Strategy

  • Validate early at trust boundaries with positive (allowlist) validation and canonicalization.
  • Treat all untrusted input as data, never as code. Use safe APIs that separate code from data.
  • Parameterize queries/commands; escape only as last resort and contextspecific.

Validation Playbook

  • Syntactic validation: enforce format, type, ranges, and lengths for each field.
  • Semantic validation: enforce business rules (e.g., start ≤ end date, enum allowlists).
  • Normalization: canonicalize encodings before validation; validate complete strings (regex anchors ^$); beware ReDoS.
  • Freeform text: define character class allowlists; normalize Unicode; set length bounds.
  • Files: validate by content type (magic), size caps, and safe extensions; servergenerate filenames; scan; store outside web root.

SQL Injection Prevention

  • Use prepared statements and parameterized queries for 100% of data access.
  • Use bind variables for any dynamic SQL construction within stored procedures and never concatenate user input into SQL.
  • Prefer leastprivilege DB users and views; never grant admin to app accounts.
  • Escaping is fragile and discouraged; parameterization is the primary defense.

Example (Java PreparedStatement):

String custname = request.getParameter("customerName");
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";  
PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, custname);
ResultSet results = pstmt.executeQuery( );

LDAP Injection Prevention

  • Always apply contextappropriate escaping:
    • DN escaping for \ # + < > , ; " = and leading/trailing spaces
    • Filter escaping for * ( ) \ NUL
  • Validate inputs with allowlists before constructing queries; use libraries that provide DN/filter encoders.
  • Use leastprivilege LDAP connections with bind authentication; avoid anonymous binds for application queries.

OS Command Injection Defense

  • Prefer builtin APIs instead of shelling out (e.g., library calls over exec).
  • If unavoidable, use structured execution that separates command and arguments (e.g., ProcessBuilder). Do not invoke shells.
  • Strictly allowlist commands and validate arguments with allowlist regex; exclude metacharacters (& | ; $ > < ` \ ! ' " ( ) and whitespace as needed).
  • Use -- to delimit arguments where supported to prevent option injection.

Example (Java ProcessBuilder):

ProcessBuilder pb = new ProcessBuilder("TrustedCmd", "Arg1", "Arg2");
Map<String,String> env = pb.environment();
pb.directory(new File("TrustedDir"));
Process p = pb.start();

Query Parameterization Guidance

  • Use the platforms parameterization features (JDBC PreparedStatement, .NET SqlCommand, Ruby ActiveRecord bind params, PHP PDO, SQLx bind, etc.).
  • For stored procedures, ensure parameters are bound; never build dynamic SQL via string concatenation inside procedures.

Prototype Pollution (JavaScript)

  • Developers should use new Set() or new Map() instead of using object literals
  • When objects are required, create with Object.create(null) or { __proto__: null } to avoid inherited prototypes.
  • Freeze or seal objects that should be immutable; consider Node --disable-proto=delete as defenseindepth.
  • Avoid unsafe deep merge utilities; validate keys against allowlists and block __proto__, constructor, prototype.

Caching and Transport

  • Apply Cache-Control: no-store on responses containing sensitive data; enforce HTTPS across data flows.

Implementation Checklist

  • Central validators: types, ranges, lengths, enums; canonicalization before checks.
  • 100% parameterization coverage for SQL; dynamic identifiers via allowlists only.
  • LDAP DN/filter escaping in use; inputs validated prior to query.
  • No shell invocation for untrusted input; if unavoidable, structured exec + allowlist + regex validation.
  • JS object graph hardened: safe constructors, blocked prototype paths, safe merge utilities.
  • File uploads validated by content, size, and extension; stored outside web root and scanned.

Test Plan

  • Static checks for string concatenation in queries/commands and dangerous DOM/merge sinks.
  • Fuzzing for SQL/LDAP/OS injection vectors; unit tests for validator edge cases.
  • Negative tests exercising blocked prototype keys and deep merge behavior.