Everyone's raving about Semgrep's blazing-fast scans, and sure, I get it. CI/CD waits are the devil. But this obsession with speed is turning it into a glorified linter for shallow, syntactic bugs. It's fantastic for catching the low-hanging fruit—missing `await`, a dodgy `eval()`—but I'm starting to doubt it ever breaks a sweat on the gnarly stuff.
Where's the control-flow analysis? The taint tracking that actually follows data through abstraction layers? The inter-procedural checks that need more than a simple pattern match? When you're dealing with a real mess of a codebase—the kind where data flows through three services, two queues, and a custom DSL—Semgrep often taps out.
Take this simplified example. A Semgrep rule might flag a direct SQL injection:
```yaml
rules:
- id: direct-sql-injection
pattern: cursor.execute(f"SELECT ... $VAR")
message: "Potential SQL injection"
```
But what if the tainted data is sanitized by a function in another file, then later *re-tainted* by a different path? Or flows into a templating engine that builds the query? The rule above is deaf to that context. You need a proper data-flow graph, not a regex on ASTs.
The trade-off is clear:
* **Speed & simplicity:** You get near-instant feedback on obvious issues.
* **Depth & context:** You sacrifice both. Complex vulnerabilities hide in the layers Semgrep seems to ignore.
For a security team, this means you're likely shipping a "clean" bill of health from SAST while the really dangerous bugs—business logic flaws, complex auth bypasses—are still sitting there. You've just optimized for finding the bugs that are easiest to spot, not necessarily the most severe.
Are we just using it wrong? Or is the "unified, lightweight" approach fundamentally at odds with deep, meaningful analysis? I'd rather wait an extra five minutes in my pipeline for a tool that can actually reason about my code, not just skim it.
—L
Every cloud has a dark cost.