On November 11, 2026, Simon Willison released version 0.37.2 of llm, his widely-adopted open-source CLI tool for interacting with Large Language Models. While the specific changelog details remain under review, any update to this critical MLOps component warrants immediate attention from security teams. The llm tool has become a staple in developer environments and CI/CD pipelines for AI orchestration, making it a high-value target for supply chain attacks and prompt injection exploitation.
Given the tool's ability to execute system commands via plugins and process untrusted input through LLM prompts, version updates often address critical security boundaries. Organizations using llm for automated content generation, code analysis, or data processing must treat this update as a priority security patch, not merely a feature release.
Technical Analysis
Affected Products and Attack Surface
Product: llm CLI (Python package)
Version: 0.37.2 (prior versions potentially vulnerable)
Platforms: All operating systems supporting Python 3.8+ (Windows, Linux, macOS)
Installation vectors: PyPI (pip install llm), Homebrew, direct GitHub installation
The llm tool presents a unique attack surface combining traditional CLI security with AI-specific threats:
-
Prompt Injection via Malicious Input: The tool processes untrusted text files, web content, and user input through LLM APIs. Maliciously crafted input could instruct the LLM to execute arbitrary system commands if the tool passes output to
os.system()or similar functions without sanitization. -
Plugin Supply Chain Risks: The tool supports community plugins (
llm install plugin-name). A compromised plugin could exfiltrate API keys, modify prompts to leak sensitive data, or establish persistence in MLOps pipelines. -
API Key Exposure: The tool stores API keys in plaintext configuration files (
~/.config/llm/keys.jsonor environment variables). Version 0.37.2 may address insecure storage or transmission vulnerabilities. -
Template Injection: Custom prompt templates using Jinja2 or similar engines could allow Server-Side Template Injection (SSTI) if user input reaches template rendering without sandboxing.
Exploitation Requirements
Exploitation typically requires:
- Local access to a system with
llminstalled, or - Ability to influence input files processed by the tool in automated pipelines, or
- Compromise of the PyPI supply chain to distribute malicious plugin versions
Current Threat Context
While no specific CVE is associated with this release in the provided summary, the 2025-2026 threat landscape has seen increased targeting of AI development tools. Attackers recognize that MLOps pipelines often have over-privileged access to training data, model weights, and production inference endpoints. A compromised llm installation could serve as a beachhead for lateral movement into AI infrastructure.
Detection & Response
Sigma Rules
---
title: LLM CLI Tool Execution with Suspicious Arguments
id: 8f4a2c91-3b7e-4d9a-b5c2-9e1f6a8d4c3b
status: experimental
description: Detects execution of the llm CLI tool with arguments indicative of prompt injection attempts or unauthorized plugin installation
references:
- https://attack.mitre.org/techniques/T1059/
- https://attack.mitre.org/techniques/T1195/
author: Security Arsenal
date: 2026/11/11
tags:
- attack.execution
- attack.t1059
- attack.supply_chain
logsource:
category: process_creation
product: windows
detection:
selection:
Image|endswith:
- '\llm.exe'
- '\python.exe'
CommandLine|contains:
- 'llm '
- 'install'
- 'plugin'
- '--system'
- 'exec'
filter_known_good:
CommandLine|contains:
- 'llm --version'
- 'llm models'
- 'llm plugins'
condition: selection and not filter_known_good
falsepositives:
- Legitimate plugin installation by developers
- Standard llm CLI usage in development environments
level: medium
---
title: Python Process Spawning System Shell via LLM Tool
id: 2c8e5f1a-9d4b-4e7a-a3c6-8f2b1d5e9a7c
status: experimental
description: Identifies Python processes (potentially running llm) spawning system shells or command interpreters, which may indicate successful prompt injection leading to command execution
references:
- https://attack.mitre.org/techniques/T1059/
- https://attack.mitre.org/techniques/T1203/
author: Security Arsenal
date: 2026/11/11
tags:
- attack.execution
- attack.t1059.001
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\python.exe'
- '\llm.exe'
selection_child:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\bash.exe'
- '\sh.exe'
- '\nc.exe'
- '\netcat.exe'
condition: selection_parent and selection_child
falsepositives:
- Legitimate use of llm plugins that require shell execution
- Development workflows involving subprocess calls
level: high
KQL (Microsoft Sentinel / Defender)
// Hunt for llm CLI execution with suspicious parameters or plugin installations
let TimeRange = 24h;
union isfuzzy=true
(SecurityEvent
| where TimeGenerated > ago(TimeRange)
| where EventID == 4688
| where Process has "llm" or CommandLine has "llm"
| where CommandLine has_any ("install", "plugin", "--system", "exec", "eval", "subprocess")
| project TimeGenerated, Computer, Account, Process, CommandLine, ParentProcessName),
(DeviceProcessEvents
| where TimeGenerated > ago(TimeRange)
| where FileName =~ "python.exe" or FileName =~ "llm.exe" or ProcessCommandLine contains "llm"
| where ProcessCommandLine has_any ("install", "plugin", "--system", "exec")
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName)
| summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Count = count() by Computer, Account, CommandLine
| where Count > 5 or CommandLine has "plugin"
| order by LastSeen desc;
// Hunt for suspicious outbound connections from llm/python processes
DeviceNetworkEvents
| where TimeGenerated > ago(24h)
| where InitiatingProcessFileName =~ "python.exe" or InitiatingProcessFileName =~ "llm.exe"
| where RemoteUrl has_any ("pastebin", "github", "raw.githubusercontent", "pypi") or RemoteIPType == "Public"
| where not(RemoteUrl has_any ("openai", "anthropic", "azure", "google")) // Exclude known API endpoints
| summarize ConnectionCount = count(), UniqueIPs = dcount(RemoteIP) by DeviceName, InitiatingProcessFileName, RemoteUrl, RemoteIP
| where ConnectionCount > 10
| order by ConnectionCount desc;
Velociraptor VQL
-- Hunt for llm CLI installations and recent modifications indicating potential compromise
SELECT
Pid,
Name,
CommandLine,
Exe,
Username,
CreateTime,
Exe as BinaryPath
FROM pslist()
WHERE CommandLine =~ 'llm'
OR Exe =~ 'llm'
OR Name =~ 'python.*llm'
-- Check for recently modified llm plugins (potential malicious updates)
SELECT
FullPath,
Size,
Mtime,
Atime,
Ctime
FROM glob(globs='**/.config/llm/plugins/**', accessor='file')
WHERE Mtime > now() - 86400 // Modified in last 24 hours
OR Ctime > now() - 86400
ORDER BY Mtime DESC
-- Hunt for suspicious network connections from Python processes (potential llm API abuse)
SELECT
Pid,
Name,
Path,
LocalAddr,
LocalPort,
RemoteAddr,
RemotePort,
State
FROM netstat()
WHERE Name =~ 'python'
AND State == 'ESTABLISHED'
AND RemoteAddr !~ '^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)' // External IPs only
Remediation Script
# Requires PowerShell 5.1 or later
# Run as Administrator for system-wide installations
Write-Host "=== LLM CLI Security Hardening Script ===" -ForegroundColor Cyan
Write-Host "Checking llm installation and version..." -ForegroundColor Yellow
# Check if llm is installed
try {
$llmVersion = & llm --version 2>$null
if ($llmVersion -match "0.37.2") {
Write-Host "[OK] llm version 0.37.2 detected" -ForegroundColor Green
} else {
Write-Host "[WARNING] llm version $llmVersion detected - UPDATE REQUIRED" -ForegroundColor Red
Write-Host "Updating llm to 0.37.2..." -ForegroundColor Yellow
pip install --upgrade llm==0.37.2
}
} catch {
Write-Host "[INFO] llm not found in PATH. Checking pip installations..." -ForegroundColor Yellow
$pipList = pip list | Select-String "llm"
if ($pipList) {
Write-Host "[WARNING] llm installed via pip but not in PATH or outdated" -ForegroundColor Red
pip install --upgrade llm==0.37.2
} else {
Write-Host "[OK] llm not installed on this system" -ForegroundColor Green
}
}
# Audit installed plugins
Write-Host "`n=== Auditing Installed Plugins ===" -ForegroundColor Cyan
$pluginPath = "$env:USERPROFILE\.config\llm\plugins"
if (Test-Path $pluginPath) {
$plugins = Get-ChildItem -Path $pluginPath -Recurse -Filter "*.py" | Select-Object FullName, LastWriteTime
foreach ($plugin in $plugins) {
$hash = Get-FileHash -Path $plugin.FullName -Algorithm SHA256
Write-Host "Plugin: $($plugin.FullName)" -ForegroundColor White
Write-Host " Last Modified: $($plugin.LastWriteTime)" -ForegroundColor Gray
Write-Host " SHA256: $($hash.Hash)" -ForegroundColor Gray
# Check for recently modified plugins (potential supply chain attack)
if ($plugin.LastWriteTime -gt (Get-Date).AddDays(-7)) {
Write-Host " [ALERT] Recently modified - verify legitimacy" -ForegroundColor Red
}
}
} else {
Write-Host "No plugins directory found" -ForegroundColor Green
}
# Check for suspicious API key storage
Write-Host "`n=== Checking API Key Storage ===" -ForegroundColor Cyan
$keyPaths = @(
"$env:USERPROFILE\.config\llm\keys.json",
"$env:APPDATA\llm\keys.json"
)
foreach ($keyPath in $keyPaths) {
if (Test-Path $keyPath) {
$acl = Get-Acl $keyPath
$accessRules = $acl.Access | Where-Object { $_.IdentityReference -notlike "*$env:USERNAME*" -and $_.IdentityReference -notlike "*SYSTEM*" -and $_.IdentityReference -notlike "*Administrators*" }
if ($accessRules) {
Write-Host "[WARNING] API key file accessible by unauthorized users: $keyPath" -ForegroundColor Red
Write-Host "Restricting permissions..." -ForegroundColor Yellow
icacls $keyPath /inheritance:r /grant:r "$env:USERNAME`(F`)" /grant:r "SYSTEM`(F`)" 2>$null
} else {
Write-Host "[OK] API key file permissions appear secure: $keyPath" -ForegroundColor Green
}
# Check if keys are base64 encoded (plaintext check)
$content = Get-Content $keyPath -Raw
if ($content -match '"sk-[a-zA-Z0-9]{48}"' -or $content -match '"sk-ant-[a-zA-Z0-9-]{95}"') {
Write-Host "[CRITICAL] Plaintext API keys detected in $keyPath" -ForegroundColor Red
Write-Host "Consider using environment variables or Azure Key Vault integration" -ForegroundColor Yellow
}
}
}
# Monitor for suspicious network activity
Write-Host "`n=== Network Security Recommendations ===" -ForegroundColor Cyan
Write-Host "1. Restrict outbound traffic from llm processes to known API endpoints only:" -ForegroundColor White
Write-Host " - api.openai.com" -ForegroundColor Gray
Write-Host " - api.anthropic.com" -ForegroundColor Gray
Write-Host " - generativelanguage.googleapis.com" -ForegroundColor Gray
Write-Host "2. Block access to pypi.org from production systems running llm" -ForegroundColor White
Write-Host "3. Implement application whitelisting to prevent unauthorized llm plugin execution" -ForegroundColor White
Write-Host "`n=== Remediation Complete ===" -ForegroundColor Green
Remediation
Immediate Actions
-
Update Immediately: Upgrade all installations to
llmversion 0.37.2 usingpip install --upgrade llm==0.37.2or your package manager equivalent. -
Plugin Audit: Review all installed plugins in
~/.config/llm/plugins/. Remove any plugins not explicitly required for business operations. Verify plugin sources—only install from official PyPI repositories or verified GitHub sources. -
API Key Hygiene: Rotate all API keys stored in
keys.jsonfiles. Migrate to environment variables or enterprise secret management solutions (Azure Key Vault, HashiCorp Vault, AWS Secrets Manager) rather than plaintext files. -
Network Segmentation: Restrict outbound network access for systems running
llmto only required API endpoints (OpenAI, Anthropic, etc.). Block access to PyPI and GitHub from production AI inference systems to prevent plugin supply chain attacks.
Configuration Hardening
- Disable Plugin Auto-Install: If not required, disable the ability to install plugins in production environments by removing write permissions to the plugins directory.
- Input Sanitization: Implement strict input validation for any files processed through
llmin automated pipelines. Treat all LLM output as untrusted code. - Sandbox Execution: Run
llmin isolated containers or VMs with restricted system access, especially when processing untrusted input.
Verification
Verify the update and check for indicators of compromise:
- Confirm version:
llm --versionshould return0.37.2 - Check for unexpected Python processes with network connections
- Audit file system for recently modified
.pyfiles in the llm installation directory - Review proxy logs for connections to suspicious domains from Python processes
Supply Chain Security
Given the November 2026 release timing, verify the integrity of the package:
- Download only from official PyPI (
pypi.org/project/llm/) - Verify package hashes against Simon Willison's official release notes
- Monitor for typosquatting packages (e.g.,
llm-cli,llm-python) that may mimic this tool
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.