<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mattybellx</title>
    <description>The latest articles on DEV Community by mattybellx (@mattybellx).</description>
    <link>https://dev.to/mattybellx</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4008474%2F59ad264d-dfe7-4e97-93ff-dc44fb83bea1.png</url>
      <title>DEV Community: mattybellx</title>
      <link>https://dev.to/mattybellx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mattybellx"/>
    <language>en</language>
    <item>
      <title>I Benchmarked 4 SAST Tools Against 164 CVEs — Here's What Found 100% of Them</title>
      <dc:creator>mattybellx</dc:creator>
      <pubDate>Fri, 17 Jul 2026 15:21:52 +0000</pubDate>
      <link>https://dev.to/mattybellx/i-benchmarked-4-sast-tools-against-164-cves-heres-what-found-100-of-them-3m66</link>
      <guid>https://dev.to/mattybellx/i-benchmarked-4-sast-tools-against-164-cves-heres-what-found-100-of-them-3m66</guid>
      <description>&lt;p&gt;If you're building software in 2026, you probably have some form of security scanning. Bandit for Python. GitHub's built-in CodeQL. Maybe Semgrep.&lt;/p&gt;

&lt;p&gt;But how good are these tools actually — tested against real, known vulnerabilities?&lt;/p&gt;

&lt;p&gt;I curated 164 CVEs across 5 languages and ran 4 free SAST tools. Results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ansede: 100% (164/164)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;CodeQL: 33.6%&lt;/li&gt;
&lt;li&gt;Bandit: 30.9% (Python only)&lt;/li&gt;
&lt;li&gt;Semgrep CE: 23.2%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The gap is authorization bugs — IDOR, missing auth. Most free tools analyze single functions. Detecting IDOR requires tracing HTTP routes → auth guards → database queries across function boundaries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/invoice/&amp;lt;id&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_invoice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Invoice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="c1"&gt;# All 3 other tools: silent
&lt;/span&gt;    &lt;span class="c1"&gt;# Ansede: IDOR — any user can view any invoice
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;False positives on 125 clean snippets: Ansede 0. Semgrep CE: 20-60%.&lt;/p&gt;

&lt;p&gt;Reproduce: pip install ansede-static &amp;amp;&amp;amp; python -m benchmarks.one_click_compare&lt;/p&gt;

&lt;p&gt;Full methodology: github.com/mattybellx/Ansede&lt;/p&gt;

&lt;p&gt;What SAST tools do you use? Have you benchmarked them?&lt;/p&gt;

</description>
      <category>security</category>
      <category>python</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Just made my fully offline security scanner free to use online, try it here: https://ansede.onrender.com/scan</title>
      <dc:creator>mattybellx</dc:creator>
      <pubDate>Thu, 09 Jul 2026 17:59:29 +0000</pubDate>
      <link>https://dev.to/mattybellx/just-made-my-fully-offline-security-scanner-free-to-use-online-try-it-here-3iej</link>
      <guid>https://dev.to/mattybellx/just-made-my-fully-offline-security-scanner-free-to-use-online-try-it-here-3iej</guid>
      <description>&lt;p&gt;Try break it or find any errors :)&lt;/p&gt;

</description>
      <category>security</category>
      <category>cybersecurity</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Built a 100% Offline SAST Scanner That Finds What Semgrep and CodeQL Miss</title>
      <dc:creator>mattybellx</dc:creator>
      <pubDate>Wed, 08 Jul 2026 20:30:54 +0000</pubDate>
      <link>https://dev.to/mattybellx/i-built-a-100-offline-sast-scanner-that-finds-what-semgrep-and-codeql-miss-30j0</link>
      <guid>https://dev.to/mattybellx/i-built-a-100-offline-sast-scanner-that-finds-what-semgrep-and-codeql-miss-30j0</guid>
      <description>&lt;p&gt;I spent the last few months building a fully offline SAST security scanner that I think deserves more attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Most free static analysis tools (Bandit, Semgrep OSS) focus on injection bugs like SQLi and XSS. They completely miss &lt;strong&gt;authorization flaws&lt;/strong&gt; — the IDOR, auth bypass, and ownership verification issues that cause real data breaches. Tools like CodeQL can find these but require manual query writing and a massive database.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Ansede Static Does Differently
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Built-in IDOR/auth bypass detection&lt;/strong&gt; — no custom rules needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100% offline&lt;/strong&gt; — no API keys, no network calls, no compilation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;6 languages&lt;/strong&gt; — Python, JavaScript/TypeScript, Go, Java, C#, Rust&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100% CVE recall&lt;/strong&gt; (164/164 across 5 languages) — Semgrep OSS: 23%, CodeQL: 34%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;93.3% OWASP recall&lt;/strong&gt; — #1 among free tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Performance (v6.1.0, today's release)
&lt;/h2&gt;

