Back to Blog
CISA KEV · Actively Exploited · Supply Chain

JFrog Artifactory
Unauth → Supply-Chain Admin

Trace the boundary from Artifactory authority to artifact distribution and workload execution. A practical investigation of the CVE routes, identity evidence, downstream trust and controls that contain the impact.

Riad DAHMANIk8sec Security ResearchSeptember 202617 min readJFrogSupply ChainCISA KEVOpenShift
JFrog Artifactory CVE chain — unauthenticated to supply-chain admin

01 A registry is a production trust boundary

An Artifactory administrator controls a distribution system that other systems rely on. That is a serious foothold. It is not automatically an OpenShift cluster-admin identity: the downstream outcome depends on publishing permissions, artifact verification, deployment references and workload authority.

Separate the vulnerability from the attack path. A vulnerable version establishes exposure. An unauthorized administrative action establishes a different fact. A compromised registry feeding a production workload requires another chain of evidence entirely.

Registry authority, artifact trust and workload identity are different boundaries. Prove each transition; do not substitute a severity score for the chain.

02 Two entry routes, not three mandatory steps

JFrog's advisories describe three distinct flaws. CVE-2026-42018 exposes an internal anonymous token; CVE-2026-42016 concerns insufficient token validation; CVE-2026-82329 is an authentication bypass. Wiz reports active exploitation of the first two together and of the third separately. JFrog advisories · Wiz investigation.

RouteBoundary under testEvidence needed in your environment
42018 → 42016Anonymous token issuance → intended token scopeCorrelate issuance, identity and subsequent accepted privileged operations. Do not collect raw tokens.
82329Unauthenticated requester → administrative authorityCorrelate unexpected join activity with account, configuration or token-management changes.
Downstream supply chainRegistry write access → accepted production artifactMatch the changed digest to the actual running workload and its admission decision.
Operator tip — classify what you know. Keep separate fields for exposure, observed action, inferred impact and missing evidence. A successful HTTP response is not, by itself, proof of exploitation.

03 Interactive investigation map

Expand a branch to see the question, supporting evidence and control that breaks that part of the path. This is an investigation model, not an exploitation console.

Artifactory authority → artifact trust → workload execution

Identity & authority

Who gained authority?

Compare the effective privileges with the account's approved purpose. Retain token identifiers and scope metadata, not bearer credentials. An anonymous subject name must not be treated as evidence of low privilege.

What authorized the action?

Join access logs to account changes and the identity provider's timeline. Identify whether the action matched an approved administrative workflow. Break the path with supported patches, restricted administrative reachability and narrow machine identities.

Artifacts & provenance

What changed?

Compare digests, repository configuration and plugin hashes against an independently preserved baseline. A hash obtained only from the suspect registry is not an independent integrity check.

Who consumed it?

Follow the artifact through publishing, promotion and deployment. Resolve mutable tags to the digest the runtime actually pulled. Break the path with protected promotion, digest pinning and enforced provenance from a trusted signer.

Execution & containment

Which identity ran it?

Record the pod, namespace, ServiceAccount, node and relevant RBAC edges. Assess that workload's effective authority. A registry administrator and a Kubernetes administrator are not interchangeable identities.

What stops recurrence?

Separate containment from recovery. Preserve evidence, restrict affected distribution paths, and rotate exposed credentials from a trusted system. Validate that the corrected admission and authorization controls reject the demonstrated path.

04 Reconstruct the downstream path

Analysis scenario: an attacker changes an artifact that a production pipeline is allowed to consume. Each arrow below represents a transition that must be demonstrated; none is guaranteed by Artifactory administrative access alone.

  1. 1 · Registry changeIdentity, repository, time, prior and new digest.
  2. 2 · PromotionBuild identity, approval and destination repository.
  3. 3 · AdmissionResolved digest, signer, policy decision and deployment revision.
  4. 4 · WorkloadRuntime imageID, ServiceAccount, RBAC and observed behavior.
Registry change → promotion → admission → workload. Correlate evidence across the boundaries; do not assume the arrows exist.
Operator tip — “Synced” is not an integrity verdict. Git reconciliation can succeed while a mutable tag points at changed content. Compare the approved digest with the runtime imageID, including init containers.

