<?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: Anand Prakash Srivastava</title>
    <description>The latest articles on DEV Community by Anand Prakash Srivastava (@anand240).</description>
    <link>https://dev.to/anand240</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%2F4159276%2F8c746f8a-f269-4844-96e5-cee01e40a855.jpg</url>
      <title>DEV Community: Anand Prakash Srivastava</title>
      <link>https://dev.to/anand240</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anand240"/>
    <language>en</language>
    <item>
      <title>SniffDog: I built my job-hunting friend a sniffer dog that sniffs out malware in fake recruiter repos</title>
      <dc:creator>Anand Prakash Srivastava</dc:creator>
      <pubDate>Sun, 04 Oct 2026 22:25:22 +0000</pubDate>
      <link>https://dev.to/anand240/sniffdog-i-built-my-job-hunting-friend-a-sniffer-dog-that-sniffs-out-malware-in-fake-recruiter-355m</link>
      <guid>https://dev.to/anand240/sniffdog-i-built-my-job-hunting-friend-a-sniffer-dog-that-sniffs-out-malware-in-fake-recruiter-355m</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;SniffDog checks a take-home coding assignment before you run it.&lt;/strong&gt; It reads the repo, never executes it, and tells you in plain English whether it's safe to open.&lt;/p&gt;

&lt;p&gt;I built it for my friend Mayank Raj. Earlier this year, Mayank, a final-year student hunting for his first developer job, got a LinkedIn message from a "recruiter" offering a remote junior developer role. The recruiter sent a GitHub repo and asked him to open it in VS Code and review the code. On the next call, he was asked to run the project live, so he ran &lt;code&gt;npm install&lt;/code&gt; and &lt;code&gt;npm run dev&lt;/code&gt; without reading it. Everything worked, and the call went well.&lt;/p&gt;

&lt;p&gt;A few days later, he got a "new login" alert on his email and found an unknown session on his GitHub account. Malware had copied his saved browser passwords. He spent the weekend changing passwords, revoking tokens and wiping his laptop. The recruiter's profile was gone.&lt;/p&gt;

&lt;p&gt;SniffDog is what I wish he'd had before he opened that folder.&lt;/p&gt;

&lt;p&gt;What happened to Mayank wasn't bad luck. Microsoft has tracked the &lt;a href="https://microsoft.com/en-us/security/blog/2026/03/11/contagious-interview-malware-delivered-through-fake-developer-job-interviews" rel="noopener noreferrer"&gt;Contagious Interview campaign&lt;/a&gt; since at least December 2022: fake recruiters send coding exercises that run malware through dependency installs and repository tasks. In 2026, &lt;a href="https://www.elastic.co/security-labs/contagious-interview-malware-svg-steganography" rel="noopener noreferrer"&gt;Elastic Security Labs&lt;/a&gt; found the same trick aimed at their own community Slack, with the payload hidden inside SVG images and obfuscated JavaScript. One developer &lt;a href="https://theregister.com/2025/10/20/ai_prompt_saved_developer" rel="noopener noreferrer"&gt;told The Register&lt;/a&gt; he was "30 seconds away" from running one.&lt;/p&gt;

&lt;p&gt;The trap fires the moment you run &lt;code&gt;npm install&lt;/code&gt;, open the folder in VS Code, or start the dev server. A normal AI coding agent asked to "get this running" would do exactly that. SniffDog does the opposite: it looks first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sniffdog https://github.com/recruiter/assignment &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--company&lt;/span&gt; &lt;span class="s2"&gt;"Acme Labs"&lt;/span&gt; &lt;span class="nt"&gt;--recruiter&lt;/span&gt; &lt;span class="s2"&gt;"Jane Doe"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You get a verdict (🟢 SAFE, 🟡 CAUTION or 🔴 DANGER) with every red flag tied to a &lt;code&gt;file:line&lt;/code&gt;, what it would do if you ran it, and what to do next.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/1zoa5F4wANQ" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Narration generated with ElevenLabs. The terminal output in the video is real SniffDog output on the repo's harmless demo assignment.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The repo ships a harmless demo assignment that copies the shape of real attacks: an install script that reaches the internet, a VS Code task that runs on folder open, JavaScript hidden inside a font file, and an obfuscated base64 payload. Every payload only prints "hello". Here is SniffDog reading it (trimmed):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🔴 DANGER
Static checks found 13 suspicious signal(s) in this repository.

