Skip to main content

06. Defenses & Secure Coding Cheatsheet

This chapter provides a quick-reference secure coding matrix, production static analysis (Semgrep SAST) rules, and a pull request security review checklist across Python, Node.js, Go, and Java.


1. Multi-Language Secure Coding Matrix

Vulnerability CategoryPython FixNode.js FixGo FixJava Fix
A01: Broken Access ControlUser.query.filter_by(id=uid, owner_id=current_user).first_or_404()Doc.findOneAndDelete({_id: id, ownerId: req.user.id})db.Where("id = ? AND user_id = ?", id, userID).First(&res)@PreAuthorize("#order.username == authentication.name")
A02: Password Hashingargon2.PasswordHasher().hash(pwd)bcrypt.hash(pwd, 12)bcrypt.GenerateFromPassword([]byte(pwd), 12)Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8()
A02: Data EncryptionAES-256-GCM via cryptography.fernet / hazmatcrypto.createCipheriv('aes-256-gcm', key, iv)cipher.NewGCM(block)Cipher.getInstance("AES/GCM/NoPadding")
A03: SQL Injectioncursor.execute("SELECT * FROM u WHERE id = %s", (uid,))db.query("SELECT * FROM u WHERE id = $1", [uid])db.QueryRow("SELECT * FROM u WHERE id = ?", uid)PreparedStatement stmt = conn.prepareStatement(...)
A03: Command Injectionsubprocess.run(["ping", "-c", "1", valid_ip])execFile('ping', ['-c', '1', valid_ip])exec.Command("ping", "-c", "1", valid_ip)new ProcessBuilder("ping", "-c", "1", valid_ip).start()
A03: SSRF DefenseValidate IP subnet against 127.0.0.0/8, 169.254.0.0/16Verify DNS resolved IP before axios.get()Custom net.Dialer blocking internal CIDRsRestrict HttpClient target IP range
A05: XXE Defenseimport defusedxml.ElementTree as ETlibxmljs.parseXml(xml, { nonet: true })encoding/xml (Safe by default)dbf.setFeature("http://xml.org/sax/features/external-general-entities", false)

2. Production Semgrep SAST Rules (.semgrep.yml)

Save the following configuration as .semgrep.yml in your repository root to automatically catch critical OWASP Top 10 vulnerabilities during code reviews or CI/CD runs:

rules:
- id: python-sqli-string-formatting
patterns:
- pattern-either:
- pattern: $CURSOR.execute(f"..." + ...)
- pattern: $CURSOR.execute("..." % ...)
- pattern: $CURSOR.execute("...".format(...))
message: "Critical: Potential SQL Injection detected. Use parameterized queries (%s) instead of string formatting."
severity: ERROR
languages: [python]

- id: python-command-injection-shell-true
patterns:
- pattern: subprocess.$FUNC(..., shell=True, ...)
message: "Critical: Command Injection risk. Avoid subprocess execution with shell=True."
severity: ERROR
languages: [python]

- id: express-cors-dynamic-origin-echo
patterns:
- pattern: res.header("Access-Control-Allow-Origin", req.headers.origin)
message: "High: CORS Misconfiguration. Reflecting the Origin header dynamically with credentials allowed risks cross-domain data theft."
severity: ERROR
languages: [javascript, typescript]

- id: python-unsafe-xml-parser
patterns:
- pattern-either:
- pattern: lxml.etree.XMLParser(resolve_entities=True, ...)
- pattern: xml.etree.ElementTree.fromstring(...)
message: "High: Unsafe XML parsing detected. Use 'defusedxml' to prevent XXE and DTD bomb attacks."
severity: WARNING
languages: [python]

- id: python-ssrf-unvalidated-request
patterns:
- pattern: requests.$METHOD(request.args.get(...), ...)
message: "High: Potential SSRF flaw. Validate target URLs and block access to 169.254.169.254 and internal subnets."
severity: ERROR
languages: [python]

Running Semgrep in CI/CD

# Install Semgrep
pip install semgrep

# Scan repository using local rules file
semgrep --config .semgrep.yml .

3. OWASP ZAP DAST CLI Scan Automation

Execute OWASP ZAP against your staging environment automatically in CI/CD pipelines:

# Run OWASP ZAP Baseline Scan using Docker
docker run -v $(pwd):/zap/wrk/:rw -t zaproxy/zap-stable zap-baseline.py \
-t https://staging.example.com \
-g gen.conf \
-r zap_report.html

4. Pull Request (PR) Security Review Checklist

Use this checklist during code reviews to ensure OWASP Top 10 compliance:

CategoryAudit Verification ItemStatus
AuthenticationAre password hashes generated using Argon2id or bcrypt (work factor >= 12)?[ ]
AuthorizationDoes every route fetching/modifying database records verify ownership server-side?[ ]
Database QueriesAre ALL SQL queries parameterized without string formatting or concatenation?[ ]
Command ExecutionAre system calls using rigid argument vectors without passing through a shell?[ ]
SSRFAre user-supplied URLs validated against internal IP ranges (127.0.0.1, 169.254.169.254)?[ ]
CORSAre CORS origins strictly allowlisted rather than reflecting req.headers.origin?[ ]
SecretsAre all secrets/API keys injected via environment variables rather than hardcoded?[ ]
LoggingAre sensitive fields (passwords, SSNs, tokens) filtered from application logs?[ ]

[!TIP] Proactive Security Gate: Set up a pre-commit git hook with gitleaks and semgrep to block developers from committing hardcoded credentials or dangerous code patterns locally!


Next Chapter: 07. Hands-On Vulnerability Lab →

Share this guide