Types of security testing, and what each one catches
Six types. For each one: what it does, what it finds, what it cannot see, and when it runs. The last two columns are the ones that decide whether your programme has a hole in it.
Static application security testing (SAST)
SAST reads your source code without running it, looking for patterns that are known to be dangerous.
What it catches: string concatenation into a database query, a password written into a config file, weak or obsolete cryptography, unvalidated input reaching something that executes it, and user data written into a page without escaping.
What it cannot see: anything that depends on how the application is deployed or configured, whether the risky code path is reachable in practice, or whether your access rules are the right rules. It reads text, and it has no idea what your business considers allowed.
The honest problem with it: SAST produces false positives, sometimes a lot of them. That is a consequence of reading code without running it, not a flaw in any particular tool. It means the output is a queue of things to look at rather than a list of things to fix, and a team that treats every finding as a defect will abandon the tool within a quarter.
When it runs: on every commit, and in the developer's editor if the tool supports it. Speed matters more than depth here, because a check that adds ten minutes to a build gets switched off.
Dynamic application security testing (DAST)
DAST attacks a running version of the application from the outside, the way an attacker would, and it has no access to your code.
What it catches: injection that actually works rather than injection that merely looks possible, endpoints you forgot were exposed, missing or misconfigured security headers, weak session handling, and error pages that reveal more than they should.
What it cannot see: where in the code the problem is, anything behind a login it has not been given credentials for, which is most of the interesting surface unless you configure it properly, and anything in a code path it never reached.
Why it is worth the trouble: everything DAST reports is real. It did the thing, and the application allowed it. That makes triage far cheaper than SAST triage, and it makes DAST findings much easier to get prioritised.
When it runs: nightly, against a deployed build in a non-production environment. It is slower than a unit test suite, and it can leave test data behind, so it does not belong in the path of somebody waiting to merge.
Software composition analysis (SCA) and the supply chain
SCA inventories every library your application pulls in, including the ones your libraries pull in, and checks them against published vulnerabilities.
This is the highest-return scan for most teams, and it is the one most often missing. The reason is arithmetic: most of the code shipping in your application was written by somebody else. You review your own code in pull requests, and nobody reviews the four hundred packages underneath it.
What it catches: known vulnerabilities in dependencies, including deep ones you never chose; licence problems, which is a different risk but the same tool; and packages that have been abandoned.
What it cannot see: whether you actually call the vulnerable function. A critical vulnerability in a code path your application never touches is not the same risk as one in your login flow, and most tools will report both the same way. Reachability analysis helps and is not universal yet.
The other thing it produces: a list of what is in your software. Customers and auditors increasingly ask for a software bill of materials, and the SCA tool is where it comes from.
When it runs: on every build, and again on a schedule even when nothing changed, and that second run is the one teams forget. Your code did not change last month; the list of known vulnerabilities did.
Penetration testing
People, not tools. A tester is given a scope and time, and tries to break the application the way a determined attacker would.
What it catches: the problems that require understanding, and chains where three small weaknesses combine into one real compromise. Business-logic flaws: the discount that can be applied twice, the export that returns another tenant's records, the workflow step that can be skipped. No scanner expresses these, because they are not violations of a rule — they are violations of intent, and only a person knows the intent.
What it cannot do: be continuous. A penetration test is a photograph of one moment. The code changed the week after, and the report is now about a version that no longer exists. It is also expensive enough that most organisations do it once or twice a year.
How to get value from one: give the tester credentials and an architecture walkthrough. An unauthenticated black-box test spends most of its time discovering things you could have told them in ten minutes, and you paid for that time. Fix what comes back and then re-test the fixes; a report with no re-test is a list of things you believe are fixed.
When it runs: before a major release, after a significant architectural change, and on whatever annual cycle your customers or regulators expect.
This is also the clearest example of why automated vs manual testing is not a choice between two options but a division of labour. Automation covers the known. People cover the unanticipated. Where a deeper engagement is warranted, our cybersecurity consulting services team scopes and runs this work alongside the delivery team rather than as a separate exercise.
Vulnerability scanning and configuration checks
This is the infrastructure side, and it is where a large share of real incidents begin. Not clever code exploits — a storage bucket left open, a management port reachable from the internet, a component three versions behind.
What it catches: unpatched operating systems and runtimes, open ports and services nobody meant to expose, default credentials, storage and database instances with permissive access, and certificates about to expire.
What it cannot see: anything about your application's own logic. It tells you the door is unlocked, not that the rules about who may come through it are wrong.
Where it now overlaps with development: infrastructure is code, so infrastructure can be scanned before it exists. Checking a Terraform or CloudFormation file catches the public bucket while it is still a pull request rather than after it is live. Container images get the same treatment, because a base image carries somebody else's operating system into your estate.
When it runs: continuously against running environments, and on every change to infrastructure code.
Secure code review and threat modelling
The two human activities, and the two most often skipped because neither produces a report with a number in it.
Secure code review is a person reading a change with security in mind. It catches what SAST cannot, because it understands what the code is for: authorisation checks that are missing rather than wrong, a new endpoint that quietly returns more than it should, a fix that only handles the case somebody happened to think of. In practice this works best as a standing question in the pull request template rather than a separate ceremony.
Threat modelling happens before any code exists. A room, a whiteboard, the design, and one question: what could go wrong here? Where does data come in from outside, what could someone send instead, who is allowed to do what, and what happens if that check fails?
It takes an hour or two, needs no tools, and is the only security activity on this page with no technology substitute. It is also the only one that can remove a vulnerability class entirely instead of finding instances of it, because the answer may be to design the feature differently.
The reason it gets skipped is that it produces no artefact anybody can count. That is exactly why it is worth writing down: a short list of what could go wrong, kept with the design, becomes the list of things to test later.
SAST versus DAST, in one paragraph
SAST reads the code and sees everything, including a great deal that is not real. DAST attacks the running application and sees only what is reachable, but everything it finds is real. SAST tells you where the problem is in the source; DAST tells you that the problem works. They find different things, so which is better is the wrong question — and if you can only afford one of the three, take SCA, because most of your code is somebody else's and that is where the known vulnerabilities already are. The individual tools for all of this sit in our note on software testing tools.