<?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: Brenn Hill</title>
    <description>The latest articles on DEV Community by Brenn Hill (@brennhill).</description>
    <link>https://dev.to/brennhill</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3856905%2F15b3b99d-a66c-43bf-b3c6-1af943635cf1.jpeg</url>
      <title>DEV Community: Brenn Hill</title>
      <link>https://dev.to/brennhill</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brennhill"/>
    <language>en</language>
    <item>
      <title>How a sandwich defeats North Korea's hackers (and the US couldn't for 70 years)</title>
      <dc:creator>Brenn Hill</dc:creator>
      <pubDate>Thu, 02 Apr 2026 06:11:21 +0000</pubDate>
      <link>https://dev.to/brennhill/how-a-sandwich-defeats-north-koreas-hackers-and-the-us-couldnt-for-70-years-5bg4</link>
      <guid>https://dev.to/brennhill/how-a-sandwich-defeats-north-koreas-hackers-and-the-us-couldnt-for-70-years-5bg4</guid>
      <description>&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.amazonaws.com%2Fuploads%2Farticles%2F49il8f4gk9ojd3hsa4nv.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.amazonaws.com%2Fuploads%2Farticles%2F49il8f4gk9ojd3hsa4nv.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
Two days ago, Google's Mandiant team &lt;a href="https://thehackernews.com/2026/03/axios-supply-chain-attack-pushes-cross.html" rel="noopener noreferrer"&gt;attributed the axios npm compromise&lt;/a&gt; to UNC1069 — a North Korean threat group previously linked to cryptocurrency theft and attacks on DeFi platforms. The malicious code shares significant overlap with WAVESHAPER, a C++ backdoor Mandiant attributed to the same group in February.&lt;/p&gt;

&lt;p&gt;North Korea just weaponized the most popular HTTP client in JavaScript. 100 million weekly downloads. The payload: a cross-platform RAT that harvests credentials, SSH keys, and cloud tokens from every developer machine that runs &lt;code&gt;npm install&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The United States has spent 70 years and trillions of dollars trying to contain North Korea. Nuclear negotiations, sanctions, carrier groups, diplomatic pressure, UN resolutions. None of it has stopped the DPRK from becoming one of the most effective cyber threats on the planet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A sloppy joe sandwich stops them in 3 seconds.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What happened
&lt;/h2&gt;

&lt;p&gt;On March 30, the attacker compromised the npm account of axios's lead maintainer (&lt;code&gt;jasonsaayman&lt;/code&gt;) using a stolen access token. They changed the account email to a Proton Mail address and published two malicious versions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="mailto:axios@1.14.1"&gt;axios@1.14.1&lt;/a&gt;&lt;/strong&gt; — published March 31, 00:21 UTC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="mailto:axios@0.30.4"&gt;axios@0.30.4&lt;/a&gt;&lt;/strong&gt; — published March 31, 01:00 UTC&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both versions injected a new dependency: &lt;code&gt;plain-crypto-js@4.2.1&lt;/code&gt;. This package was never imported anywhere in the axios source. Its sole purpose was to run a &lt;code&gt;postinstall&lt;/code&gt; hook that deployed platform-specific RATs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;macOS&lt;/strong&gt;: Binary at &lt;code&gt;/Library/Caches/com.apple.act.mond&lt;/code&gt;, executed via AppleScript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows&lt;/strong&gt;: PowerShell RAT with Registry persistence and in-memory binary injection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux&lt;/strong&gt;: Python RAT script via &lt;code&gt;nohup&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dropper script deleted itself after execution to hide forensic evidence. The attacker staged &lt;code&gt;plain-crypto-js&lt;/code&gt; 18 hours in advance, pre-built three platform payloads, and hit both release branches within 39 minutes. This was not amateur hour.&lt;/p&gt;
&lt;h2&gt;
  
  
  How sloppy-joe blocks every layer of this attack
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/brennhill/sloppy-joe" rel="noopener noreferrer"&gt;sloppy-joe&lt;/a&gt; is an open-source supply chain security tool. It runs &lt;strong&gt;before&lt;/strong&gt; &lt;code&gt;npm install&lt;/code&gt;. It reads your &lt;code&gt;package-lock.json&lt;/code&gt; and checks every dependency — direct and transitive — against multiple independent signals. No packages are downloaded. No code is executed.&lt;/p&gt;
&lt;h3&gt;
  
  
  Signal 1: Version age gate
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR axios [metadata/version-age]
      Version '1.14.1' of 'axios' was published 0 hours ago (minimum: 72 hours).
      New versions need time for the community and security scanners to review them.
 Fix: Wait until the version is at least 72 hours old, or pin to an older version.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The compromised versions were live for 2-3 hours before npm yanked them. A 72-hour gate means they never get installed. Period. This requires zero knowledge of the attack — it works purely on the principle that new versions should survive community review before hitting production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This single check stops the attack.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But sloppy-joe doesn't stop at one signal. With &lt;code&gt;--deep&lt;/code&gt; transitive scanning, &lt;code&gt;plain-crypto-js&lt;/code&gt; gets demolished by five independent checks:&lt;/p&gt;