Code snippets:
  - lib/config.js:7 (encoded-code) — unwrapped from base64:
    console.log('hello'); /* … */
    Gemma: The code prints 'hello' to the console.
  - package.json:6 (package-script):
    node scripts/setup.js &amp;amp;&amp;amp; curl -s https://example.com &amp;gt; /dev/null
    Gemma: The code first executes the `setup.js` script
           using `node`, then fetches data from a URL
           and discards it.
  - public/fonts/inter.woff:1 (disguised-asset):
    console.log('hello from a harmless imitation font');
    Gemma: The code prints the text 'hello from a
           harmless imitation font' to the console.

memory: on
  - resembles known technique: alternate npm registry
  - resembles known technique: disguised font
  - …
tracing: on
Explainer: Gemma (local) read 3 snippets
Static checks only — nothing from the repo was executed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A clean assignment comes back safe, and the recruiter web check adds context without changing the verdict:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxkdtbwp4jcd1biw1auav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxkdtbwp4jcd1biw1auav.png" alt="SniffDog SAFE verdict with the recruiter web check" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Anand-240" rel="noopener noreferrer"&gt;
        Anand-240
      &lt;/a&gt; / &lt;a href="https://github.com/Anand-240/sniffdog" rel="noopener noreferrer"&gt;
        sniffdog
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;SniffDog&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Review coding assignment repositories before you run them.&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Anand-240/sniffdog/docs/images/sniffdog-cover.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FAnand-240%2Fsniffdog%2FHEAD%2Fdocs%2Fimages%2Fsniffdog-cover.png" alt="SniffDog"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Anand-240/sniffdog/actions/workflows/sniffdog.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/Anand-240/sniffdog/actions/workflows/sniffdog.yml/badge.svg" alt="SniffDog workflow"&gt;&lt;/a&gt; &lt;a href="https://github.com/Anand-240/sniffdog/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="MIT license"&gt;&lt;/a&gt; &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/64e4e70182a719335ba59d3ba0cf9c009a241550e3ead7d5e2b76a13e6d3b731/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31322532422d626c75652e737667"&gt;&lt;img src="https://camo.githubusercontent.com/64e4e70182a719335ba59d3ba0cf9c009a241550e3ead7d5e2b76a13e6d3b731/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31322532422d626c75652e737667" alt="Python 3.12+"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Demo video: &lt;a href="https://youtu.be/1zoa5F4wANQ" rel="nofollow noopener noreferrer"&gt;Watch SniffDog&lt;/a&gt; | DEV post: [DEV_POST_URL]&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why this exists&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Fake recruiters send take-home repositories that hide malware. &lt;a href="https://www.microsoft.com/en-us/security/blog/2026/03/11/contagious-interview-malware-delivered-through-fake-developer-job-interviews/" rel="nofollow noopener noreferrer"&gt;Microsoft&lt;/a&gt; and &lt;a href="https://www.elastic.co/security-labs/contagious-interview-malware-svg-steganography" rel="nofollow noopener noreferrer"&gt;Elastic Security Labs&lt;/a&gt; have documented this Contagious Interview tactic. A trap may start during &lt;code&gt;npm install&lt;/code&gt;, when a folder opens in VS Code, or when the developer starts the app. SniffDog reads the repository before those steps and does not run its code. It was built for a friend who got hit by one of these fake assignments.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it looks like&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Anand-240/sniffdog/docs/images/sniffdog-danger.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FAnand-240%2Fsniffdog%2FHEAD%2Fdocs%2Fimages%2Fsniffdog-danger.png" alt="Danger report for the suspicious demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The harmless suspicious demo triggers 13 findings, with file locations, rule explanations, and selected code snippets.&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/Anand-240/sniffdog/docs/images/sniffdog-safe.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FAnand-240%2Fsniffdog%2FHEAD%2Fdocs%2Fimages%2Fsniffdog-safe.png" alt="Safe report for the safe demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The safe demo has zero findings; public recruiter search results appear separately from its verdict.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick start&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Install Python 3.12 or newer and &lt;a href="https://ollama.com/download" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt; on macOS or Linux. Start Ollama, then run:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;ollama pull gemma3:1b
ollama pull nomic-embed-text
git clone https://github.com/Anand-240/sniffdog.git
&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Anand-240/sniffdog" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Python 3.12+, standard library only for the core. MongoDB and Sentry are optional extras that switch off cleanly when not configured.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;SniffDog is a Python CLI built around one rule: &lt;strong&gt;deterministic checks decide how dangerous a repo is; Gemma only reads the code and explains it.&lt;/strong&gt; The model can never lower the verdict.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;repo URL or folder
  → safe clone (no hooks, no symlinks, https only, depth 1)
  → 5 static scanners: scripts · VS Code · obfuscation · assets · deps
  → base64 payloads decoded as data (never run), max 4 KB
  → Gemma 3 (1B, local via Ollama) reads up to 5 snippets
  → MongoDB Atlas: known-technique vector search + history
  → GitHub API + SerpApi: repo age and recruiter context
  → verdict 🟢/🟡/🔴 + next steps
  (every step traced in Sentry, metadata only)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What it catches
