# AppSec Vulnerable Code Screening Cheat Sheet by Language

![Interview Labs](/files/V8VjP4MnEb6IvB6ruoGN)

## AppSec Vulnerable Code Screening Cheat Sheet by Language

> **Purpose:** give candidates and reviewers a fast, repeatable way to inspect vulnerable-code snippets under interview pressure without scanners. This page is intentionally biased toward the first 2 to 5 minutes of analysis: what to look at first, what patterns are high signal, and how to explain findings crisply.

> **Use this page with:** [AppSec Engineer Code and Weakness Review Drills](/learning-labs-interview-and-templates/index-1/appsec-engineer-code-and-weakness-review-drills.md) and [Live Code-Review Drills and Answer Guides](https://github.com/D3One/Product-Security-Gitbook/blob/main/14-interview-labs/live-code-review-drills-and-answer-guides.md).

### The universal screening pattern

When a snippet lands on screen, scan in this order:

1. **Where does attacker-controlled input enter?** Request params, JSON body, headers, cookies, uploaded files, environment variables, CLI args, queue payloads, DB results, deserialized objects.
2. **Where are the dangerous sinks?** SQL, OS commands, filesystem writes, archive extraction, templates, redirects, authz decisions, crypto calls, serialization, reflection, unsafe native APIs.
3. **What protects the path?** Validation, output encoding, parameterization, allow-lists, authn, authz, object ownership checks, safe defaults, rate limits, audit logs.
4. **What business action is happening?** Money movement, role change, password reset, approval, export, delete, token issuance, tenant switch, webhook trust decision.
5. **What is the likely impact?** Code execution, data theft, cross-tenant access, privilege escalation, account takeover, denial of service, tampering, secret disclosure.
6. **What exact fix would you make first?** Name the vulnerable line, the control you would add, and the regression test you would write.

### A good 30-second opening statement

> "I would start by identifying the trust boundary and the dangerous sinks. In this snippet, untrusted input reaches **\[sink]** without **\[control]**. The primary issue is **\[weakness]**; the likely impact is **\[impact]**. I would fix it by **\[precise fix]** and add **\[test/guardrail]** so it does not regress."

### What you can usually skip on first pass

* harmless constant definitions and obvious DTOs;
* formatting, style, and naming nits;
* imports that are not security-relevant;
* comments unless they reveal hidden trust assumptions;
* framework boilerplate if it does not affect auth, validation, or I/O.

### Python

#### High-signal danger words and APIs

* `os.system`, `subprocess.run(..., shell=True)`, `subprocess.Popen(..., shell=True)`
* `eval`, `exec`, `ast.literal_eval` on untrusted input used incorrectly
* raw SQL via string formatting, `%`, `.format()`, f-strings
* `pickle.loads`, `yaml.load` with unsafe loader, `marshal`, `shelve`
* `hashlib.md5`, `hashlib.sha1` for passwords or integrity decisions
* `tempfile.mktemp`, unsafe file writes to predictable paths
* Flask/Django routes that mutate state without authz/CSRF/object ownership checks

#### What dangerous sections look like

* f-strings or concatenation around `SELECT`, `UPDATE`, `DELETE`, `ORDER BY`
* shell helpers that interpolate request params into command strings
* serializers/deserializers fed by cookies, queues, or uploaded files
* password reset, invite acceptance, admin endpoints guarded only by a shared token
* archive processing with no canonical path checks

#### What to say out loud

* "I see untrusted input flowing into a shell/SQL/deserialize sink."
* "This is structural injection, not only string injection, because `ORDER BY`/table names are also attacker-influenced."
* "The larger issue is broken authorization or tenant isolation, not just input validation."

#### Typical safe replacements

* parameterized queries with DB driver placeholders
* `subprocess.run([...], shell=False, check=True)` with allow-listed arguments
* `yaml.safe_load`, never `pickle` for untrusted data
* Argon2, `bcrypt`, or `scrypt` for passwords

### Java

#### High-signal danger words and APIs

* `Runtime.getRuntime().exec`, `ProcessBuilder` with attacker-influenced args
* string-built JDBC / JPA native queries
* `ObjectInputStream.readObject`, XML decoders, risky Jackson polymorphic config
* Spring controller methods missing `@PreAuthorize` or object ownership checks
* `MessageDigest.getInstance("MD5")` or SHA-1 for passwords/signatures
* `Files.write`, `Paths.get` with user-controlled path elements
* open redirects through `redirect:` or attacker-controlled `Location`

#### Dangerous section patterns

* repositories loading by `id` only when path also contains `tenantId`
* approval or delete endpoints that check authentication but not role or workflow state
* native queries with concatenated `ORDER BY`, search, tenant, or status filters
* download/export handlers returning entire entity objects or raw stack traces

#### What to say out loud

* "This looks like IDOR or broken object-level authorization because the lookup ignores tenant or ownership context."
* "I would not stop at the controller annotation; I want service-layer authorization and state-transition checks too."
* "The right remediation is a repository method constrained by tenant plus a policy service, not another inline `if` block."

#### Typical safe replacements

* `findByIdAndTenantId(...)` or equivalent object-scoped data access
* bean validation + allow-lists for sort/filter fields
* `PasswordEncoder` with strong algorithms
* safer deserialization and strict type handling

### C++

#### High-signal danger words and APIs

* `system`, `popen`, `exec*`
* `strcpy`, `strcat`, `sprintf`, `gets`, unchecked `memcpy`
* raw pointer arithmetic around buffers
* archive extraction with path concatenation
* manual crypto or homegrown token logic
* insecure random sources (`rand`) for security decisions
* deserialization of attacker-controlled binary formats with weak bounds checks

#### Dangerous section patterns

* fixed-size char buffers receiving unbounded input
* archive/file extraction logic that joins base dir + entry name blindly
* integer length fields used for allocation/copy without validating range
* unsafe narrowing conversions before buffer use
* network services parsing custom binary protocols without strict framing

#### What to say out loud

* "I would look for memory-safety bugs and trust-boundary mistakes before syntax details."
* "The extraction path is vulnerable to traversal unless canonicalized against the intended root."
* "Even if this is not obviously exploitable RCE, a denial-of-service or overwrite primitive is still serious."

#### Typical safe replacements

* safer abstractions (`std::string`, bounded APIs)
* canonical path validation using filesystem APIs
* strict bounds checking before allocation and copy
* least-privilege runtime and sandboxing where native parsing is unavoidable

### TypeScript / JavaScript

#### High-signal danger words and APIs

* `eval`, `new Function`, dynamic import from untrusted path
* `child_process.exec`, `execSync`, `spawn` with shell or interpolated args
* template rendering with unescaped HTML
* direct use of `req.query`, `req.body`, `req.headers` in SQL/NoSQL/redirects
* prototype pollution via merge helpers or unsafe deep merge
* JWT verification bugs, `alg=none` anti-patterns, weak secret handling
* NoSQL queries built directly from user objects

#### Dangerous section patterns

* spreading `req.body` into trusted objects (`{...req.body}`) without allow-listing
* Mongo queries using attacker-provided JSON directly
* Express middleware checking only `if (user.isAdmin)` without strong session or auth source
* SSR or template code returning attacker-controlled HTML snippets

#### What to say out loud

* "I am checking both data injection and object-shape abuse, because JavaScript ecosystems are also vulnerable to prototype pollution and auth bypass through implicit trust in object fields."
* "In Node.js, shell execution and broad object merges are both high-signal danger zones."

#### Typical safe replacements

* schema validation at boundaries
* allow-listed object mapping instead of mass assignment
* parameterized DB calls and ORM safe APIs
* safe templating defaults and output encoding

### PHP

#### High-signal danger words and APIs

* `include`, `require`, `include_once`, `require_once` with user-controlled path
* raw `$_GET`, `$_POST`, `$_COOKIE`, `$_REQUEST` reaching SQL or file paths
* `unserialize`, dynamic function names, variable variables
* weak file upload handling, `move_uploaded_file` into web root
* `md5`, `sha1` for passwords or security tokens
* loose comparisons (`==`) in auth/token logic
* `shell_exec`, backticks, `exec`, `passthru`

#### Dangerous section patterns

* file paths built from request params
* session booleans used as the only control on admin actions
* report export features returning attacker-selected files
* comparison of secrets or auth values with loose equality
* upload handlers trusting extension or client MIME type

#### What to say out loud

* "I am checking for local file inclusion, traversal, and weak session assumptions first because those are common interview traps in PHP snippets."
* "Loose comparison is dangerous here if token or hash values are compared with `==`."

#### Typical safe replacements

* strict comparisons (`===`)
* allow-listed template identifiers
* `password_hash` / `password_verify`
* file storage outside web root with server-side generated names

### Go

#### High-signal danger words and APIs

* `exec.Command` with attacker-controlled program or arguments
* SQL built with `fmt.Sprintf` or concatenation
* unsafe deserialization or custom parsers without bounds checks
* `http.HandleFunc` handlers mutating state without authz/CSRF checks
* `crypto/md5`, `crypto/sha1` used for passwords or security decisions
* archive extraction or filesystem writes without path normalization
* direct exposure of internal errors in HTTP responses

#### Dangerous section patterns

* path params or JSON fields passed into SQL or filesystem helpers
* privileged admin endpoints missing actor/role verification
* `http.ListenAndServe` with weak TLS posture for sensitive services
* goroutines masking time-of-check/time-of-use state bugs in approval flows

#### What to say out loud

* "In Go I would still follow the same model: source, sink, authz, state transition, then exact fix."
* "If I see `fmt.Sprintf` around SQL, that is an immediate injection smell."

#### Typical safe replacements

* prepared statements / query parameterization
* strict object mapping from request DTOs to domain structs
* safe archive extraction helpers and canonical path checks
* explicit authz middleware and policy services

### SQL

#### High-signal danger words and patterns

* dynamic SQL with concatenated user input
* `EXEC`, `sp_executesql`, procedural dynamic query builders
* wildcard privileges and broad grants
* missing tenant filters in multi-tenant tables
* functions or procedures performing privileged actions without caller checks
* ad hoc reporting queries with attacker-controlled `ORDER BY`, table, or column names

#### What dangerous sections look like

* procedure parameters inserted into SQL text directly
* audit or export procedures not scoped by actor or tenant
* grants to application accounts that exceed CRUD needs
* maintenance procedures callable by application identities

#### What to say out loud

* "I am checking both injection and authorization inside the data layer. Even a safe query can still be a security bug if it ignores tenant or ownership filters."
* "Structural elements such as sort fields, table names, or procedure names must be allow-listed, not escaped."

#### Typical safe replacements

* parameters for values, allow-lists for structural SQL choices
* least-privilege DB accounts
* views or row-level security where appropriate
* immutable audit patterns for sensitive state changes

### One-page answer structure for any language

When the interviewer asks you to explain the snippet, use this shape:

1. **Call out the trust boundary.** "Input comes from request body / path / cookie / queue message."
2. **Name the sink.** "That input reaches SQL / shell / file include / deserializer / approval action."
3. **Name the weakness precisely.** SQL injection, IDOR, broken authz, path traversal, weak crypto, insecure deserialization, mass assignment.
4. **State the impact in business terms.** Data theft, cross-tenant access, admin takeover, workflow abuse, privilege escalation.
5. **Give the first fix and the durable fix.** Parameterize now, then add policy guardrails / tests / lint rules / codeowners / safer abstractions.
6. **Mention how you would verify.** Unit test, negative test, integration test, policy gate, regression rule.

### The short list of danger words to memorize

* **Execution:** `exec`, `system`, `shell`, `Runtime.exec`, `subprocess`, `ProcessBuilder`, `child_process`
* **Deserialization:** `pickle`, `unserialize`, `readObject`, unsafe `yaml.load`
* **Crypto:** `md5`, `sha1`, custom crypto, static IVs, ECB, hardcoded keys
* **Filesystem:** `include`, `require`, `open`, `fopen`, `Paths.get`, archive extract, temp file helpers
* **Database:** string-built `SELECT/UPDATE/DELETE`, `ORDER BY`, `LIMIT`, dynamic SQL, raw query APIs
* **Auth:** `isAdmin`, `role`, `tenantId`, `ownerId`, `approved`, `reset`, `invite`, `token`, `session`
* **Web:** redirect, template, HTML, upload, webhook, callback, origin, CORS

### Final coaching note

Interviewers are usually not looking for every issue in the snippet. They are looking for whether you can:

* find the **highest-risk issue first**;
* explain it in **clear engineering language**;
* propose a **realistic fix**;
* show you understand **blast radius**, **trust boundaries**, and **how to prevent recurrence**.

A calm, prioritized answer beats a chaotic list of ten possible bugs every time.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.product-security.expert/learning-labs-interview-and-templates/index-1/appsec-vulnerable-code-screening-cheat-sheet-by-language.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