&lt;h3&gt;
  
  
  Signal 2: New package detection
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR plain-crypto-js [metadata/new-package]
      'plain-crypto-js' was first published 0 days ago. New packages are higher
      risk — verify this is a legitimate, maintained project before depending on it.
 Fix: Verify 'plain-crypto-js' at its registry page and source repository.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;plain-crypto-js&lt;/code&gt; was created the day before the attack. Brand new packages as transitive dependencies of 100M-download packages are inherently suspicious.&lt;/p&gt;
&lt;h3&gt;
  
  
  Signal 3: Install script risk amplifier
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR plain-crypto-js [metadata/install-script-risk]
      'plain-crypto-js' has install scripts AND was published 0 days ago and with
      0 downloads. Install scripts on new, low-download packages are the #1
      malware delivery vector.
 Fix: Do not install this package. Verify it is legitimate before proceeding.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Install scripts + new package + zero downloads. This is the exact fingerprint of a supply chain attack. sloppy-joe's install script risk signal combines multiple weak signals into a high-confidence detection. Every real-world npm supply chain attack in the last 5 years has matched this pattern.&lt;/p&gt;
&lt;h3&gt;
  
  
  Signal 4: No source repository
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WARNING plain-crypto-js [metadata/no-repository]
        'plain-crypto-js' has no source repository URL and is a new package
        (&amp;lt; 30 days old). Legitimate packages almost always link to their source code.
 Fix: Verify 'plain-crypto-js' at its registry page.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Legitimate packages link to their GitHub/GitLab repo. Malicious packages created as payload delivery vehicles don't bother.&lt;/p&gt;
&lt;h3&gt;
  
  
  Signal 5: Name similarity
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WARNING plain-crypto-js [similarity/mutation-match]
        'plain-crypto-js' is suspiciously similar to existing package 'crypto-js'
 Fix: Verify this is the package you intend to use.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;plain-crypto-js&lt;/code&gt; is a clear attempt to look like &lt;code&gt;crypto-js&lt;/code&gt; — a real, popular cryptography package with hundreds of millions of downloads. sloppy-joe's mutation generators catch this.&lt;/p&gt;
&lt;h2&gt;
  
  
  Five signals. One sandwich. Zero dollars.
&lt;/h2&gt;

&lt;p&gt;Here's what's remarkable: none of these detections require threat intelligence feeds, malware signature databases, or AI-powered behavioral analysis. They're all variations of the same primitive: &lt;strong&gt;cross-reference what the code claims to use against what actually exists on the registry.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the version too new? Flag it.&lt;/li&gt;
&lt;li&gt;Is the transitive dep brand new? Flag it.&lt;/li&gt;
&lt;li&gt;Does a brand new package have install scripts? Block it.&lt;/li&gt;
&lt;li&gt;Does it have no source repository? Flag it.&lt;/li&gt;
&lt;li&gt;Does the name look like a popular package? Flag it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each signal alone is informational. All five firing together on the same package is a certainty.&lt;/p&gt;
&lt;h2&gt;
  
  
  The cost of this defense
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add to any CI pipeline&lt;/span&gt;
npx sloppy-joe check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's it. One line. Runs in 5-15 seconds. No account needed. No API key. No subscription. Open source, MIT licensed.&lt;/p&gt;

&lt;p&gt;The DPRK's UNC1069 spent 18 hours staging payloads, pre-building RATs for three platforms, and compromising a maintainer account. sloppy-joe catches it in the time it takes to read a &lt;code&gt;package-lock.json&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  What sloppy-joe can't catch
&lt;/h2&gt;