&lt;/h3&gt;

&lt;p&gt;The scanners look for the tricks used in real assignment attacks: &lt;code&gt;postinstall&lt;/code&gt; scripts that call &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;.vscode/tasks.json&lt;/code&gt; with &lt;code&gt;runOn: folderOpen&lt;/code&gt;, &lt;code&gt;.woff&lt;/code&gt; and &lt;code&gt;.png&lt;/code&gt; files that are really JavaScript, code pushed 200 spaces off-screen, &lt;code&gt;_0x&lt;/code&gt; obfuscator names, raw-IP URLs, a custom &lt;code&gt;.npmrc&lt;/code&gt; registry, and typosquats like &lt;code&gt;expres&lt;/code&gt;. Each rule has a hand-written, plain-English consequence ("When you run npm install, packages come from an unknown server…").&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging Gemma: from "summarize everything" to "read this code"
&lt;/h3&gt;

&lt;p&gt;My first design asked Gemma to write the whole explanation. It went badly in three useful ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It claimed the user's system was "likely compromised", which a static scan can't know. I added a validator that rejects claims of completed harm.&lt;/li&gt;
&lt;li&gt;Next it just copied the rule messages back, so it added nothing.&lt;/li&gt;
&lt;li&gt;When I gave it only rule names, even &lt;code&gt;gemma3:4b&lt;/code&gt; explained hidden code as "may cause rendering issues with extra whitespace". The model wasn't the problem. It had no code to read.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I changed its job. SniffDog now unwraps the hidden payload itself, statically, and hands Gemma the real snippet. Asked "what would this code do if it ran?", the 1B model is accurate. Every URL it mentions must appear in the snippet, or the sentence is dropped.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging with Sentry
&lt;/h3&gt;

&lt;p&gt;Sentry tracing showed a full scan takes 5.16 s, and the local Gemma call is 3.59 s of it (~70%). That's why Gemma reads at most 5 snippets with a 30 s timeout. The trace also showed the Atlas memory lookup taking 1.52 s, mostly the network round trip, while every local scanner finished in about 1 ms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9stbku3ei1to4f6he057.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9stbku3ei1to4f6he057.png" alt="Sentry trace: the local Gemma call takes 3.59 s of a 5.16 s scan" width="799" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two bugs surfaced along the way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No traces arrived.&lt;/strong&gt; The CLI exited before the SDK sent anything. Fix: flush before exit, including on errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Too much data.&lt;/strong&gt; Sentry's debug log showed it auto-enabling its PyMongo and logging integrations, which can record query contents. I turned default integrations off. Traces now carry span names, timings and counts only, and a test proves no code, prompts or finding text leave the machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other lessons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A real company isn't a scam.&lt;/strong&gt; My first recruiter check flagged "Microsoft" as CAUTION, because the web is full of "Microsoft scam" warnings about impersonators. Now web results only add context ("Scammers have impersonated Microsoft before; verify on the official careers site") and can never change the verdict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No hiding spots.&lt;/strong&gt; My coding agent once made the scanner skip a &lt;code&gt;.kilo&lt;/code&gt; folder because its own worktree lived there. That's a hole: an attacker could hide a payload in any folder SniffDog ignores. I reverted it. Skipping now needs an explicit &lt;code&gt;--exclude&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Repo&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;th&gt;Findings&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Harmless demo assignment&lt;/td&gt;
&lt;td&gt;🔴 DANGER&lt;/td&gt;
&lt;td&gt;13 of 13 planted tricks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safe demo assignment&lt;/td&gt;
&lt;td&gt;🟢 SAFE&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MDN todo-react&lt;/td&gt;
&lt;td&gt;🟢 SAFE&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MDN Express Local Library&lt;/td&gt;
&lt;td&gt;🟢 SAFE&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;expressjs/generator&lt;/td&gt;
&lt;td&gt;🟡 CAUTION&lt;/td&gt;
&lt;td&gt;2 (&lt;code&gt;child_process&lt;/code&gt; in test files)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I kept the Express Generator result on purpose. Many assignments say "run &lt;code&gt;npm test&lt;/code&gt;", so code in test files that starts processes deserves a look. SniffDog has 17 unit tests, and a GitHub Actions workflow runs them plus a SniffDog scan on every PR that touches package files:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0moarbhpg8qvqrhtqjsx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0moarbhpg8qvqrhtqjsx.png" alt="GitHub Actions: SniffDog scan passed in 6 s" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Limitations
&lt;/h3&gt;