&lt;p&gt;I just finished scanning 43 random repos with the new taint-aware demotion engine. Results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1,075 HIGH/CRITICAL findings → 205 suspected real vulns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;19.1% precision&lt;/strong&gt; on HIGH/CRIT — up from ~0% in previous versions&lt;/li&gt;
&lt;li&gt;0% HIGH/CRIT false negative rate (confirmed across 1,941+ findings)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Live playground (no install): &lt;a href="https://ansede.onrender.com/scan" rel="noopener noreferrer"&gt;https://ansede.onrender.com/scan&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;ansede-static
ansede-static src/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub: &lt;a href="https://github.com/mattybellx/Ansede" rel="noopener noreferrer"&gt;https://github.com/mattybellx/Ansede&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would love feedback from the security community!&lt;/p&gt;

</description>
      <category>python</category>
      <category>security</category>
      <category>sast</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Why Your SAST Scanner Misses 86% of Real Vulnerabilities</title>
      <dc:creator>mattybellx</dc:creator>
      <pubDate>Thu, 02 Jul 2026 13:29:04 +0000</pubDate>
      <link>https://dev.to/mattybellx/why-your-sast-scanner-misses-86-of-real-vulnerabilities-2ab7</link>
      <guid>https://dev.to/mattybellx/why-your-sast-scanner-misses-86-of-real-vulnerabilities-2ab7</guid>
      <description>&lt;h1&gt;
  
  
  Why Your SAST Scanner Misses 86% of Real Vulnerabilities
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;A data-driven comparison of modern static analysis tools, and why interprocedural taint analysis changes everything.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By the Ansede Static team · July 2026 · 12 min read&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Your SAST scanner is lying to you. Not maliciously — it just can't see most of what it's supposed to catch.&lt;/p&gt;

&lt;p&gt;We ran a controlled experiment: 164 known CVEs across Python, JavaScript, Go, Java, and C#. Three tools. Same corpus. Same conditions. Here's what happened:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;CVEs Detected&lt;/th&gt;
&lt;th&gt;Recall Rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ansede Static&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;158 / 164&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;96.3%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semgrep OSS&lt;/td&gt;
&lt;td&gt;38 / 164&lt;/td&gt;
&lt;td&gt;23.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeQL&lt;/td&gt;
&lt;td&gt;55 / 164&lt;/td&gt;
&lt;td&gt;33.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Semgrep missed &lt;strong&gt;77%&lt;/strong&gt; of known vulnerabilities. CodeQL missed &lt;strong&gt;66%&lt;/strong&gt;. These aren't obscure edge cases — they're CVEs with public exploit code, assigned severity scores, and patches shipped years ago.&lt;/p&gt;

&lt;p&gt;This post explains &lt;em&gt;why&lt;/em&gt;, what the architectural differences actually mean, and how to choose a SAST tool that finds real problems instead of generating noise.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Experiment: Fair, Reproducible, Brutal
&lt;/h2&gt;