&lt;p&gt;Honesty matters: sloppy-joe would &lt;strong&gt;not&lt;/strong&gt; have detected the credential theft itself. The attacker hijacked the real maintainer's account — the npm &lt;code&gt;_npmUser&lt;/code&gt; field still shows &lt;code&gt;jasonsaayman&lt;/code&gt;. There's no publisher change to detect. npm's &lt;a href="https://docs.npmjs.com/generating-provenance-statements" rel="noopener noreferrer"&gt;provenance attestation&lt;/a&gt; (OIDC-based publishing via GitHub Actions) is the real defense against token theft — the malicious versions were published manually, bypassing axios's CI pipeline.&lt;/p&gt;

&lt;p&gt;sloppy-joe catches the &lt;strong&gt;payload&lt;/strong&gt;, not the &lt;strong&gt;compromise&lt;/strong&gt;. But the payload is what hurts you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install&lt;/span&gt;
cargo &lt;span class="nb"&gt;install &lt;/span&gt;sloppy-joe

&lt;span class="c"&gt;# Run&lt;/span&gt;
sloppy-joe check

&lt;span class="c"&gt;# In CI (GitHub Actions)&lt;/span&gt;
- uses: brennhill/sloppy-joe-action@v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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/brennhill" rel="noopener noreferrer"&gt;
        brennhill
      &lt;/a&gt; / &lt;a href="https://github.com/brennhill/sloppy-joe" rel="noopener noreferrer"&gt;
        sloppy-joe
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Shields against supply-chain, slopsquatting, and typosquatting attacks from dependencies and code.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&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%2Fraw.githubusercontent.com%2Fbrennhill%2Fsloppy-joe%2Fmain%2Fassets%2Fsloppy-joe.svg%3Fv%3D3" 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%2Fraw.githubusercontent.com%2Fbrennhill%2Fsloppy-joe%2Fmain%2Fassets%2Fsloppy-joe.svg%3Fv%3D3" alt="sloppy-joe" width="400"&gt;&lt;/a&gt;
  
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Catch hallucinated, typosquatted, and non-canonical dependencies&lt;br&gt;before they reach production.&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;code&gt;cargo install sloppy-joe&lt;/code&gt;
&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The &lt;a href="https://thehackernews.com/2026/03/teampcp-backdoors-litellm-versions.html" rel="nofollow noopener noreferrer"&gt;LiteLLM supply chain attack&lt;/a&gt; (March 2026) compromised a package with 97M monthly downloads. Attackers stole publishing credentials, pushed malicious versions that harvested SSH keys, cloud credentials, and K8s secrets. sloppy-joe's default 72-hour version age gate would have blocked both poisoned versions — they were discovered within hours, well before the gate would have opened. If you run &lt;code&gt;sloppy-joe check&lt;/code&gt; in CI, this attack fails.&lt;/strong&gt; &lt;a href="https://github.com/brennhill/sloppy-joe/docs/blog/2026-03-24-litellm-attack-blocked.md" rel="noopener noreferrer"&gt;Full analysis&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI code generators hallucinate package names &lt;a href="https://arxiv.org/abs/2406.10279" rel="nofollow noopener noreferrer"&gt;~20% of the time&lt;/a&gt;. Attackers register those names and wait. sloppy-joe catches them in CI before &lt;code&gt;npm install&lt;/code&gt; or &lt;code&gt;pip install&lt;/code&gt; runs.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How to Use&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Install (single static binary, no runtime dependencies)&lt;/span&gt;
cargo install sloppy-joe
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Or download an auditable binary archive from GitHub Releases&lt;/span&gt;
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; https://github.com/brennhill/sloppy-joe/releases&lt;/span&gt;

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Check current project — auto-detects ecosystem from manifest files&lt;/span&gt;
sloppy-joe check

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Check a&lt;/span&gt;&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/brennhill/sloppy-joe" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;






&lt;p&gt;&lt;em&gt;sloppy-joe is an open-source supply chain security tool that catches hallucinated, typosquatted, and compromised dependencies before they reach production. It runs before your package manager, requires no code execution, and blocks attacks like axios, LiteLLM, event-stream, and ua-parser-js.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>npm</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
