<?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: Amirthavarshini Marimuthu</title>
    <description>The latest articles on DEV Community by Amirthavarshini Marimuthu (@amir09).</description>
    <link>https://dev.to/amir09</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%2F4169471%2Fb45690e2-f730-4121-88c7-e5d0f806d546.jpg</url>
      <title>DEV Community: Amirthavarshini Marimuthu</title>
      <link>https://dev.to/amir09</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amir09"/>
    <language>en</language>
    <item>
      <title>I Fact-Checked Every Finding an AI Security Reviewer Gave Me. Here's What Held Up.</title>
      <dc:creator>Amirthavarshini Marimuthu</dc:creator>
      <pubDate>Sun, 01 Nov 2026 20:40:57 +0000</pubDate>
      <link>https://dev.to/amir09/i-fact-checked-every-finding-an-ai-security-reviewer-gave-me-heres-what-held-up-e2k</link>
      <guid>https://dev.to/amir09/i-fact-checked-every-finding-an-ai-security-reviewer-gave-me-heres-what-held-up-e2k</guid>
      <description>&lt;p&gt;During my internship at RakFort, one of my tasks was simple to describe and slow to do: &lt;strong&gt;run every security check in &lt;a href="https://github.com/secfoo-com/secfoo" rel="noopener noreferrer"&gt;Secfoo&lt;/a&gt; with the Claude agent, and then check whether the AI was actually right.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not "did the run finish". Not "does the report look good". Is each finding &lt;em&gt;true&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;This post is about what I found, and what I'd tell anyone who is starting to use AI for security reviews.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick background: what Secfoo is
&lt;/h2&gt;

&lt;p&gt;Secfoo is an open-source tool that turns the AI coding agent you already use (Claude Code, Codex, Gemini CLI, Cursor, GitHub Copilot and others) into a security reviewer.&lt;/p&gt;

&lt;p&gt;You point it at your code, pick a check, and it gives the AI clear instructions and a fixed report format. You get back a structured report with findings, severity and recommendations, and everything shows up in a local dashboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;secfoo run &lt;span class="nt"&gt;--skill&lt;/span&gt; deployment-readiness &lt;span class="nt"&gt;--agent&lt;/span&gt; claude &lt;span class="nt"&gt;--target&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
secfoo serve   &lt;span class="c"&gt;# open the dashboard&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It has 9 checks, including SAST, threat modeling, secret scanning, dependency triage, deployment readiness and responsible AI compliance.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I tested
&lt;/h2&gt;

&lt;p&gt;My target was Secfoo's own codebase (a good test, because I could read every file the AI talked about).&lt;/p&gt;