&lt;p&gt;We built a corpus of 164 CVEs spanning 5 languages and 26 CWE categories. Every CVE has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A public advisory with a CVE ID&lt;/li&gt;
&lt;li&gt;Known-vulnerable source code we could clone&lt;/li&gt;
&lt;li&gt;A verified patch that fixes it&lt;/li&gt;
&lt;li&gt;At least a &lt;code&gt;HIGH&lt;/code&gt; CVSS severity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each tool was run with default settings, no custom rules, no tuning. The question was simple: &lt;strong&gt;"Does this tool detect this known vulnerability out of the box?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The full methodology, corpus, and scripts are open-source at &lt;a href="https://github.com/mattybellx/Ansede" rel="noopener noreferrer"&gt;github.com/mattybellx/Ansede&lt;/a&gt;. You can reproduce every number in about 10 minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Per-Category Breakdown
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CWE Category&lt;/th&gt;
&lt;th&gt;Cases&lt;/th&gt;
&lt;th&gt;Ansede&lt;/th&gt;
&lt;th&gt;Semgrep&lt;/th&gt;
&lt;th&gt;CodeQL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SQL Injection (CWE-89)&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;94.4%&lt;/td&gt;
&lt;td&gt;27.8%&lt;/td&gt;
&lt;td&gt;38.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Command Injection (CWE-78)&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;76.9%&lt;/td&gt;
&lt;td&gt;15.4%&lt;/td&gt;
&lt;td&gt;23.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Path Traversal (CWE-22)&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;77.8%&lt;/td&gt;
&lt;td&gt;33.3%&lt;/td&gt;
&lt;td&gt;22.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hardcoded Secrets (CWE-798)&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;9.1%&lt;/td&gt;
&lt;td&gt;18.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSRF (CWE-918)&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;16.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unsafe Deserialization (CWE-502)&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;18.2%&lt;/td&gt;
&lt;td&gt;27.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Redirect (CWE-601)&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;20.0%&lt;/td&gt;
&lt;td&gt;40.0%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weak Cryptography (CWE-327)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;33.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XSS / Template Injection&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;33.3%&lt;/td&gt;
&lt;td&gt;44.4%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two things jump out immediately: Semgrep's &lt;strong&gt;0% recall on SSRF, weak crypto, and weak random&lt;/strong&gt;, and CodeQL's &lt;strong&gt;single-digit recall on hardcoded secrets&lt;/strong&gt;. These aren't niche categories — they're OWASP Top 10 staples.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why the Gap? Pattern Matching vs. Data-Flow Analysis
&lt;/h2&gt;

&lt;p&gt;The core architectural difference comes down to one question: &lt;strong&gt;does the tool understand how data flows through your program?&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How Semgrep Works
&lt;/h3&gt;

&lt;p&gt;Semgrep is a &lt;em&gt;pattern-matching engine&lt;/em&gt;. It converts your code into an AST, then checks if any subtree matches a rule pattern. It's fast, it's clever, and it's fundamentally limited:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Semgrep rule: "request.getParameter(...) is tainted"
&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# ← Semgrep flags this
&lt;/span&gt;
&lt;span class="c1"&gt;# But what about this?
&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;# ← Semgrep flags this
&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;                    &lt;span class="c1"&gt;# ← Semgrep loses track here
&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users WHERE id=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# ← Semgrep: nothing to see here
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Semgrep matches patterns on AST nodes. It doesn't track how &lt;code&gt;y&lt;/code&gt; was derived from &lt;code&gt;x&lt;/code&gt; which was derived from &lt;code&gt;request.getParameter&lt;/code&gt;. Once the tainted value passes through a method call or assignment chain, the pattern match breaks.&lt;/p&gt;

&lt;p&gt;This is why Semgrep scores 0% on SSRF: the pattern &lt;code&gt;request.getParameter(...) → http.Get(...)&lt;/code&gt; almost never appears as adjacent AST nodes in real code. There are always intermediate variables, helper functions, or configuration lookups in between.&lt;/p&gt;

&lt;h3&gt;
  
  
  How CodeQL Works
&lt;/h3&gt;

&lt;p&gt;CodeQL builds a database of your code and runs declarative queries over it. It &lt;em&gt;can&lt;/em&gt; do data-flow analysis, but its default query packs are conservative — they prioritize low false-positive rates over high recall:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// CodeQL query: taint from RemoteFlowSource to SQL sink
from RemoteFlowSource source, SqlExecution sink
where source.flowsTo(sink)
select sink
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem: CodeQL's &lt;code&gt;RemoteFlowSource&lt;/code&gt; class is narrowly defined. It misses framework-specific taint sources (Flask &lt;code&gt;request.args&lt;/code&gt;, Express &lt;code&gt;req.params&lt;/code&gt;, Gin &lt;code&gt;c.Query&lt;/code&gt;). And its default security queries only cover a subset of CWEs — many categories have no query pack at all.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Ansede Works: IFDS Taint Analysis
&lt;/h3&gt;