05 The Read-Only Investigation Runbook

Patching stops step 1 tomorrow. It does nothing about the admin account created last week or the Groovy plugin already on disk. Run two parallel investigations: a compromise hunt (did someone get in, mint tokens, plant plugins, alter artifacts?) and a posture review (could a build system or upstream repo still poison what OpenShift runs?).

Everything below is read-only and evidence-first. It uses an approved investigation identity and a protected curl config — never paste tokens into commands, screenshots, or chat. UI labels vary by version and license.

5.1 · Preserve evidence before you touch anything

Before you restart Artifactory, delete a suspicious account, clear a cache, or rotate a credential — capture state. Restarting rotates logs; deleting an account destroys the timeline.

Timestamp
Record investigation start in UTC. Every read-only API call you make also generates logs — note that you are a source of events too.
Snapshot
Protected snapshots of config, database, and storage through your IR team — before any change.
All nodes
Preserve logs from every HA node including rotated/archived copies, plus reverse-proxy/WAF, IdP, EDR, Jenkins, and Kubernetes audit logs.
Do not "test"
Do not run exploit PoCs against production to "check." Do not pull suspicious images onto developer machines.

5.2 · Establish version, exposure, and repository inventory

Use an approved investigation identity. Have your administrator provision a protected curl config holding the auth header — accessible only to its owner. Never use curl -k.

read-only — version & repository inventory
export ART_URL='https://artifactory.example.com/artifactory'
export JFROG_CURL_CONFIG='/secure/path/artifactory-audit.curl'   # header lives here, not on the CLI

# Exact running build — compare against ALL THREE advisories, not one headline CVE
curl --fail --silent --show-error --config "$JFROG_CURL_CONFIG" \
  "$ART_URL/api/system/version"

# Full repository inventory — Local, Remote, Virtual, Federated
curl --fail --silent --show-error --config "$JFROG_CURL_CONFIG" \
  "$ART_URL/api/repositories"

Read the version output: record version, revision, deployment type, and the date each node was patched. Then establish exposure — self-hosted or Cloud? VM, container, or OpenShift? Which UI/API/registry endpoints are internet-reachable? Can callers bypass the reverse proxy and hit backend services directly? Were vulnerable versions exposed before patching? In the inventory, look for unknown repositories, unexpected package types, dev repos serving production, and missing ownership. A restricted identity may not see everything — incomplete visibility is an assessment gap, not a pass.

5.3 · Hunt unexpected administrators and tokens

This is where the chain lands. In Administration → Identity and Access, review Users, Groups, Permissions, and Access Tokens against what you expect.

InspectExpectedInvestigate immediately
AdministratorsNamed, approved ownersUnknown account or unexplained elevation
Service accountsOne identity per integration/environmentA Jenkins or pull identity holding platform-admin
TokensKnown subject, scope, issuer, audience, expiryAdmin scope on an anonymous subject; long lifetime; cross-instance audience
GroupsApproved membershipUnexpected privileged or broad auto-join membership
Federation / trustDocumented trusted instancesAn undocumented trust relationship
Anonymous accessDeliberately restrictedAnonymous reaching private artifacts or privileged activity

Token identities are not always persistent users, so reviewing the Users page alone is insufficient. For any suspicious identity, record the username/token ID, creation time, scope, and source IP — and correlate every one against the access log, IdP activity, and the expected owner. Do not export token values.

5.4 · Reconstruct the sequence from logs

Collect and work against preserved copies — not the live install. The files that matter: artifactory-access.log, artifactory-request.log, artifactory-service.log, the Access service logs, router-request.log, artifactory-request-out.log, and every rotated equivalent.

triage searches over preserved evidence (not live logs)
export EVIDENCE_DIR='/secure/evidence/artifactory-case'

# The signature of this chain: privileged actions attributed to the anonymous token
rg -n -i 'token:anonymous|/access/api/v1/aws/token' "$EVIDENCE_DIR" -g '*.log'

