Your artifact repository is the beating heart of your software supply chain — and this week, it became a confirmed attack surface. Security researchers have disclosed two vulnerabilities in JFrog Artifactory that allow attackers to poison package metadata across software repositories, according to reporting by Infosecurity Magazine. In practical terms: an attacker who can manipulate package metadata in your Artifactory instance can redirect dependency resolution, inject malicious artifacts into builds, and compromise every developer workstation, CI/CD runner, and production system that pulls from your repositories.
This is not a theoretical supply chain thought exercise. Artifactory sits at the center of thousands of enterprise build pipelines, proxying and caching npm, PyPI, Maven, NuGet, Docker, and dozens of other package types. A metadata poisoning flaw in that position is a force multiplier for adversaries — one compromised repository can silently propagate malicious code across an entire engineering organization without touching a single endpoint directly.
If you run Artifactory — self-hosted, in the cloud, or as part of a hybrid pipeline — you need to treat this as an urgent patch-and-hunt event. This post breaks down what these flaws enable, how to detect abuse in your environment, and how to remediate and harden your repository infrastructure.
Technical Analysis
What Happened
Per the reporting, two distinct flaws in JFrog Artifactory enable an attacker to manipulate package metadata — the index, descriptor, and resolution files that tell package managers which artifact version to download and from where. Metadata poisoning is dangerous because package managers implicitly trust it: when npm install, pip install, or a Maven build resolves a dependency, it follows the metadata. If the metadata lies, the build pulls attacker-controlled content.
The attack chain from a defender's perspective looks like this:
- Initial access or abuse of the flaw: The attacker exploits one of the two Artifactory weaknesses — either remotely against an exposed instance, or with low-privilege authenticated access that should not permit metadata modification.
- Metadata manipulation: The attacker alters package index files (e.g., npm
package.jsondist-tarball references, PyPI simple index entries, Mavenmaven-metadata.xml, or checksum files) to point at malicious artifacts, spoof version ordering, or substitute hashes. - Silent propagation: Downstream CI/CD jobs and developer builds resolve dependencies against the poisoned metadata and pull attacker-controlled packages. Because the artifacts come from the trusted internal repository, they inherit trust — signature checks, egress allowlists, and developer intuition all fail.
- Execution: Malicious install scripts or trojanized library code execute on build agents and developer machines, establishing persistence, stealing credentials (npm tokens, cloud keys, SSH keys), or pivoting further.
Affected Products and Exposure
- Product: JFrog Artifactory (self-hosted and cloud-managed deployments serving remote, local, and virtual repositories)
- Affected surface: Repository metadata handling across multiple package types. Repository managers that proxy public registries (npmjs.org, PyPI, Maven Central) are particularly sensitive, because poisoned cached metadata persists and is served to every internal consumer until invalidated.
- Who is exposed: Any organization whose Artifactory instance is reachable from the internet, reachable by lower-trust internal users, or whose access control model allows write/metadata operations beyond a tightly-scoped admin group.
Severity Assessment
While JFrog's advisory should be consulted for exact CVSS scoring and affected version ranges, the defender's severity calculation should weight three factors:
- Blast radius: One poisoned metadata entry propagates to every consumer of that repository — this is inherent amplification, not a single-host impact.
- Stealth: Metadata tampering does not trip traditional EDR. The malicious code arrives via a sanctioned channel over HTTPS from a trusted internal host.
- Persistence: Poisoned metadata in cached/remote repositories survives until the cache is purged. Patching the vulnerability does not undo metadata that was already altered.
Treat this as a high-severity, patch-immediately event with a mandatory post-patch integrity verification step.
Exploitation Status
At time of writing, the flaws have been publicly disclosed with technical detail sufficient for defenders — and therefore for attackers — to understand the mechanism. Public disclosure of supply chain flaws in ubiquitous infrastructure like Artifactory historically drives rapid attacker interest, including opportunistic scanning for exposed instances. Assume scanning and exploitation attempts will follow disclosure; hunt accordingly.
Detection & Response
The detections below target the observable behaviors this class of attack produces: anomalous API-driven modification of repository content, package manager processes pulling or executing unexpected payloads on build agents, and post-exploitation command execution on developer/CI endpoints.
Sigma Rules
---
title: Suspicious Package Manager Child Process Execution on Build or Developer Hosts
id: 8f3e2a91-4b7c-4d1e-9a05-2c6f8d1b3e7a
status: experimental
description: Detects package managers (npm, pip, mvn, gradle) spawning shells, script interpreters, or download tools — a hallmark of malicious install scripts delivered via poisoned repository metadata or trojanized dependencies.
references:
- https://www.infosecurity-magazine.com/news/jfrog-flaws-software-supply-chain/
- https://attack.mitre.org/techniques/T1195/002/
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1195.002
- attack.execution
- attack.t1059
logsource:
category: process_creation
product: windows
detection:
selection_parent:
ParentImage|endswith:
- '\npm.exe'
- '\node.exe'
- '\pip.exe'
- '\python.exe'
- '\mvn.exe'
- '\mvnw.cmd'
- '\gradle.exe'
- '\dotnet.exe'
- '\nuget.exe'
selection_child:
Image|endswith:
- '\cmd.exe'
- '\powershell.exe'
- '\pwsh.exe'
- '\wscript.exe'
- '\cscript.exe'
- '\mshta.exe'
- '\curl.exe'
- '\bitsadmin.exe'
- '\certutil.exe'
condition: selection_parent and selection_child
falsepositives:
- Legitimate build tooling that shells out during compilation (e.g., node-gyp spawning cmd.exe); baseline per build pipeline and filter known-good parent/child pairs
level: high
---
title: Linux Package Manager Spawning Shell or Download Utility
id: 1c9d4f62-7a3b-4e58-b2c1-9d5e7f0a3b48
status: experimental
description: Detects package manager or build tool processes (npm, node, pip, mvn, gradle, yarn) spawning shells, curl, wget, or base64 on Linux build agents and developer systems — consistent with malicious post-install scripts from a poisoned artifact repository.
references:
- https://www.infosecurity-magazine.com/news/jfrog-flaws-software-supply-chain/
- https://attack.mitre.org/techniques/T1195/002/
- https://attack.mitre.org/techniques/T1059/004/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1195.002
- attack.execution
- attack.t1059.004
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/npm'
- '/node'
- '/yarn'
- '/pip'
- '/pip3'
- '/python'
- '/python3'
- '/mvn'
- '/gradle'
- '/apt'
- '/apt-get'
- '/dpkg'
selection_child:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/curl'
- '/wget'
- '/base64'
- '/nc'
- '/ncat'
- '/python3'
condition: selection_parent and selection_child
falsepositives:
- Apt/dpkg maintainer scripts legitimately invoke shells during package installation; tune by parent process and build agent role
level: high
---
title: Anomalous Artifactory Repository Metadata Modification via API
id: 5b2a8e17-3f6d-4c9a-a7e4-8d1c2f5b9e06
status: experimental
description: Detects HTTP PUT/POST/DELETE requests against Artifactory API endpoints that modify package metadata files (maven-metadata.xml, package.json, index files) from sources outside expected deployment service accounts — potential metadata poisoning activity.
references:
- https://www.infosecurity-magazine.com/news/jfrog-flaws-software-supply-chain/
- https://attack.mitre.org/techniques/T1195/001/
- https://attack.mitre.org/techniques/T1078/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1195.001
- attack.persistence
logsource:
category: webserver
product: jfrog
detection:
selection_method:
cs-method:
- 'PUT'
- 'POST'
- 'DELETE'
selection_target:
cs-uri-stem|contains:
- 'maven-metadata.xml'
- 'package.json'
- '/api/npm/'
- 'index.xml'
- 'Release'
- 'Packages.gz'
- '.nupkg'
condition: selection_method and selection_target
falsepositives:
- CI/CD deploy service accounts legitimately publishing packages; scope to known deploy identities and source IPs, alert on all others
level: medium
KQL (Microsoft Sentinel / Defender)
The following hunts assume Artifactory access/request logs are ingested into Sentinel (via Syslog/CEF or a custom connector) and that build agents and developer workstations are onboarded to Microsoft Defender for Endpoint. The first query hunts for package-manager-spawned child processes on endpoints; the second hunts for anomalous write activity against Artifactory metadata paths in web logs.
// Hunt 1: Package managers spawning shells, downloaders, or script interpreters on build/dev endpoints
// Lookback: 14 days. Tune KnownGoodPipelines to your environment before production deployment.
let lookback = 14d;
let PackageManagers = dynamic(["npm.exe","node.exe","yarn.exe","pip.exe","python.exe","mvn.exe","gradle.exe","dotnet.exe","nuget.exe"]);
let SuspiciousChildren = dynamic(["cmd.exe","powershell.exe","pwsh.exe","wscript.exe","cscript.exe","mshta.exe","curl.exe","bitsadmin.exe","certutil.exe","rundll32.exe","regsvr32.exe","sh","bash","wget","nc"]);
DeviceProcessEvents
| where TimeGenerated > ago(lookback)
| where InitiatingProcessFileName in~ (PackageManagers)
| where FileName in~ (SuspiciousChildren)
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName, InitiatingProcessRemoteUrl, ReportId
| extend IsRemoteFetch = ProcessCommandLine has_any ("http://", "https://", "curl", "wget", "iwr", "downloadstring")
| order by TimeGenerated desc;
// Hunt 2: Write/modify operations against Artifactory package metadata paths (CEF/Syslog ingestion)
// Alert on metadata-modifying requests NOT sourced from known CI deploy subnets/service accounts.
let lookback = 14d;
let KnownDeploySources = dynamic(["10.10.20.0/24"]); // Replace with your CI/CD egress ranges
CommonSecurityLog
| where TimeGenerated > ago(lookback)
| where RequestMethod in ("PUT", "POST", "DELETE")
| where RequestURL has_any ("maven-metadata.xml", "/api/npm/", "package.json", ".nupkg", "/api/pypi/", "Packages.gz")
| where DeviceProduct has "Artifactory" or RequestURL has "artifactory"
| extend SourceInKnownRange = ipv4_is_in_range(SourceIP, "10.10.20.0/24")
| where SourceInKnownRange == false
| project TimeGenerated, SourceIP, SourceUserName, RequestMethod, RequestURL, RequestClientApplication, DestinationHostName, Activity
| summarize RequestCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, SourceUserName, RequestURL, RequestMethod
| order by RequestCount desc;
Velociraptor VQL
Use this hunt artifact on build agents and developer workstations to identify package-manager parentage anomalies — the execution footprint of a trojanized dependency delivered through poisoned repository metadata.
-- Hunt: Package managers spawning suspicious child processes
-- Targets build agents and developer endpoints potentially compromised via
-- poisoned Artifactory repository metadata / trojanized dependencies.
SELECT Pid,
Ppid,
Name AS ProcessName,
CommandLine,
Exe,
Username,
CreateTime
FROM pslist()
WHERE Ppid IN (
SELECT Pid
FROM pslist()
WHERE Name =~ '(?i)(npm|node|yarn|pip|python|mvn|gradle|dotnet|nuget)'
)
AND ( Name =~ '(?i)(cmd|powershell|pwsh|sh|bash|dash|curl|wget|mshta|wscript|cscript|certutil|bitsadmin|nc)'
OR CommandLine =~ '(?i)(curl |wget |iwr |downloadstring|base64 -d|FromBase64String|http://|https://)' )
ORDER BY CreateTime DESC
Post-Patch Integrity Verification Script
Patching Artifactory closes the door, but it does not evict an intruder who already poisoned metadata. The following Bash script verifies deployment state and audits cached metadata against upstream registries for tampering. Run it on your Artifactory host (or against the REST API) after upgrading.
#!/usr/bin/env bash
# artifactory-supplychain-audit.sh
# Post-remediation integrity audit for JFrog Artifactory after metadata poisoning flaw disclosure.
# Usage: ./artifactory-supplychain-audit.sh https://artifactory.example.com YOUR_ACCESS_TOKEN
set -euo pipefail
ART_URL="${1:?Provide Artifactory base URL}"
ART_TOKEN="${2:?Provide read-only access token}"
REPORT="artifactory-audit-$(date +%Y%m%d-%H%M%S).txt"
AUTH_HEADER="Authorization: Bearer ${ART_TOKEN}"
echo "=== Artifactory Supply Chain Integrity Audit ===" | tee "$REPORT"
echo "Target: ${ART_URL} Date: $(date -u)" | tee -a "$REPORT"
# --- 1. Confirm running version and compare against JFrog's fixed release ---
echo -e "\n[1] Installed Artifactory version:" | tee -a "$REPORT"
curl -sf -H "$AUTH_HEADER" "${ART_URL}/artifactory/api/system/version" | tee -a "$REPORT"
echo -e "\n>> ACTION: Compare this version against the fixed versions listed in the JFrog security advisory." | tee -a "$REPORT"
# --- 2. Enumerate users and flag accounts with deploy/delete (write) permissions ---
echo -e "\n[2] Non-admin users (review any with deploy/cache permissions on remote repos):" | tee -a "$REPORT"
curl -sf -H "$AUTH_HEADER" "${ART_URL}/artifactory/api/security/users" | grep -o '"name":"[^"]*"' | tee -a "$REPORT"
echo ">> ACTION: Audit permission targets; restrict deploy/cache rights to CI service accounts only." | tee -a "$REPORT"
# --- 3. Audit anonymous access — must be disabled on instances serving internal packages ---
echo -e "\n[3] Anonymous access configuration:" | tee -a "$REPORT"
ANON=$(curl -sf -H "$AUTH_HEADER" "${ART_URL}/artifactory/api/system/configuration" | grep -o '"anonAccessEnabled":[a-z]*' || echo "check-manually")
echo "$ANON" | tee -a "$REPORT"
echo ">> ACTION: If anonAccessEnabled is true, disable it immediately unless strictly required." | tee -a "$REPORT"
# --- 4. Spot-check cached npm metadata against upstream registry for tampering ---
# Pull dist tarball URLs and hashes for recently-resolved packages and diff against npmjs.org.
echo -e "\n[4] Checking recent artifact downloads for metadata review:" | tee -a "$REPORT"
curl -sf -H "$AUTH_HEADER" \
"${ART_URL}/artifactory/api/search/usage?notUsedSince=0" 2>/dev/null | head -c 4000 | tee -a "$REPORT" || \
echo "(usage API not available — pull recent download stats from the request log instead)" | tee -a "$REPORT"
echo ">> ACTION: For each recently resolved package, fetch upstream metadata (e.g., https://registry.npmjs.org/<pkg>)" | tee -a "$REPORT"
echo " and diff dist.tarball URLs and dist.integrity/shasum values against Artifactory's cached copy." | tee -a "$REPORT"
echo " Any mismatch = treat as poisoned; invalidate the remote repo cache for that package." | tee -a "$REPORT"
# --- 5. Review request logs for metadata-write operations from unexpected sources ---
echo -e "\n[5] Metadata-modifying requests in the last 7 days (requires log access):" | tee -a "$REPORT"
LOG_DIR="${ARTIFACTORY_HOME:-/opt/jfrog/artifactory/var}/log"
if [[ -f "${LOG_DIR}/request.log" ]]; then
grep -E '\.(PUT|POST|DELETE)\.' "${LOG_DIR}/request.log"* 2>/dev/null \
| grep -Ei 'maven-metadata\.xml|package\.json|/api/npm/|\.nupkg|Packages\.gz' \
| tail -n 200 | tee -a "$REPORT"
else
echo "(request.log not found at ${LOG_DIR} — export via your log pipeline and filter the same patterns)" | tee -a "$REPORT"
fi
echo ">> ACTION: Correlate each entry with CI deploy service accounts. Unknown source = investigate as intrusion." | tee -a "$REPORT"
# --- 6. Invalidate remote repository caches (purge potentially poisoned metadata) ---
echo -e "\n[6] Cache invalidation reminder:" | tee -a "$REPORT"
echo "For each REMOTE repository, zap caches post-patch: UI -> Repository -> right-click -> 'Zap Caches'," | tee -a "$REPORT"
echo "or via REST: curl -X POST -H \"$AUTH_HEADER\" ${ART_URL}/artifactory/api/<repo-key>/zap-caches" | tee -a "$REPORT"
echo -e "\n=== Audit complete. Report: ${REPORT} ==="
Remediation
1. Patch immediately. Upgrade Artifactory to the fixed version specified in JFrog's official security advisory for these flaws. Obtain the advisory and exact fixed release numbers directly from JFrog's security bulletins page (https://jfrog.com/help/r/jfrog-release-information/jfrog-security-advisories) and the JFrog Trust center — do not rely on third-party version summaries. JFrog Cloud (SaaS) customers receive patched versions automatically; verify with JFrog support that your instance has been updated.
2. Treat patch as necessary but not sufficient. Because these flaws enable metadata poisoning, you must assume any metadata written during your exposure window is suspect. After upgrading:
- Zap caches on all remote repositories (npm, PyPI, Maven, NuGet, Docker remotes) to force re-fetch of metadata and artifacts from upstream sources.
- Diff cached package metadata against upstream registries for your most-consumed dependencies — tarball URLs, integrity hashes, and version listings. Any divergence is an incident, not a discrepancy.
- Rebuild critical artifacts from source where feasible, and rotate any credentials present on build agents that executed builds during the exposure window (npm/PyPI tokens, cloud IAM keys, code-signing keys, SSH keys).
3. Lock down write access. Audit Artifactory permission targets. Deploy/delete permissions should belong exclusively to CI/CD service accounts with scoped repository access. Disable anonymous access. Enforce SSO with MFA and remove local accounts. Network-segment Artifactory so only build infrastructure and developers can reach it — it should never be internet-exposed without compensating controls.
4. Add supply chain integrity controls. Enforce checksum/signature verification in builds (npm --audit plus lockfile integrity pinning, pip install --require-hashes, Maven signature verification). Pin dependencies by hash, not just version. Consider JFrog Xray or equivalent SCA with curation policies that block unvetted upstream packages, and monitor for unexpected new versions of internal packages resolving from public registries (dependency confusion signal).
5. Hunt retroactively. Run the detections above across at least 30 days of telemetry. Any unexplained metadata writes, or package-manager-spawned shell/download activity on build agents, warrants a full IR scoping — treat build agents as high-value assets in your crown-jewel analysis, because attackers clearly do.
6. Verify external exposure. Scan your perimeter for Artifactory instances (including forgotten dev/test deployments). Shodan and your own EASM tooling will surface them. Any exposed instance running a vulnerable version should be treated as compromised until proven otherwise.
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.