&lt;p&gt;SniffDog is a first look, not an antivirus. It reads files and matches known patterns, so a new trick can slip past it, and a SAFE verdict is never a guarantee. Package scanners like Socket and Datadog's GuardDog go deeper on npm packages; SniffDog focuses on the whole assignment repo (VS Code tasks, disguised assets, recruiter context) and explains it for someone who has never heard of a postinstall script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For this tool, a closed cloud model isn't just worse. In the safest setup it can't run at all.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It works where you should test untrusted code.&lt;/strong&gt; Microsoft's own advice is to do take-home assignments in an isolated, non-persistent VM. The safest version of that VM has no network. A cloud API can't answer there; Gemma on Ollama can. I tested it with Wi-Fi off: same scan, same verdict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's free for the people who need it.&lt;/strong&gt; Mayank is still job hunting. He shouldn't need a paid AI subscription to check whether a recruiter is trying to rob him again. SniffDog runs on my 8 GB MacBook Air with &lt;code&gt;gemma3:1b&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A security tool should be inspectable.&lt;/strong&gt; Open model, open code, deterministic rules: anyone can read exactly why SniffDog called something dangerous, and change it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could change the model's job, not just its prompt.&lt;/strong&gt; When Gemma struggled, I could swap sizes in seconds (&lt;code&gt;gemma3:4b&lt;/code&gt; ran, but froze my laptop and took two minutes), read its raw output, and redesign its role around what a small model does well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One honest trade-off: the optional GitHub, SerpApi, Atlas and Sentry checks need the network. Everything that touches the code itself works offline.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;I built SniffDog with a coding agent, phase by phase, reviewing every commit and pushing back when it took shortcuts (like the &lt;code&gt;.kilo&lt;/code&gt; skip above).&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; &lt;code&gt;gemma3:1b&lt;/code&gt; runs locally via Ollama and reads the hidden code SniffDog unwraps, so the explanation works on an offline, isolated machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of MongoDB Atlas:&lt;/strong&gt; Atlas Vector Search matches suspicious snippets against known attack techniques (local &lt;code&gt;nomic-embed-text&lt;/code&gt; embeddings), and Atlas stores scan history so a repeat scan shows "Scanned before on …". No source code is stored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Sentry Agent Tracing:&lt;/strong&gt; every scan is a transaction with spans per scanner, memory and the Gemma call. Tracing found the CLI exit bug and showed ~70% of scan time is the local model. Metadata only, default integrations off.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of SerpApi:&lt;/strong&gt; live web search checks the recruiter and company for impersonation reports, as context that never changes the code verdict.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of GitHub Copilot:&lt;/strong&gt; a GitHub Actions workflow runs the tests and a SniffDog scan on every PR that touches package files, failing the check on DANGER.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs:&lt;/strong&gt; the demo video's narration was generated with ElevenLabs.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
      <category>security</category>
    </item>
  </channel>
</rss>
