Static Application Security Testing
dpndncY's SAST is a proprietary AST + data-flow engine with real interprocedural taint tracking across 24 languages. User input is followed from a source, through propagation and sanitisers, to a sink — and every finding ships a step-by-step data-flow trace and a CWE/OWASP mapping. It is not regex pattern matching.
How a finding is proven
A SAST finding is only emitted when a tainted value provably reaches a dangerous sink. The engine models three things per language:
- Sources — where untrusted input enters (request params, headers, cookies, env, argv, file/socket reads, framework request objects).
- Sanitisers — calls that neutralise taint for a given sink class (parameterised queries, HTML encoders, path canonicalisers, validators). A sanitiser on the path kills the finding.
- Sinks — dangerous operations (SQL exec, command exec, file open, HTML write, redirect, deserialise, eval, …) tagged with a CWE/OWASP class and severity.
Propagation tracks assignments and flows across function calls (interprocedural, depth-bounded), so a value tainted in one function and passed into another is still caught.
Languages
Interprocedural taint models exist for all of the following (24):
JavaScript · TypeScript · Python · Java · Kotlin · Scala · Groovy · C# · VB.NET · Go · PHP · Ruby · Swift · Objective-C · Objective-C++ · Dart · Apex · C · C++ · CUDA · Fortran · JSP · Erlang · Elixir
Framework awareness
Taint sources are a framework’s request-input APIs, so one model covers many frameworks. dpndncY ships precision models for the common server-side and client-side frameworks:
| Stack | Frameworks |
|---|---|
| Java | Spring, JAX-RS, Struts, Hibernate/JPA, JSF, Apache Shiro, Vert.x |
| .NET | ASP.NET Core / MVC / Web API / Web Forms, WCF, Razor |
| Node | Express, Koa, Fastify, Hapi, Restify, Next.js |
| Frontend | Angular, React, Vue, jQuery, Ember, Backbone + template engines (Handlebars, Pug, EJS, Nunjucks) |
| Python | Django, Flask, aiohttp, SQLAlchemy |
| Go | Gin, Echo, Fiber, fasthttp, Buffalo, Beego, Gorilla |
| Others | Rails (Ruby), Symfony/Laravel (PHP), Flutter (Dart), Phoenix (Elixir) |
Controller parameters bound by an annotation — @RequestParam, @QueryParam, [FromQuery], [FromBody] — are treated as user-controlled and tainted into the method body.
Vulnerability classes
SQL injection (CWE-89), command injection (CWE-78), code injection / eval (CWE-95), server-side template injection (CWE-1336), XSS (CWE-79), path traversal (CWE-22), SSRF (CWE-918), open redirect (CWE-601), insecure deserialisation (CWE-502), LDAP injection (CWE-90), log injection (CWE-117), buffer overflow & format-string for C/C++ (CWE-120/134), prototype pollution (CWE-1321), and XXE.
Example
@GetMapping("/u")
public String user(@RequestParam("id") String id) { // ← source (annotated param)
String sql = "SELECT * FROM users WHERE id=" + id; // ← propagation (concat)
return jdbc.executeQuery(sql); // ← sink (CWE-89)
}The same code with a PreparedStatement + setString binding is not flagged — the parameterised binding is a recognised sanitiser, so the taint never reaches the sink.
Custom rules & suppression
- Author custom sources/sinks/sanitisers in a YAML DSL.
- Suppress a specific finding inline with a comment annotation, tracked with a reason for audit.
Output & CI
- SARIF 2.1.0 — ingests natively into GitHub code-scanning and GitLab SAST.
- Per-finding: rule id, CWE/OWASP, severity, confidence, and the full data-flow trace.
See also
- SCA · Attack-path graph
- Policy reference — gating on SAST severities