&lt;p&gt;For each report I:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Opened every finding&lt;/li&gt;
&lt;li&gt;Went to the exact file and line it pointed to&lt;/li&gt;
&lt;li&gt;Checked the code &lt;strong&gt;as it was on the day of the scan&lt;/strong&gt; (using the commit from that date, not today's code)&lt;/li&gt;
&lt;li&gt;Marked it &lt;strong&gt;Confirmed&lt;/strong&gt;, &lt;strong&gt;Partly wrong&lt;/strong&gt; or &lt;strong&gt;Wrong&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Checked that the numbers on the dashboard matched the report&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Step 3 matters more than I expected. Code changes every day. If you check an old report against today's code, you'll blame the AI for things that were true at the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Deployment readiness: 6 of 7 fully correct
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;Finding&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;F1&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Local dashboard has no login or CSRF protection&lt;/td&gt;
&lt;td&gt;✅ Confirmed (exact lines were right)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F2&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;No security scanning in CI&lt;/td&gt;
&lt;td&gt;⚠️ Partly wrong&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F3&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Release actions pinned by tag, long-lived tokens&lt;/td&gt;
&lt;td&gt;✅ Confirmed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F4&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Uploads saved to disk before the size check&lt;/td&gt;
&lt;td&gt;✅ Confirmed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F5&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Docker image runs as root, base image not pinned&lt;/td&gt;
&lt;td&gt;✅ Confirmed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F6&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;No health endpoint&lt;/td&gt;
&lt;td&gt;✅ Confirmed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F7&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Dependencies have no upper version pins&lt;/td&gt;
&lt;td&gt;✅ Confirmed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Responsible AI compliance: 4 of 4 correct
&lt;/h3&gt;

&lt;p&gt;All four findings were accurate, and the overall rating ("Low") made sense for a tool that doesn't make decisions about people.&lt;/p&gt;

&lt;h2&gt;
  
  
  The interesting one: F2
&lt;/h2&gt;

&lt;p&gt;Most of F2 was right. CI really didn't run any security scanners, and the linter was set to never fail the build.&lt;/p&gt;

&lt;p&gt;But the report also said the release workflow &lt;strong&gt;"runs on any v* tag push"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It didn't. The workflow had been changed to &lt;strong&gt;manual-only&lt;/strong&gt; five days before the scan. The file even had a comment at the top explaining the change.&lt;/p&gt;

&lt;p&gt;So the AI described how the project &lt;em&gt;used to&lt;/em&gt; work. My guess is that it matched a very common pattern ("release on tag push") instead of reading the current trigger carefully.&lt;/p&gt;

&lt;p&gt;This is exactly the kind of mistake that is easy to miss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It sounds completely reasonable&lt;/li&gt;
&lt;li&gt;It's in a well-formatted report next to six correct findings&lt;/li&gt;
&lt;li&gt;It's only wrong in one detail&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I had just skimmed the report, I would have believed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things I tested besides the reports
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bad input.&lt;/strong&gt; I fed the CLI things a real user might get wrong: a folder that doesn't exist, a file instead of a folder, an unknown skill or agent name, a GitHub repo that doesn't exist. Every one gave a clear error, with no crash and no AI tokens wasted. I found two small issues (a negative &lt;code&gt;--timeout&lt;/code&gt; was accepted, and an empty target quietly scanned the current folder) and reported them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The dashboard.&lt;/strong&gt; All pages loaded and the finding counts matched the reports, except the home page, which crashed with a 500 error. The cause was a recent change: agents that don't report cost now store "unknown" instead of $0, and the home page added the costs together with a plain &lt;code&gt;sum()&lt;/code&gt;, which fails on an empty value. It was a one-line fix, and my PR for it (&lt;a href="https://github.com/secfoo-com/secfoo/pull/31" rel="noopener noreferrer"&gt;#31&lt;/a&gt;) is now merged.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. AI reviewers are genuinely useful.&lt;/strong&gt; Most findings were correct, with the right file and line numbers. For coverage and speed, it's a huge help, especially for a small team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. "Looks professional" is not the same as "true".&lt;/strong&gt; The one wrong detail was written just as confidently as the correct ones. Severity labels and neat tables don't make a finding correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Check against the right version of the code.&lt;/strong&gt; Use the commit from the scan date. Otherwise you'll mark correct findings as wrong (or the other way round).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Keep a human in the loop for anything that matters.&lt;/strong&gt; If a report is going to someone who will sign it off, every finding should be checked first. It took me a while, but it's much faster than reviewing the code from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Secfoo is free and open source (MIT). If you're a student or developer interested in security, try it on your own project and check the findings yourself. That's honestly the best way to learn what AI reviewers are good and bad at.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/secfoo-com/secfoo" rel="noopener noreferrer"&gt;https://github.com/secfoo-com/secfoo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback, issues and contributions are welcome. I'd love to hear how it does on your code!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is my second post about Secfoo. The first one was about &lt;a href="https://dev.to/amir09/secfoo-i-caught-our-security-scanner-inventing-fake-vulnerabilities-heres-the-proof-1hak"&gt;catching an AI scanner inventing fake vulnerabilities&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  security #ai #opensource #testing
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>opensource</category>
      <category>security</category>
    </item>
    <item>
      <title>SecFoo — I Caught Our Security Scanner Inventing Fake Vulnerabilities — Here's the Proof!</title>
      <dc:creator>Amirthavarshini Marimuthu</dc:creator>
      <pubDate>Wed, 07 Oct 2026 16:31:51 +0000</pubDate>
      <link>https://dev.to/amir09/secfoo-i-caught-our-security-scanner-inventing-fake-vulnerabilities-heres-the-proof-1hak</link>
      <guid>https://dev.to/amir09/secfoo-i-caught-our-security-scanner-inventing-fake-vulnerabilities-heres-the-proof-1hak</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;What is Secfoo?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/secfoo-com/secfoo" rel="noopener noreferrer"&gt;Secfoo&lt;/a&gt; is an open-source CLI that turns an AI coding agent into a disciplined security reviewer. Instead of building its own scanner, it hands your codebase and a specific review checklist to an AI agent you already have like Claude Code, Cursor, Gemini CLI, Codex, and few others - lets it actually read the code the way a human security reviewer would.&lt;/p&gt;

&lt;p&gt;You pick a target (a local folder or a GitHub repo), pick one or more checks to run, and Secfoo does the rest: renders the right prompt, runs the agent, and stores the results in a local dashboard you can browse in your browser. It can run 8 different kinds of review — architecture, threat modeling, SAST, SCA, secret scanning, prompt review, deployment readiness, and responsible AI compliance.&lt;/p&gt;

&lt;p&gt;Part of my internship on Secfoo was real simple: install it, use it like a real user would, and see if it actually does what it claims.&lt;/p&gt;

&lt;p&gt;One of its agent options broke that promise on the very first real test I ran. Here's exactly how I proved it, because "the AI made something up" is a big claim, and I wanted receipts, not a hunch.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The setup&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Secfoo has a "no coding-agent CLI needed" option — give it an API key, and it talks straight to a model instead of needing Claude Code or Cursor installed. I pointed it at a small folder in Secfoo's own codebase and asked for a SAST (static code analysis) scan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;secfoo run &lt;span class="nt"&gt;--skill&lt;/span&gt; sast &lt;span class="nt"&gt;--target&lt;/span&gt; src/secfoo/report &lt;span class="nt"&gt;--agent&lt;/span&gt; secfoo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It came back &lt;strong&gt;successful&lt;/strong&gt;, with 3 findings — 1 High, 1 High, 1 Medium. Confident-looking report, proper CWE IDs, CVSS vectors, even illustrative fix diffs.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The first red flag&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Secfoo saves the &lt;em&gt;exact prompt&lt;/em&gt; it sends to the model, alongside the report. So before trusting the output, I checked what the AI had actually been shown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"def &lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;class &lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;import "&lt;/span&gt; prompt.md
&lt;span class="c"&gt;# 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero. Out of 161 lines. The entire prompt was instructions and a single line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## **Target**
Inspect the codebase at: `/path/to/src/secfoo/report`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No file contents. Nothing. The model was told to review code it was never actually shown.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The proof it made things up&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The report cited three "High/Medium" vulnerabilities, each with a specific file path:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;db/query_handler.py:15&lt;/code&gt; — SQL injection&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;template/render.py:45&lt;/code&gt; — XSS&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;file_upload/upload.py:30&lt;/code&gt; — path traversal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of those files exist. Anywhere in the project. I checked with &lt;code&gt;find&lt;/code&gt;. The folder I scanned only has 7 files, and not one of them is named any of those. The AI had nothing real to look at, so it generated the textbook example anyone would expect from "write me a SAST report" with zero actual input — and reported it with full confidence, including the line &lt;em&gt;"Confidence in this assessment is moderate to high."&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ruling out "maybe the AI is just unreliable"
&lt;/h2&gt;

&lt;p&gt;Before calling this a tool bug rather than a model limitation, I ran the &lt;strong&gt;exact same skill, on the exact same folder&lt;/strong&gt;, through a different built-in option in Secfoo — one that actually reads files first. That one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Correctly named all 7 real files in the folder&lt;/li&gt;
&lt;li&gt;Cited a real, specific line of code accurately — down to the exact syntax&lt;/li&gt;
&lt;li&gt;Found 0 issues and said so honestly, instead of padding the report to look thorough&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same tool, same folder, same day. One option told the truth. The other one guessed and called it confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why this matters more than a normal bug&lt;/strong&gt;??
&lt;/h2&gt;

&lt;p&gt;A security tool's entire value is that you can trust what it tells you. A tool that invents vulnerabilities is worse than one that finds nothing — it burns your time chasing ghosts, or worse, gives you false confidence that a real issue doesn't exist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The good news&lt;/strong&gt;: this is now fixed — the team removed the broken implementation. But it's a good reminder for anyone building on top of an LLM: "the run succeeded and returned a well-formatted answer" is not the same claim as "the answer is true." If your pipeline can check its own inputs the way I did here — just read the prompt you're about to log — do it. It's a five-second check that would have caught this before it ever shipped.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
