Injection Flaws · Buffer Overflows · XSS · CSRF · Crypto · Secure Coding · Code Review
Study with Practice Tests →Domain 4 (~14%) of the CSSLP CBK. This domain covers writing secure code — eliminating injection flaws, preventing memory corruption, applying cryptography correctly, and conducting rigorous code review.
| Domain | Weight | Key Topics |
|---|---|---|
| 1. Secure Software Concepts | 10% | CIA triad, security principles, risk, trust models |
| 2. Secure Software Requirements | 14% | Requirements gathering, privacy, compliance, abuse cases |
| 3. Secure Software Design | 14% | Threat modeling, STRIDE, security architecture, auth design |
| 4. Secure Software Implementation | 14% | Secure coding, injection flaws, crypto, code review |
| 5. Secure Software Testing | 14% | SAST, DAST, IAST, fuzzing, pen testing |
| 6. Secure Software Lifecycle Management | 11% | SDLC integration, DevSecOps, metrics |
| 7. Secure Software Deployment & Ops | 11% | Deployment, configuration, patch management, IR |
| 8. Secure Software Supply Chain | 12% | Third-party risk, SBOM, CI/CD security |
Occurs when user input is concatenated directly into SQL queries, allowing attackers to alter query logic. The fix: parameterized queries (prepared statements). Input escaping is unreliable and can be bypassed via alternate encodings — parameterization is the only reliable defense.
Attacker injects malicious scripts into pages viewed by other users. Fix: context-aware output encoding — HTML, JS, URL, and CSS contexts each require different escaping. Content Security Policy (CSP) is defense-in-depth, not the primary fix.
Cross-Site Request Forgery tricks an authenticated user's browser into making unauthorized requests. Fix: CSRF tokens (synchronizer or double-submit) combined with the SameSite cookie attribute. HTTPS alone does not prevent CSRF.
Writing beyond allocated buffer boundaries corrupts adjacent memory, enabling code execution. Fix: use memory-safe languages (Rust, Go, Java), stack canaries, ASLR, and DEP/NX. In C/C++: bounds-check all array writes.
Never use ECB mode (same plaintext = same ciphertext, reveals patterns). Use AES-GCM or ChaCha20-Poly1305 for AEAD. Use bcrypt/Argon2 for passwords — never SHA-256 alone (too fast for brute-force). Never roll your own crypto implementation.
Manual security code review should cover: authentication, authorization, input validation, crypto usage, error handling, and secrets. 4-eyes principle: no self-approval. Complement with SAST tools (Checkmarx, SonarQube, Semgrep) — they find different classes of bugs than manual review.
Exam questions will try to make you choose input escaping as the answer. Parameterized queries / prepared statements are the correct and reliable fix for SQL Injection. WAF alone is insufficient. Escaping can be bypassed. Parameterization structurally separates code from data.
The CSSLP exam strongly tests this. Use established libraries: libsodium, OpenSSL, BouncyCastle. If a question asks about crypto implementation, always select the option that uses a standard library over a custom implementation — regardless of how "secure" the custom implementation sounds.
Domain 4 maps heavily to OWASP Top 10: A01 (Broken Access Control), A02 (Cryptographic Failures), A03 (Injection), A04 (Insecure Design), A05 (Security Misconfiguration). Know these categories and their primary mitigations — many exam questions are rooted in OWASP guidance.
Domain 4 covers a broad range of software vulnerability classes. Understanding the root cause — not just the name — is critical for selecting the correct mitigation on the exam.
| Vulnerability | Root Cause | Primary Fix |
|---|---|---|
| SQL Injection (SQLi) | User input concatenated into SQL string | Parameterized queries / prepared statements |
| Command Injection | User input passed to shell or OS command | Avoid shell calls; use API/library; allowlist inputs strictly |
| LDAP Injection | Unsanitized input in LDAP filter construction | Escape LDAP special chars; parameterize LDAP queries |
| XXE (XML External Entity) | XML parser resolves external entity declarations in untrusted XML | Disable external entity processing in parser configuration |
| XSS — Reflected | Input reflected in response without encoding | Output encoding; Content Security Policy (defense-in-depth) |
| XSS — Stored | Malicious payload persisted in DB, served to all visitors | Output encoding on render; input validation; CSP |
| XSS — DOM-based | Client-side JS writes attacker-controlled data to DOM | Use safe DOM APIs (textContent not innerHTML); DOMPurify |
| CSRF | Authenticated user's browser auto-sends cookies on cross-origin request | CSRF tokens (synchronizer/double-submit) + SameSite cookie |
| Vulnerability | Root Cause | Mitigations |
|---|---|---|
| Buffer Overflow | Write beyond allocated buffer boundary | Memory-safe languages; stack canaries; ASLR; DEP/NX; bounds checking |
| Integer Overflow | Arithmetic result exceeds type maximum — wraps around | Safe math libraries; explicit bounds checking before arithmetic |
| Format String Attack | User-controlled input used directly as printf format string | Always use printf("%s", input) — never printf(input) |
| Use-After-Free | Memory accessed via pointer after it has been freed | Set pointer to NULL after free; use smart pointers (C++); memory-safe languages |
| TOCTOU / Race Condition | Security check and resource use are non-atomic — state can change between them | Atomic operations; open-then-check pattern; file locking; avoid file-based security decisions |
Deserializing untrusted data can trigger Remote Code Execution (RCE) via gadget chains — sequences of pre-existing code objects in the application's classpath that are activated by the attacker-controlled object graph. The attacker doesn't inject new code; they craft the object structure to invoke existing dangerous code paths.
| Vulnerability | Root Cause | Primary Fix |
|---|---|---|
| SQL Injection | User input interpreted as SQL syntax | Parameterized queries |
| XSS (Cross-Site Scripting) | User input rendered as executable script | Context-aware output encoding |
| CSRF | Browser auto-sends credentials on cross-origin requests | CSRF tokens + SameSite cookie attribute |
| Buffer Overflow | Write past allocated memory boundary | Memory-safe languages; ASLR; stack canaries; DEP/NX |
| XXE | XML parser resolves external entities from untrusted input | Disable external entity processing in parser |
| Insecure Deserialization | Untrusted object graph invokes gadget chains | Avoid native deserialization of untrusted data; use JSON |
Secure coding practices form the day-to-day discipline that prevents vulnerabilities from entering the codebase. These practices apply across all languages and frameworks.
Client-side validation (JavaScript) is UX only — it can be bypassed by any attacker using browser dev tools, curl, or a proxy. All security validation must be performed server-side. Client-side validation is acceptable in addition to, but never instead of, server-side validation.
Allowlist (whitelist): Define exactly what IS valid — reject everything else. Most secure approach. Hard to bypass.
Blocklist (blacklist): Define what IS NOT valid. Inherently incomplete — attackers find bypasses via alternate encodings, new attack vectors, Unicode variations. Avoid for security validation.
Always normalize input before validating:
• URL-decode: %3C → <
• Unicode normalize: SELECT → SELECT
• Collapse path traversal: ../ sequences
Failing to canonicalize allows double-encoding bypass attacks.
| Context | What to Encode | Example |
|---|---|---|
| HTML body | & < > " ' | & → &, < → < |
| HTML attribute | & " ' < > | Always quote attributes; encode content |
| JavaScript | JS special chars, Unicode escapes | Use \uXXXX escaping; never inject into JS strings raw |
| URL | Non-alphanumeric characters | Percent-encode: space → %20 |
| CSS | CSS special characters | Escape values placed in style attributes/properties |
Error messages shown to users must never reveal: stack traces, database error messages, internal file paths, software versions, framework names, or server configurations. Each piece of info aids attacker reconnaissance (OWASP A05 — Security Misconfiguration).
On any error or unexpected condition, deny access by default — never grant. If the authorization check throws an exception, the user should be denied, not granted access. Logging should capture full detail server-side; users see only a generic message like "An error occurred."
Hardcoded secrets in source code end up in version control, logs, build artifacts, and containers — accessible to anyone with repo access and to attackers who compromise those systems. Use environment variables or secrets managers (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault).
4-eyes principle: No developer approves their own code. A second reviewer (ideally security-aware) must approve before merge.
SAST tools: Checkmarx, SonarQube, Semgrep — analyze source code for vulnerability patterns without executing. Find different bugs than manual review (taint tracking, pattern matching). Complement, don't replace, manual review.
Correct cryptography implementation is one of the most exam-tested areas of Domain 4. Know which algorithms are recommended, broken, or deprecated — and the common pitfalls that undermine even strong algorithms.
| Algorithm | Type | Status | Notes |
|---|---|---|---|
| AES-128 / AES-256 | Symmetric | Recommended | Use with GCM mode for AEAD; avoid ECB mode entirely |
| 3DES (Triple DES) | Symmetric | Deprecated | 64-bit block size — vulnerable to Sweet32 attack; replace with AES |
| DES | Symmetric | Broken | 56-bit key — brute-forced in hours; never use |
| RSA-2048+ | Asymmetric | Recommended | Key sizes below 2048 bits insufficient; use for encryption and digital signatures |
| ECC P-256 (ECDSA/ECDH) | Asymmetric | Recommended | Smaller key for equivalent security; preferred for TLS and mobile |
| ChaCha20-Poly1305 | Symmetric AEAD | Recommended | Alternative to AES-GCM; software-friendly; used in TLS 1.3 |
| Algorithm | Status | Use For | Notes |
|---|---|---|---|
| MD5 | Broken | Never security use | Collision attacks demonstrated; deprecated for all security purposes |
| SHA-1 | Broken | Never security use | SHAttered collision attack (2017); browsers reject SHA-1 TLS certs |
| SHA-256 / SHA-384 / SHA-512 | Recommended | Data integrity, HMAC, signatures | NOT for password hashing — too fast, enables brute-force |
| SHA-3 (Keccak) | Recommended | Data integrity, future-proofing | Different internal structure from SHA-2 (sponge construction) |
| bcrypt | Recommended | Password hashing | Cost factor controls slowness; automatic salting per hash |
| Argon2 | Recommended | Password hashing | Password Hashing Competition winner; memory-hard; prefer Argon2id |
| scrypt | Recommended | Password hashing | Memory-hard; tunable CPU and memory cost parameters |
Custom crypto implementations introduce subtle, hard-to-detect vulnerabilities. Use established, audited libraries: libsodium (high-level, opinionated), OpenSSL, BouncyCastle. Even security experts make implementation mistakes — standard libraries have been reviewed by cryptographers and tested by millions of deployments.
AES-ECB encrypts each 16-byte block independently with the same key. Identical plaintext blocks always produce identical ciphertext blocks — structural patterns in data are preserved and visible (the "AES-ECB penguin" example shows bitmap image structure survives encryption). Always use CBC, CTR, or preferably GCM.
In CTR and GCM modes, reusing a nonce with the same key is catastrophic: XORing two ciphertexts encrypted with the same keystream reveals the XOR of the two plaintexts. In GCM, nonce reuse allows forging authentication tags. Generate a fresh random nonce per encryption operation using a CSPRNG.
Math.random() and similar PRNG functions are not cryptographically secure — their output is predictable. Always use CSPRNG (Cryptographically Secure Pseudo-Random Number Generator): java.security.SecureRandom, crypto.getRandomValues() (JS), os.urandom() (Python), /dev/urandom (Unix).
AES-CBC and AES-CTR provide only confidentiality — no integrity protection. An attacker can flip bits in ciphertext to flip bits in plaintext without detection. Use AES-GCM or ChaCha20-Poly1305 (AEAD) which provide confidentiality + integrity + authentication in one operation. If using CBC, add a separate HMAC (Encrypt-then-MAC).
Without a salt, identical passwords produce identical hashes — enabling rainbow table attacks. bcrypt, Argon2, and scrypt automatically generate and store a unique per-user salt. Never use SHA-256 for passwords even with a manual salt — it's too fast (billions of hashes/second on GPU). The cost factor in bcrypt/Argon2 is designed to make brute-force computationally infeasible.
10 questions covering Domain 4 exam topics. Select your answer for each question, then click "Check Answers" to see your score and explanations.
printf(userInput) where userInput comes directly from a web form. This code is vulnerable to:Six memorable frameworks to lock in the highest-yield concepts from Domain 4. Each hook gives you a mental model that works under exam pressure.
SELECT * FROM users WHERE id = ? — the ? is always data, never SQL syntax. Escaping can be bypassed via alternate encodings. Parameterized queries are the ONLY reliable fix — not WAF alone, not escaping alone.Click any card to flip it and reveal the explanation. Use the Study Advisor below to explore any Domain 4 topic in depth.
Click a card to flip · Click again to flip back
Select a topic to explore key questions and concepts for that area of Domain 4.