SAST Fundamentals and Secure Coding Concepts
What this domain tests
This domain checks whether you understand how CxSAST decides that a line of code is a vulnerability, and whether you can map results back to secure-coding patterns. Questions rarely ask for a definition; they ask you to judge a code snippet, a sanitizer, or a claimed false positive.
The taint model behind every result
Every flow-based CxSAST query is built from four elements:
- Source - where untrusted data enters: request parameters, headers, cookies, file reads, command-line arguments, environment variables.
- Propagation - assignments, concatenation, collection inserts, return values, aliasing.
- Sink - the dangerous operation: SQL execution, OS command, file path, HTML output, deserialization, crypto call.
- Sanitizer - an operation that makes the data safe for that sink class.
Sanitizers are sink-specific. HTML encoding neutralizes an XSS sink but does nothing for a SQL sink, and a PreparedStatement is not a sanitizer for Runtime.exec. Control-flow influence (a value deciding whether a sink runs) is reported by some queries too, which is why branch conditions matter.
Secure-coding mapping
Injection → parameterization or allowlisting; XSS → context-aware output encoding; path traversal → canonicalization plus a prefix check; XXE → disable DTDs and external entities; hardcoded secrets → a secret store; weak crypto → AEAD ciphers and current hashes. CxSAST cannot see runtime configuration, container flags, or effective permissions - that is DAST/configuration territory, while dependency versions belong to SCA.
Worked example
String q = "SELECT * FROM t WHERE id=" + request.getParameter("id"); stmt.executeQuery(q);
getParameter is a registered source, concatenation propagates, executeQuery is a SQL sink, and no sanitizer sits on the path - confirm it as genuine SQL injection. Change it to ps.setString(1, id) on a constant query string and the value is bound, so the flow ends. But if the identifier (ORDER BY column) is appended to the prepared statement, it is still exploitable: identifiers cannot be bound.
Traps that cost marks
- Reading "no results" as "no vulnerability": unsupported frameworks, missing models, or excluded folders hide flows.
- Accepting a function as a sanitizer because its name sounds safe.
- Equating severity with exploitability when prioritizing a fix.
- Assuming SAST validates runtime behavior or dependency versions.