The software supply chain threat model just shifted under our feet — and most security programs haven't recalibrated. AI coding assistants (Copilot-class tools, LLM-driven scaffolding, agentic coding workflows) are now generating functional code at a pace no human review board can match. The problem isn't just speed: these tools routinely introduce dependencies that were never vetted, and in some cases dependencies that don't exist at all. As ActiveState recently highlighted, the ingestion of open source packages is happening upstream of every control most organizations have — code review, SCA scans in CI, even pre-merge checks — because the package enters the developer's environment the moment the AI suggests it and the developer hits accept.
Attackers have figured this out. The phenomenon known as slopsquatting — registering malicious packages under names that LLMs are statistically likely to hallucinate — converts an AI's confidence into an adversary's delivery mechanism. A hallucinated package name that appears plausible (requests-auth-helper, colorama-utils) gets registered on PyPI or npm with a credential stealer in its install hooks, and the next developer whose assistant suggests it becomes patient zero.
This post breaks down the actual risk mechanics, what you can realistically detect, and how to build governance at the point of selection — before the package ever reaches your pipeline.
Technical Analysis
What's actually happening
There are three distinct failure modes defenders need to separate, because they demand different controls:
-
Hallucinated dependencies (slopsquatting surface). LLMs generate import statements and install commands for packages that sound real but don't exist. Research over the past two years has consistently shown that a meaningful percentage of model-suggested package names are non-existent — and those names repeat deterministically across prompts, which means attackers can enumerate them, register them, and wait. This is no longer theoretical; security researchers have demonstrated malicious slopsquatting packages receiving thousands of downloads.
-
Unvetted but real dependencies. The model suggests a legitimate package that your organization has never assessed: no maintainer reputation check, no provenance verification, no license review, no look at its transitive dependency tree. Traditional AppSec review cycles (weekly scans, quarterly audits) simply don't operate at the cadence AI-assisted development produces. A developer can pull in 15 new transitive dependencies in a single afternoon.
-
Version and provenance drift. AI tools frequently suggest outdated package versions with known vulnerabilities, or suggest installing via direct URL/git references that bypass your internal registry proxy entirely — defeating whatever registry-level controls you do have in place.
Why existing controls miss it
Most SCA tooling operates at build time or commit time. By then, the package is already on the developer's workstation — which means install hooks (setup.py, preinstall/postinstall scripts in npm) have already executed in an environment that typically holds cloud credentials, SSH keys, source code, and VPN access. The developer laptop is the softest target with the richest secrets, and AI-assisted ingestion puts malicious code there before any scanner sees the manifest.
Exploitation status
No single CVE defines this threat — it's a technique class, not a bug. What is confirmed: slopsquatting packages have been observed in the wild on PyPI and npm, typosquatting and dependency-confusion campaigns against open source registries are continuous and well-documented by CISA and registry security teams, and the volume of AI-assisted code generation in enterprise environments has grown dramatically through 2025 into 2026. Treat this as an active, ongoing exposure, not an emerging one.
Detection & Response
Realistic detection here means watching how packages enter developer environments — not trying to signature individual malicious packages, which is a losing game. The highest-fidelity signals: package managers installing from non-approved registries, direct-URL/git installs that bypass your proxy, and install-time script execution spawning unexpected child processes.
---
title: Package Manager Install From Non-Approved Registry or Direct URL
id: 8c2e4f61-3b7a-4d29-9e15-6a1c8f2b3d44
status: experimental
description: Detects npm, pip, or similar package managers invoked with custom registry/index arguments or direct URL/git installs that bypass internal package proxies — a common pattern when AI-generated install commands are accepted without review.
references:
- https://www.bleepingcomputer.com/news/security/who-vets-ais-code-the-scale-challenge-facing-open-source-ingestion/
- https://attack.mitre.org/techniques/T1195/002/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1195.002
logsource:
category: process_creation
product: windows
detection:
selection_tool:
Image|endswith:
- '\npm.cmd'
- '\npm.exe'
- '\pip.exe'
- '\pip3.exe'
- '\yarn.cmd'
- '\pnpm.cmd'
- '\python.exe'
selection_args:
CommandLine|contains:
- '--registry='
- '--index-url'
- '--extra-index-url'
- 'install git+'
- 'install https://'
- 'install http://'
- 'npm i git+'
condition: selection_tool and selection_args
falsepositives:
- Documented internal registries not yet added to the allowlist — tune by excluding approved index URLs
- Developers testing pre-release packages (should route through the approved proxy instead)
level: high
---
title: Package Install Hook Spawning Shell or Download Cradle
id: 3f7b9d25-1e4c-4a82-b6d3-9c5e2f8a1b77
status: experimental
description: Detects node/npm/pip child processes spawning shells, script interpreters, or download utilities during package installation — consistent with malicious preinstall/postinstall hooks or setup.py payloads delivered via slopsquatted or typosquatted packages.
references:
- https://www.bleepingcomputer.com/news/security/who-vets-ais-code-the-scale-challenge-facing-open-source-ingestion/
- https://attack.mitre.org/techniques/T1195/002/
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.execution
- attack.t1059
- attack.t1195.002
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\node.exe'
- '\npm.cmd'
- '\npm.exe'
- '\pip.exe'
- '\pip3.exe'
- '\python.exe'
- '\yarn.cmd'
- '\pnpm.cmd'
selection_child:
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
- '\cmd.exe'
- '\wscript.exe'
- '\cscript.exe'
- '\curl.exe'
- '\wget.exe'
- '\certutil.exe'
- '\mshta.exe'
condition: selection_parent and selection_child
falsepositives:
- Legitimate native module compilation (node-gyp) spawning build tooling — exclude cl.exe, msbuild.exe, and known build chains
- Some legitimate postinstall scripts invoke cmd.exe for environment setup; baseline against your approved package set
level: high
// Hunt: package installation activity that bypasses approved registries or pulls from direct URLs
// Scope: developer workstations and build agents via Defender for Endpoint
let ApprovedRegistries = dynamic(["registry.npmjs.org", "pypi.org", "artifactory.corp.example.com"]);
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where FileName in~ ("npm.exe", "npm.cmd", "pip.exe", "pip3.exe", "python.exe", "yarn.cmd", "pnpm.cmd", "node.exe")
or ProcessCommandLine has_any ("npm install", "npm i ", "pip install", "yarn add", "pnpm add")
| where ProcessCommandLine has_any ("--registry=", "--index-url", "--extra-index-url", "git+", "install http")
or (ProcessCommandLine matches regex @"https?://[^\s]+" and not(ProcessCommandLine has_any (ApprovedRegistries)))
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessAccountName, SHA256
| order by TimeGenerated desc
-- Hunt: recently modified dependency manifests and lockfiles across developer endpoints,
-- correlated with package-manager processes referencing non-standard sources.
-- Deploy as a Velociraptor hunt across the developer fleet.
LET manifest_hits = SELECT FullPath, Mtime, Size
FROM glob(globs=['C:/Users/*/**/package.json',
'C:/Users/*/**/package-lock.json',
'C:/Users/*/**/requirements.txt',
'C:/Users/*/**/Pipfile.lock',
'C:/Users/*/**/yarn.lock'])
WHERE Mtime > now() - 86400 * 7
LET suspicious_installs = SELECT Pid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE CommandLine =~ '(?i)(--registry=|--index-url|git\+|install https?://)'
AND Name =~ '(?i)(npm|pip|yarn|pnpm|node|python)'
SELECT * FROM manifest_hits
UNION ALL
SELECT FullPath, Mtime, Size FROM manifest_hits WHERE 1=0
SELECT Pid, Name, CommandLine, Username, CreateTime FROM suspicious_installs
# Dependency drift audit for Windows developer workstations
# Flags recently installed global npm/pip packages not present in an approved allowlist
# Run via your RMM/Intune as a recurring compliance check
$AllowlistPath = "\\corp\security\approved-packages.txt" # one package name per line
$Approved = Get-Content $AllowlistPath -ErrorAction Stop
$Findings = @()
# --- npm global packages ---
if (Get-Command npm -ErrorAction SilentlyContinue) {
$npmGlobal = npm ls -g --depth=0 --json 2>$null | ConvertFrom-Json
foreach ($pkg in $npmGlobal.dependencies.PSObject.Properties.Name) {
if ($Approved -notcontains $pkg) {
$Findings += [pscustomobject]@{Ecosystem='npm'; Package=$pkg; Version=$npmGlobal.dependencies.$pkg.version; Approved=$false}
}
}
}
# --- pip user/site packages ---
if (Get-Command pip -ErrorAction SilentlyContinue) {
$pipList = pip list --format=json 2>$null | ConvertFrom-Json
foreach ($pkg in $pipList) {
if ($Approved -notcontains $pkg.name) {
$Findings += [pscustomobject]@{Ecosystem='pip'; Package=$pkg.name; Version=$pkg.version; Approved=$false}
}
}
}
# --- direct-URL / git-sourced entries in pip (high-risk indicator) ---
if (Get-Command pip -ErrorAction SilentlyContinue) {
pip freeze 2>$null | Where-Object { $_ -match '@ (git\+|https?://)' } | ForEach-Object {
$Findings += [pscustomobject]@{Ecosystem='pip-direct-url'; Package=$_; Version='n/a'; Approved=$false}
}
}
if ($Findings) {
$Findings | Sort-Object Ecosystem, Package | Format-Table -AutoSize
$Findings | Export-Csv "$env:ProgramData\security\dependency-drift-$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
Write-Warning "$($Findings.Count) unapproved package(s) detected. Route to AppSec for review before next build."
exit 1
} else {
Write-Output "All installed packages are on the approved list."
exit 0
}
Remediation
The core principle from the ActiveState piece is correct and worth operationalizing: govern at the point of selection, not at the point of scan. Concretely:
-
Force all package resolution through an internal proxy/registry. Artifactory, Nexus, GitHub Packages, or a curated artifact service should be the only reachable package source. Enforce this at the network layer (egress rules blocking direct access to npmjs.org / pypi.org from developer and build VLANs) — config alone will be bypassed by AI-suggested
--registryflags, as the detection rules above illustrate. -
Stand up an approval workflow for net-new dependencies. Any package not already in your curated repository requires a lightweight review: maintainer history, download velocity, release cadence, install-hook analysis, transitive tree scan. Tools in the curated-repository space (ActiveState's offering among them) exist specifically for this; evaluate whether your current artifact management can enforce "deny by default."
-
Defang install hooks. Where possible, disable lifecycle script execution:
npm config set ignore-scripts truefleet-wide, and usepip install --no-binary :all:policies judiciously with sandboxed builds. This single control neutralizes the most common slopsquatting payload delivery mechanism. -
Pin and lock everything. Enforce lockfile usage (
package-lock.json,Pipfile.lock, hashes inrequirements.txtviapip install --require-hashes) and fail builds on lockfile drift. AI assistants love suggesting floating versions — your CI shouldn't accept them. -
Guard against slopsquatting proactively. Monitor new package registrations on PyPI/npm that resemble your internal package names and your commonly used dependencies (typosquat/slopsquat watchlists). Several open source tools and registry APIs support this. If your organization publishes packages, register the obvious hallucination-adjacent names defensively.
-
Constrain the AI tooling itself. Where your coding assistants support it, restrict suggestion sources to your internal registry and disable features that auto-execute install commands. Update acceptable-use policy: an AI-suggested dependency is treated as untrusted input until it clears the same review as a human-proposed one.
-
Train developers on the specific failure mode. "The model suggested it" is not provenance. A 30-minute awareness module on slopsquatting and hallucinated dependencies will do more than another generic secure-coding course.
There is no patch for this — it's a process and architecture problem. The organizations that get ahead of it will be the ones that treat dependency ingestion as a controlled gateway rather than an audit trail.
Related Resources
Security Arsenal Alert Triage Automation AlertMonitor Platform Book a SOC Assessment platform Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.