A local notes application can pass its unit tests while two security failures ship together. The route GET /notes/:id returns note 42 whenever an authenticated user requests it, even when note 42 belongs to another account. Separately, the application accepts a search term that reaches a database query without being safely handled. A third problem sits outside the repository’s custom code, where a package version carries a published security advisory. An attacker needs only a valid low-privilege account for the first flaw, a reachable HTTP endpoint for the second, and no source-code access for the dependency risk.
These failures expose the application’s attack surface, meaning every code path, runtime interface, and dependency boundary through which untrusted input or attacker-controlled behavior can affect the system. The defender’s question is not which scanner is best in general. We need to decide what evidence static application security testing, dynamic application security testing, and software composition analysis should produce for the same notes application, then use that evidence to decide whether a change may ship. Source repositories, running HTTP behavior, and third-party packages reveal different parts of the risk.
The smallest useful contrast is the request for /notes/42. Source analysis can identify the authorization condition that never compares the requesting user’s account with the note owner. Runtime analysis can send an authorized lab request as one user and observe whether the response exposes another user’s note. Dependency analysis can inspect the package manifest without invoking the vulnerable feature at all. Which observer can prove each claim depends on where the failure exists.
The trust boundaries in the notes application show where each kind of evidence begins and ends.
This diagram shows why no single scanner observes the browser input, application logic, database call, and external package boundary equally.
Because the three observers need a common target, the course uses one repository containing a locally owned, intentionally flawed notes application. The application accepts HTTP parameters and JSON bodies at the web API boundary, uses an identity established by the local login route, returns HTML or JSON responses, and sends database operations through its data-access layer. We scan only this local lab application and environments we control. Testing third-party services without written authorization is outside the course and may violate laws such as the Computer Fraud and Abuse Act in the United States or the Computer Misuse Act 1990 in the United Kingdom.
The repository carries two deliberate behaviors. One is an injection-prone search path, representative of CWE-89, Improper Neutralization of Special Elements used in an SQL Command. The other is broken object-level authorization on GET /notes/:id, the failure category OWASP API Security Top 10 2023 calls API1 Broken Object Level Authorization. The dependency manifest also names a deliberately outdated package with a known issue. These cases stay separate because a code finding, an HTTP observation, and a package advisory are not interchangeable proof.
The repository snapshot locates the routes, data access, and dependency declaration without executing any scan or request.