&lt;p&gt;Ansede uses &lt;strong&gt;Interprocedural Finite Distributive Subset (IFDS)&lt;/strong&gt; analysis — the same algorithm underpinning academic static analysis research for 25 years.&lt;/p&gt;

&lt;p&gt;The key insight of IFDS: taint is a &lt;em&gt;distributive&lt;/em&gt; property. If data at point A is tainted, and data flows from A to B and from A to C, then both B and C are tainted. This sounds obvious, but implementing it correctly across function boundaries, method calls, field stores, and aliasing is what separates research-grade analysis from production tools.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                        ┌─────────────┐
  request.getParameter  │ Taint Source │  "id" is tainted
         │              └──────┬──────┘
         ▼                     │
    String x = ...             │  IFDS propagates taint
         │                     │  through assignments
         ▼                     │
    String y = x.strip()       │  "y" inherits taint from "x"
         │                     │
         ▼                     │
    db.execute("..." + y)  ◄───┘  Sink reached! Finding reported.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The IFDS solver builds a call graph, identifies sources (user input), propagates taint facts through the graph using distributive transfer functions, and checks whether any tainted value reaches a sink (SQL query, shell command, file path, HTTP request, etc.).&lt;/p&gt;

&lt;p&gt;This is why Ansede catches SSRF: it traces &lt;code&gt;request.getParameter&lt;/code&gt; → &lt;code&gt;config.getTargetUrl()&lt;/code&gt; → &lt;code&gt;httpClient.Get()&lt;/code&gt; across three function boundaries. No amount of AST pattern matching will ever connect those dots.&lt;/p&gt;




&lt;h2&gt;
  
  
  The IDOR Problem: What All Three Tools Miss
&lt;/h2&gt;

&lt;p&gt;Insecure Direct Object Reference (CWE-639) is the &lt;strong&gt;#1 OWASP API Security risk&lt;/strong&gt;. It's also invisible to most SAST tools because it requires understanding &lt;em&gt;intent&lt;/em&gt; — does this endpoint check that the requesting user owns the requested resource?&lt;/p&gt;

&lt;p&gt;Here's what Ansede's AST-native route→guard→sink analysis looks for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/orders/&amp;lt;order_id&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@login_required&lt;/span&gt;                         &lt;span class="c1"&gt;# ← Guard: user is authenticated
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;                &lt;span class="c1"&gt;# ← Route: parameterized endpoint
&lt;/span&gt;    &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# ← Sink: fetches by ID directly
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_dict&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;     &lt;span class="c1"&gt;# ← No ownership check!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pattern: a parameterized route, with an auth guard but &lt;strong&gt;no ownership check between the guard and the data access&lt;/strong&gt;. User A can access User B's order by changing &lt;code&gt;order_id&lt;/code&gt;. This is the most common API vulnerability in production, and neither Semgrep nor CodeQL have default rules for it.&lt;/p&gt;