# Identity / plugin / config activity to correlate
rg -n -i '/security/users|/tokens|/groups|/permissions|/plugins|\.groovy' "$EVIDENCE_DIR" -g '*.log'

# Security-relevant state changes
rg -n -i 'CONFIGURATION_CHANGE|ACCEPTED (DEPLOY|DELETE)|BUILD_PROMOTE|PROPERTY_UPDATED' "$EVIDENCE_DIR" -g '*.log'

These are triage leads, not reliable signatures — they produce legitimate matches and do not search compressed archives (process those separately on working copies). Look for the ordered sequence: unexpected caller → token activity → admin creation/elevation → plugin/config change → unusual outbound connection or artifact modification. For each event, pin UTC timestamp, identity, source IP, trace ID, URL, and outcome. Behind a proxy, resolve the true client IP from trusted proxy logs — an HTTP 200 or an "anonymous" entry alone does not prove exploitation.

5.5 · Inspect plugins and host persistence

Malicious Groovy plugins and payloads in temp directories were the reported persistence mechanism. Treat those as hunting leads, against a preserved copy — do not execute or reload a suspicious plugin.

plugin + temp-dir triage (preserved copy / IR-authorized host only)
# Hash every plugin file and diff against your known-good Git repo / deployment package
find "$EVIDENCE_DIR/plugins" -maxdepth 3 -type f -exec sha256sum {} +

# If IR authorises live host triage — recent drops in the classic staging dirs
find /tmp /var/tmp /dev/shm -xdev -type f -newermt '2026-08-15' \
  -printf '%TY-%Tm-%TdT%TH:%TM:%TS  %u  %s  %p\n'

# Process ancestry and current listeners (visibility depends on permissions)
ps -eo user,pid,ppid,lstart,args --forest
ss -plant

Investigate unapproved .groovy files or dependency JARs, legitimate plugin names with changed content, and any plugin code that executes processes, opens network connections, or reads credential files. Timestamps can be forged and temp files are not inherently malicious — prefer EDR evidence for historical execution. For containerised or OpenShift deployments, investigate both the workload and its node / PVCs.

5.6 · Review remotes, mirrors, and Helm — and the artifacts themselves

A remote repository is an on-demand cache, not a full mirror; a normal request through it can fetch upstream and mutate the cache — so preserve metadata first and avoid exploratory downloads during forensics. For each remote/virtual/federated repo, inspect upstream URL and TLS, upstream credentials, virtual membership and deployment target, and replication direction.

ControlRed flag
Upstream source URLUnknown domain, plain HTTP, or an unexpected internal destination
TLS verificationCertificate validation bypassed
Virtual membership / orderingProduction resolves from a dev or untrusted remote
Replication / federationUndocumented external synchronization
Environment separationA dev identity can publish production artifacts

Then hunt artifact tampering with a bounded, read-only AQL query — this is a POST that queries, not an upload:

read-only AQL — recent changes in a production repo
curl --fail --silent --show-error --config "$JFROG_CURL_CONFIG" \
  -H 'Content-Type: text/plain' --data-binary \
  'items.find({"repo":"docker-prod-local","type":"file","modified":{"$gte":"2026-08-15T00:00:00Z"}})
     .include("repo","path","name","created","created_by","modified","modified_by","size")
     .sort({"$desc":["modified"]}).limit(100)' \
  "$ART_URL/api/search/aql"

Investigate production modifications by humans or unexpected service accounts, changes outside release windows, missing build provenance, and — the one that ends careers — a previously approved tag now resolving to a different digest. AQL shows current metadata, not overwrite history; verify integrity against an independent trusted record. A checksum stored inside a compromised registry is not independent proof.

5.7 · Trace the blast radius into Jenkins, Argo CD, and OpenShift

For each suspicious artifact, walk the chain forward: artifact digest → publishing Jenkins build → source commit → promotion → Argo CD revision → deployed workload. Read what is actually running, not what Git says should be running.

read the runtime-resolved image straight from the pod
oc --context=prod-cluster -n app-namespace get pod app-pod \
  -o jsonpath='{range .status.containerStatuses[*]}{.name}{"\t"}{.image}{"\t"}{.imageID}{"\n"}{end}'

