Skip to content

Commit 2ca2ed0

Browse files
committed
docs(blog): Improve spring-analyzer post
1 parent f5b7cf4 commit 2ca2ed0

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

src/content/blog/spring-analyzer.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Taint Analysis for Spring: Data Flow Beyond the Call Graph"
3-
description: "Conventional static analysis breaks where Spring's architecture begins — dependency injection, JPA persistence, framework configuration. OpenTaint traces tainted data through every layer, from injected services to database storage to dangerous API calls, distinguishing raw columns from sanitized ones."
3+
description: "AST-pattern analyzers break where Spring's architecture begins — dependency injection, JPA persistence, framework configuration. OpenTaint traces tainted data through every layer, from injected services to database storage to dangerous API calls, distinguishing raw columns from sanitized ones."
44
date: "2026-03-25"
55
updatedDate: "2026-03-25"
66
keywords:
@@ -17,9 +17,9 @@ author: "Seqra Team"
1717

1818
import Mermaid from "@/components/astro/Mermaid.astro";
1919

20-
Spring Boot's annotation-driven architecture creates data flows that are invisible to conventional static analysis. The mechanism is everywhere: an `@Autowired` injection crosses class boundaries with no call site the parser can see; JPA persistence links two HTTP endpoints through a database row with no shared code path; a template engine's configuration decides — at runtime, from a flag set in some other file — whether the call to `template.process()` is exploitable or harmless. Three different invisibilities, three different framework features, the same blind spot.
20+
Spring Boot's annotation-driven architecture creates data flows that are invisible to AST-pattern analyzers. The mechanism is everywhere: an `@Autowired` injection crosses class boundaries with no call site the parser can see; JPA persistence links two HTTP endpoints through a database row with no shared code path; a template engine's configuration decides — at runtime, from a flag set in some other file — whether the call to `template.process()` is exploitable or harmless. Three different invisibilities, three different framework features, the same blind spot.
2121

22-
These are not edge cases. They are the default architecture of most Java web applications. The post walks three progressively harder challenges — following data through dependency injection, connecting endpoints through persistence, and distinguishing dangerous fields from safe ones at per-column granularity — and shows what each demands of the engine. Generic SAST plateaus at the first; OpenTaint models all three.
22+
These are not edge cases. They are the default architecture of most Java web applications. The post walks three progressively harder challenges — following data through dependency injection, connecting endpoints through persistence, and distinguishing dangerous fields from safe ones at per-column granularity — and shows what each demands of the engine. AST-pattern analyzers plateau at the first; OpenTaint models all three.
2323

2424
## Single-Request Flows
2525

@@ -271,7 +271,7 @@ The same logic applies to sanitizers at read time. The `GET /api/messages/{id}/c
271271

272272
## Conclusion
273273

274-
The call graph is the wrong primitive for framework-driven Java. Annotations replace explicit calls; persistence connects endpoints with no shared code; configuration decides whether a sink is a sink. An analyzer built on the call graph plus pattern matching cannot see these flows — not because they are rare, but because the abstraction is wrong. OpenTaint commits to a richer abstraction: bean wiring, persistence boundaries, conditional sinks per-column taint. The cost is whole-program analysis that needs a build. The payoff is the findings the call graph alone cannot reach.
274+
The call graph is the wrong primitive for framework-driven Java. Annotations replace explicit calls; persistence connects endpoints with no shared code; configuration decides whether a sink is a sink. An analyzer built on the call graph plus pattern matching cannot see these flows — not because they are rare, but because the abstraction is wrong. OpenTaint commits to a richer abstraction: bean wiring, persistence boundaries, conditional sinks, per-column taint. The cost is whole-program analysis that needs a build. The payoff is the findings the call graph alone cannot reach.
275275

276276
Clone the [purpose-built Spring Boot demo](https://github.com/seqra/java-spring-demo) and reproduce every finding in this post.
277277

0 commit comments

Comments
 (0)