JFrog Artifactory Under Attack: Unauthenticated Admin in Two HTTP Requests, Groovy Backdoors Survive the Patch

Introduction

Self-hosted JFrog Artifactory is being taken over with a handful of unauthenticated HTTP requests. Wiz Research documented active chaining of CVE-2026-42018 (anonymous token leak), CVE-2026-42016 (token scope not enforced), and CVE-2026-82329 (unauthenticated admin via the registry-join path). CISA added 42016 and 42018 to KEV on September 11 after adding 82329 a week earlier. Wiz's September 17 update is the part most teams will miss: attackers drop Groovy user plugins that keep running after you upgrade, and stealing Artifactory's Access private.key lets them mint valid tokens forever without returning to the host.

What Happened

Artifactory is the binary source of truth for a lot of CI/CD estates — containers, npm, Maven, PyPI, generic artifacts, even model files. Wiz's cloud telemetry found that when CVE-2026-42016 published on July 27, 67% of organizations running Artifactory had at least one vulnerable instance. Patching has been slow: six weeks later 59% were still exposed to 42016.

The two-step chain observed between August 15 and September 8:

  1. Unauthenticated POST /access/api/v1/aws/token/ (trailing slash) returns HTTP 200 and a JWT for the internal anonymous user — CVE-2026-42018, even when anonymous access is disabled.
  2. That JWT is exchanged at POST /access/api/v1/tokens for an admin-scoped token that still shows actor token:anonymous — CVE-2026-42016, because signature/issuer were checked and scope was not.
  3. Within minutes, actors PUT a persistent admin user under /api/security/users/ or /access/api/ui/users/.

Separately, CVE-2026-82329 (default-config auth bypass, CVSS 9.8) was exploited from September 1–8 via unauthenticated POST /access/api/v1/registry/join returning 200/201 with an admin-scoped token. Follow-on: configuration dump (GET /api/system/configuration), join-key theft, token minting, and SSH keys attached to the new users.

Post-exploitation that survives an upgrade:

  • Malicious Groovy plugins in $JFROG_HOME/var/etc/artifactory/plugins/ exposed at /artifactory/api/plugins/execute/... — unsandboxed inside the JVM
  • Disposable shells (rce.groovy, cmd.groovy, jwtToken.groovy / uploadFile.groovy)
  • Credential harvesters (JFrogImage.groovy) that decrypt LDAP, proxy, and remote-repo passwords and dump Access keys
  • Resident implants (metrics.groovy, httpSession.groovy) that inject an in-memory Tomcat filter, tunnel into the internal network with Proxy.NO_PROXY, and truncate request logs

Boilerplate backdoor usernames Wiz saw: Nxploited_*, labadmin_*, 0xTerror, svc_*, plus lookalikes like jfrog-distribution, jfrog-insight, repo-service, backup-service, migration-tool, ldap_admin.

JFrog Cloud was vendor-remediated. Self-hosted must upgrade. Fixed builds Wiz and the CVE records agree on: 7.111.21, 7.117.28, 7.125.20, 7.133.29, 7.146.38, 7.161.20 or later. Do not target a mythical 7.146.37 — it was never released.

Why It Matters

Admin on Artifactory is admin on the software supply chain. Poison a popular internal package once and every pipeline that pulls latest ships the implant. The Groovy plugin persistence is worse than the entry CVE: upgrading closes the door and leaves the resident filter in memory until the JVM restarts, and Access key theft means the attacker does not even need the host anymore.

Wiz's occupancy numbers — still a majority unpatched weeks after disclosure — explain why this belongs on the same list as the Bitwarden CLI and Trivy supply-chain pieces already on this site.

Who Is Affected

  • Self-hosted Artifactory on the 7.111, 7.117, 7.125, 7.133, 7.146, and 7.161 trains below the fixed builds above
  • Especially internet-exposed instances and anything that still allows anonymous or weakly segmented Access API reachability
  • JFrog Cloud customers — no self-serve patch for these CVEs; confirm with JFrog if you have a hybrid edge
  • Every CI job, Kubernetes pull, and developer workstation that trusts this registry

How to Protect Yourself

1. Upgrade every node, replica, DR copy, and container image to a fixed build.

# identify the running version (Omnibus / archive / compose all differ — check what you actually run)
curl -sS -u admin:"$ART_PASS" https://artifactory.example.test/artifactory/api/system/version
# or
cat $JFROG_HOME/var/etc/system.yaml | head

Move to at least 7.111.21 / 7.117.28 / 7.125.20 / 7.133.29 / 7.146.38 / 7.161.20 on your train. Then restart the JVM so an in-memory metrics.groovy filter dies.

2. Hunt plugins, then delete anything you did not put there.

ls -la "$JFROG_HOME/var/etc/artifactory/plugins/"
# known malicious names from Wiz
ls "$JFROG_HOME/var/etc/artifactory/plugins/" |
  grep -Ei '^(rce|cmd|jwtToken|uploadFile|JFrogImage|metrics|httpSession)\.groovy$'

sha1sum "$JFROG_HOME/var/etc/artifactory/plugins/"*.groovy 2>/dev/null

Wiz published SHA1s for the recovered plugins (rce.groovy, cmd.groovy, JFrogImage.groovy, metrics.groovy, httpSession.groovy, jwtToken/uploadFile). Any match is confirmed compromise. Remove the files, restart Artifactory, and confirm /artifactory/api/plugins no longer lists them. If plugin APIs return HTTP 400 for administrators, treat that as the metrics.groovy anti-remediation behavior and restart/reimage.

3. Audit users and tokens. Delete lookalikes.

# list users — look for Nxploited_, labadmin_, svc_, 0xterror, jfrog-distribution, repo-service, etc.
curl -sS -u admin:"$ART_PASS" https://artifactory.example.test/artifactory/api/security/users

Revoke all Access tokens minted during the exposure window and reissue from a clean admin session. If Access keys may have been copied, reset the token signing certificate per JFrog's docs — patching does not invalidate a stolen private.key.

4. Search request logs for the exploit shape (and remember httpSession.groovy truncates request*.log to zero bytes):

# 42018: trailing-slash aws token endpoint succeeding
grep -E 'POST .*/access/api/v1/aws/token/' "$JFROG_HOME/var/log/artifactory/request.log"*

# 42016: anonymous identity minting tokens or touching /api/plugins
grep -E 'POST .*/access/api/v1/tokens|token:anonymous' "$JFROG_HOME/var/log/"*

# 82329: registry join returning 200/201 from an unexpected client
grep -E 'POST .*/access/api/v1/registry/join' "$JFROG_HOME/var/log/"*

Wiz's highest-confidence 42018 tell is behavioral: 401 on the bare path, then 200 on the trailing-slash variant from the same client in a short window.

5. Rotate everything Artifactory could decrypt. LDAP manager passwords, remote-repo credentials, proxy passwords, Crowd/SSO secrets, join keys, and CI tokens stored as Artifactory identities. Block egress from the Artifactory host except to known upstreams — several implants explicitly bypass the configured proxy.

6. Take it off the internet. Put Artifactory behind SSO and a VPN or private link. Disable anonymous access. Pin CI to digests, not moving tags, until you have verified repository integrity.

Source