# init containers matter too — a poisoned init image escapes a main-container-only check
oc --context=prod-cluster -n app-namespace get pod app-pod \
  -o jsonpath='{range .status.initContainerStatuses[*]}{.name}{"\t"}{.image}{"\t"}{.imageID}{"\n"}{end}'

image is the requested reference; imageID is the runtime-resolved digest. Then confirm: could Jenkins credentials publish directly to production? Could untrusted pull-request builds reach publishing credentials? Does production admission actually enforce signatures/provenance, or merely log? Argo CD "Synced" does not mean the image is trustworthy — a changed mutable tag leaves Git untouched.

06 Verdict — Config Finding Or Incident?

The evidence decides the response. Do not let "we patched" collapse into "we're clean."

EvidenceClassification & next action
Vulnerable version, no corroborating activityExposure — prioritise patching, keep hunting
Excessive CI permissions or untrusted upstreamPosture finding — document the attack path and remediate
Unauthorised admin/token, or a malicious pluginIncident — activate IR, assess privileged compromise
Unauthorised production artifact changeSupply-chain incident — identify and contain downstream consumers
Missing logs / incomplete visibilityInconclusive — not "clean"

If compromise is suspected: preserve evidence, restrict affected access and promotion routes, rotate exposed credentials from a trusted system, and handle JFrog trust/join-key changes through the vendor-supported recovery process. Deleting one plugin is not recovery. Record each finding as: UTC time | node/repo | identity | evidence ref | artifact digest | affected builds/workloads | severity | owner | next action.

07 Detection is correlation, not a path match

Use a short, documented correlation window and retain the underlying events. Group by trustworthy client address, identity and instance; include reverse-proxy records where they provide the only reliable caller attribution.

LeadCorroborationFalse-positive check
Unexpected token or join activityPrivileged account or configuration change by the same actorWas an approved administrative integration running?
Plugin integrity mismatchDeployment provenance, file history and process telemetryWas a reviewed plugin release deployed?
Production artifact modificationIndependent digest, publishing identity and downstream imageIDWas the modification an approved promotion?

These are detection design patterns, not tested vendor-neutral SIEM rules. Verify field mappings and retention in your own pipeline. Missing evidence should produce an inconclusive result, not a clean bill of health.

Operator tip — preserve before searching. Work from copies, document collection time and timezone, hash evidence, and handle compressed log rotations separately. Keep raw credentials out of tickets and reports.

08 Break the demonstrated path

Patch the affected branch
Use the vendor advisory for each CVE and your release line. Do not compare unrelated release branches as if they share one minimum safe version.
Restrict administrative reachability
Inventory every ingress path, including direct backends that bypass the intended proxy. Keep legitimate artifact consumers functional while restricting administrative access.
Enforce artifact trust
Require an approved digest and provenance from a trusted build identity at promotion and admission. A signature from a compromised trusted identity is not sufficient by itself.
Recover from a trusted baseline
If compromise is established, use the incident-response and vendor recovery process. Patching closes a vulnerability; it does not remove persistence or invalidate all stolen credentials.

09 Final word

The hardest question is not whether the registry was vulnerable. It is whether authority crossed from that registry into a system you still consider trusted. Answer it with identities, digests and authorization decisions—not with a dashboard's green status.

Security teams own the reconstruction. Trace the actual path, identify the missing controls, and demonstrate that remediation breaks it.

— Riad DAHMANI, k8sec Security Research

Continue from infrastructure evidence.

K8SEC Agent provides read-only Kubernetes graph intelligence. Correlate its workload and identity relationships with separately collected registry and pipeline evidence; it does not autonomously exploit or validate this supply-chain scenario.

Explore KAOS methodology Read the detection engineering guide

References: JFrog security advisories; Wiz's original investigation, updated September 11, 2026; CISA KEV catalog. Downstream examples and investigation tips are K8SEC analysis, not claims that every affected installation follows the same path. Validation is restricted to systems you are authorized to assess.

On this page

Contents

Trust boundaryTwo entry routesInvestigation mapDownstream pathInvestigationVerdictDetectionRemediationFinal word