Secure coding, in the code.
ISO 27001:2022 A.8.28 (secure coding) is about applying secure-coding principles so that software does not ship with the kinds of weakness attackers rely on: injection, unsafe handling of input and output, insecure defaults. Of all the Annex A controls it is the one that lives most directly in the code, which makes the pull request the natural place to hold it.
The shapes the same control failure takes.
A.8.28 weakens when a change introduces a known-bad pattern or removes a guard against one. The recurring shapes:
A query is built by string concatenation
User input is interpolated straight into a SQL, shell, or query string instead of being passed as a parameter, opening an injection path.
Output is rendered unescaped
User-controlled data is written into HTML, a template, or a response without escaping, opening a cross-site-scripting path.
A security lint or check is disabled
A static-analysis rule or a security linter is silenced (an inline ignore, a disabled rule) to make a change pass rather than fixing what it flagged.
Untrusted input is deserialised
Data from outside the trust boundary is deserialised into objects or evaluated, a classic remote-code-execution pattern.
Validation is removed
Input validation or sanitisation that protected a path is dropped in a refactor, so malformed or hostile input now reaches the logic behind it.
A query stitched together from user input.
A search feature is being added. The quickest way to filter by the user's term is to drop it straight into the SQL string. It works for normal input, and it is a SQL injection: a crafted term can read or change data it should never reach.
- const rows = await db.query("SELECT * FROM items WHERE name = $1", [term])+ const rows = await db.query(`SELECT * FROM items WHERE name = '${term}'`)return rowsInterpolating the search term into the SQL string is a SQL-injection path: a crafted term breaks out of the string and runs as query logic. A.8.28 (secure coding) expects exactly this class of weakness to be avoided. Go back to a parameterised query, which keeps the input as data rather than code.
Secure coding is checked at the practice, and at the code.
An auditor looks for evidence that secure coding is part of your process: code review, static analysis, dependency scanning, and that findings are acted on. A change that introduces an injection path or disables a security check is the concrete failure behind that process, and it is visible in the diff. Catching it in review is both the fix and the evidence that the practice works.
A review, not a full SAST suite.
heygrc flags changes that touch A.8.28 and cites the control so the fix happens in the pull request. It is not a replacement for your static analysis or your security testing; it is the framework-aware layer that ties a secure-coding weakness to the control it breaks. heygrc is in early access.