&lt;p&gt;Ansede detects this by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identifying route handlers with path parameters&lt;/li&gt;
&lt;li&gt;Verifying auth guards are present (&lt;code&gt;@login_required&lt;/code&gt;, &lt;code&gt;@PreAuthorize&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Checking whether an ownership filter is applied to the data access (&lt;code&gt;WHERE user_id = current_user.id&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Flagging when step 3 is missing&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Real-World Scale: 58 Repos, 3.1M+ Lines
&lt;/h2&gt;

&lt;p&gt;Controlled benchmarks are useful, but what happens on real code? We scanned 58 real-world open-source repositories — 21,871 files, 3,186,097 lines of code, across Python, JavaScript, and Java:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Total Findings (meaningful)&lt;/th&gt;
&lt;th&gt;Scan Failures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ansede Static&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1,255&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeQL&lt;/td&gt;
&lt;td&gt;167&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That's a &lt;strong&gt;7.5x difference&lt;/strong&gt; in findings. Not because Ansede is noisier — because CodeQL's default queries simply don't cover most CWE categories. When a tool has no rule for "hardcoded secret" or "open redirect," it finds zero instances regardless of how many exist.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Honest Trade-offs
&lt;/h2&gt;

&lt;p&gt;Ansede is not better at everything. Here's where others win:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Winner&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Speed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Semgrep (2.7x faster)&lt;/td&gt;
&lt;td&gt;Semgrep is compiled OCaml with years of optimization. Ansede's IFDS solver takes ~87s for 2,740 files vs Semgrep's 32s. A Rust-native engine is on the roadmap.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Language Coverage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Semgrep (30+ languages)&lt;/td&gt;
&lt;td&gt;Ansede supports 5: Python, JS/TS, Go, Java, C#. Semgrep has Ruby, PHP, Kotlin, Swift, Rust, and more.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rule Ecosystem&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Semgrep (200+ community rules)&lt;/td&gt;
&lt;td&gt;Semgrep's registry has years of community contributions. Ansede has fewer rules, but each is AST-native and interprocedural.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Enterprise Features&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SonarQube / Checkmarx&lt;/td&gt;
&lt;td&gt;SSO, compliance dashboards, decades of enterprise polish. Ansede Pro adds LLM triage and SBOM — enterprise tier coming.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Install Simplicity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ansede / Bandit&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pip install&lt;/code&gt; — zero dependencies, no database, no Docker. Runs on any machine with Python 3.9+.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What This Means for You
&lt;/h2&gt;

&lt;h3&gt;
  
  
  If you use Semgrep:
&lt;/h3&gt;

&lt;p&gt;You're getting &lt;strong&gt;23% CVE coverage&lt;/strong&gt;. The 77% gap is real — test it yourself against our corpus. Add Ansede as a second scanner in your CI pipeline for the categories Semgrep misses (SSRF, crypto, secrets, IDOR).&lt;/p&gt;

&lt;h3&gt;
  
  
  If you use CodeQL:
&lt;/h3&gt;

&lt;p&gt;You're getting &lt;strong&gt;34% CVE coverage&lt;/strong&gt; with the default query packs. Enable experimental queries, write custom data-flow queries for your frameworks, and consider running Ansede alongside for hardcoded secrets, open redirects, and auth bypass patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  If you use Bandit:
&lt;/h3&gt;

&lt;p&gt;You're getting &lt;strong&gt;~20% CVE coverage&lt;/strong&gt; on Python only. Bandit is fast and simple, but it's pattern-based and single-file. It can't do interprocedural analysis. Ansede is a drop-in replacement: same &lt;code&gt;pip install&lt;/code&gt; experience, dramatically better coverage.&lt;/p&gt;

&lt;h3&gt;
  
  
  If you use nothing:
&lt;/h3&gt;

&lt;p&gt;Start with &lt;code&gt;pip install ansede-static&lt;/code&gt; (free, zero deps, 5 languages) and run it on your next PR. The &lt;code&gt;--strict&lt;/code&gt; flag filters to HIGH+CRITICAL findings only, keeping noise low while catching the patterns that matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;ansede-static
ansede-static &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--strict&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; sarif &lt;span class="nt"&gt;--output&lt;/span&gt; results.sarif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or run the full three-tool comparison on your own repos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/mattybellx/Ansede.git
&lt;span class="nb"&gt;cd &lt;/span&gt;Ansede
python benchmarks/one_click_compare.py &lt;span class="nt"&gt;--repo&lt;/span&gt; https://github.com/your/repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every benchmark in this post is &lt;strong&gt;fully reproducible&lt;/strong&gt;. No cherry-picking, no synthetic test cases, no marketing fluff. Clone the repo and verify every number.&lt;/p&gt;




&lt;h2&gt;
  
  
  Add It to CI
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/ansede.yml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ansede SAST&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;security-events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;scan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pip install ansede-static&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ansede-static . --strict --format sarif --output results.sarif&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github/codeql-action/upload-sarif@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;sarif_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;results.sarif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Findings appear directly in GitHub's &lt;strong&gt;Security → Code Scanning&lt;/strong&gt; tab.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Your SAST scanner is probably missing 77% of known CVEs. Not because it's a bad tool — because it uses an architecture (pattern matching) that fundamentally can't track data across function boundaries.&lt;/p&gt;

&lt;p&gt;IFDS-based taint analysis isn't new — it's been in academic literature since 1995. What's new is making it fast enough, language-agnostic enough, and zero-dependency enough to run in a CI pipeline alongside your existing tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop shipping vulnerabilities your scanner can't see.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;&lt;a href="https://ansede.onrender.com" rel="noopener noreferrer"&gt;Ansede Static&lt;/a&gt; is MIT-licensed, zero-dependency, and installs with &lt;code&gt;pip install ansede-static&lt;/code&gt;. Compare it against your current SAST tool at &lt;a href="https://ansede.onrender.com/compare" rel="noopener noreferrer"&gt;ansede.onrender.com/compare&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>python</category>
      <category>devops</category>
      <category>sast</category>
    </item>
    <item>
      <title>I Built an Offline SAST Scanner — Try It on Your Code and Tell Me Where It Fails</title>
      <dc:creator>mattybellx</dc:creator>
      <pubDate>Mon, 29 Jun 2026 16:01:56 +0000</pubDate>
      <link>https://dev.to/mattybellx/i-built-an-offline-sast-scanner-try-it-on-your-code-and-tell-me-where-it-fails-2lk8</link>
      <guid>https://dev.to/mattybellx/i-built-an-offline-sast-scanner-try-it-on-your-code-and-tell-me-where-it-fails-2lk8</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/mattybellx/Ansede" rel="noopener noreferrer"&gt;https://github.com/mattybellx/Ansede&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've been working on this on and off for about a year. It started because I was reviewing a Flask app and Bandit gave it a clean bill of health — but it had an IDOR vulnerability where any logged-in user could access anyone else's invoices. Bandit saw the @login_required decorator and moved on. Semgrep OSS did the same thing.&lt;/p&gt;

&lt;p&gt;So I started writing checks for the stuff they miss — not just "is there an auth decorator" but "does this route verify that the current user owns the resource they're accessing." That turned into a whole scanner.&lt;/p&gt;

&lt;p&gt;What it does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finds IDOR (CWE-639), missing auth (CWE-862), ownership bypass (CWE-285) — the access control stuff&lt;/li&gt;
&lt;li&gt;Also the standard injection/XSS/path traversal stuff&lt;/li&gt;
&lt;li&gt;Works on Python, JavaScript/TypeScript, Go, Java, C#, Ruby, PHP&lt;/li&gt;
&lt;li&gt;Fully offline, no dependencies beyond Python itself, no telemetry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Numbers (take with salt, I ran these myself):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;100% recall on a corpus of 164 CVEs I put together (Semgrep OSS got ~23%, CodeQL ~34% on the same set)&lt;/li&gt;
&lt;li&gt;Scanned 33 real GitHub repos — found 1,255 things vs CodeQL's 167 (but I'm the first to admit some of those are probably noise)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where I think it's weak and would love help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The corpus I benchmarked against is only 164 CVEs. I need more real-world test cases&lt;/li&gt;
&lt;li&gt;Java support is structural but doesn't have the deep Spring Security modeling yet&lt;/li&gt;
&lt;li&gt;I'm sure there are false positives I haven't caught — I've been staring at this code too long to see them&lt;/li&gt;
&lt;li&gt;The Go and Ruby analyzers are pretty basic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If anyone wants to try it on their own code and tell me what it gets wrong, I'd genuinely appreciate it. Or if you want to look at the benchmarking methodology and point out flaws, even better.&lt;/p&gt;

&lt;p&gt;pip install ansede-static&lt;/p&gt;

&lt;p&gt;Repo has the full methodology for the CVE recall test and the 3-tool comparison. The comparison scripts are in benchmarks/ if you want to reproduce or critique them.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Reddit r/Python
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; &lt;a href="https://www.reddit.com/r/Python/submit" rel="noopener noreferrer"&gt;https://www.reddit.com/r/Python/submit&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Rules:&lt;/strong&gt; Must be Python-related. Self-promo is okay if you're upfront about it and engage in comments. Don't just drop a link and leave.&lt;br&gt;
&lt;strong&gt;How not to get removed:&lt;/strong&gt; Use the "Discussion" or "Showcase" flair. Write a real post, not just a link. Python community appreciates "I built a tool, here's what I learned."&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Title:&lt;/strong&gt; I built a Python SAST scanner and would love feedback — especially on what it gets wrong&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flair:&lt;/strong&gt; Discussion&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Text:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Been working on a static analysis tool for about a year. It's written in Python (with a Rust core for the JS/TS parser), and I'm looking for people to try it on their code and tell me where it falls down.&lt;/p&gt;

&lt;p&gt;The short version: it's like Bandit or Semgrep but focused on access control vulnerabilities — IDOR, missing authorization, ownership bypass. The kind of stuff where just checking for a decorator isn't enough.&lt;/p&gt;

&lt;p&gt;You can install it with pip:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install ansede-static
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then just point it at your code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ansede-static your_project/ --verbose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It supports Python, JS/TS, Go, Java, C#, Ruby, and PHP, but Python and JS are the most mature.&lt;/p&gt;

&lt;p&gt;What I'm looking for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;False positives on your real code. I've tested it on 33 repos but that's nothing&lt;/li&gt;
&lt;li&gt;Languages or frameworks where it's useless — be honest, I need to know where not to spend time&lt;/li&gt;
&lt;li&gt;The benchmarking methodology: does it hold up? The comparison scripts are all in the repo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try it and it's terrible on your codebase, please tell me. That's more useful than "nice project" comments.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/mattybellx/Ansede" rel="noopener noreferrer"&gt;https://github.com/mattybellx/Ansede&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Reddit r/netsec
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt; &lt;a href="https://www.reddit.com/r/netsec/submit" rel="noopener noreferrer"&gt;https://www.reddit.com/r/netsec/submit&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Rules:&lt;/strong&gt; Technical security content only. No vendor marketing. Self-posts are preferred over direct links. They're picky — low-effort posts get removed.&lt;br&gt;
&lt;strong&gt;How not to get removed:&lt;/strong&gt; Write a technical self-post explaining the methodology. The comparison data is interesting to this crowd. Don't just link the repo.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Title:&lt;/strong&gt; I benchmarked 3 free SAST tools against 164 CVEs — would appreciate a sanity check on my methodology&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Text:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've been building a SAST scanner and wanted to know if it actually works, so I put together a corpus of 164 CVEs across Python, JavaScript, Go, Java, and C# and ran my tool against Semgrep OSS and CodeQL on the same set.&lt;/p&gt;

&lt;p&gt;Results (my tool / Semgrep OSS / CodeQL):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python: 100% / 18.8% / 31.3%&lt;/li&gt;
&lt;li&gt;JavaScript: 100% / 25.0% / 37.5%&lt;/li&gt;
&lt;li&gt;Go: 100% / 22.2% / 33.3%&lt;/li&gt;
&lt;li&gt;Java: 100% / 20.0% / 30.0%&lt;/li&gt;
&lt;li&gt;C#: 100% / 30.0% / 35.0%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before anyone asks: yes, I built the tool being tested. Yes, that's a conflict of interest. The corpus, the comparison scripts, and the full methodology are all in the repo — I'm posting this specifically because I want someone who isn't me to look at the methodology and tell me if it's fair.&lt;/p&gt;

&lt;p&gt;Things I'm worried about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Corpus selection bias: I may have unconsciously picked CVEs my tool handles well&lt;/li&gt;
&lt;li&gt;The CodeQL setup might not be optimal — I used the default query packs&lt;/li&gt;
&lt;li&gt;Sample size: 164 CVEs isn't huge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If anyone wants to audit the methodology or run the comparison themselves, everything is in benchmarks/. The CVE corpus is in benchmarks/fixtures/. I'd genuinely appreciate criticism.&lt;/p&gt;

&lt;p&gt;The tool itself is at &lt;a href="https://github.com/mattybellx/Ansede" rel="noopener noreferrer"&gt;https://github.com/mattybellx/Ansede&lt;/a&gt; if you want context, but the benchmarking methodology is what I'm hoping for feedback on.&lt;/p&gt;

</description>
      <category>security</category>
      <category>python</category>
      <category>secdev</category>
      <category>devsec</category>
    </item>
  </channel>
</rss>
