Skip to content

CVE-2026-82329: Verified Reproduction

CVE-2026-82329: JFrog Artifactory critical unauthenticated authentication bypass leading to administrative takeover

CVE-2026-82329 is verified against the affected target. Vulnerability class: Auth Bypass. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00341.

REPRO-2026-00341 Auth Bypass Vulnerable-path variant Sep 1, 2026 CVE entry .txt
Severity
CRITICAL
Confidence
HIGH
Reproduced in
145m 14s
Tool calls
255
Spend
$8.72
01 · Overview

What Is CVE-2026-82329?

CVE-2026-82329 is a critical-severity Auth Bypass vulnerability. Pruva has independently reproduced it and publishes a verified, runnable proof-of-concept (reproduction REPRO-2026-00341).

02 · Severity & CVSS

CVE-2026-82329 Severity

CVE-2026-82329 is rated critical severity.

CRITICAL threat level
Weakness CWE-287 Improper Authentication — Improper Authentication

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

How to Reproduce CVE-2026-82329

$ pruva-verify REPRO-2026-00341
or curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00341/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-82329

Authorization bypass — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

Unauthenticated HS256 join JWT (service_id/node_id claims chosen by attacker) signed with the publicly derivable blank-join-key HMAC secret (32 bytes of 0x20), sent to POST /access/api/v1/registry/join

Attack chain
  1. JFrog Access RegistryNoAuthResource POST /access/api/v1/registry/join
  2. JoinServiceImpl.getValidatedJwtToken
  3. JoinKeyAccess.getTokenSignatureVerifiers (blank additional join key, kid=sha256(''))
  4. ServiceTokenProviderImpl issues scope=admin service token; then /access/api/v1/users + /access/api/v1/tokens + /artifactory/api/system/info for admin takeover
Variants tested

Alternate unauthenticated entry points and key-selection branches reaching the same blank-join-key sink as the parent exploit: (A) POST /access/api/v1/registry/join/router (RegistryNoAuthResource.joinRouter, second no-auth endpoint), (B) same with ?override=true, (C) POST /access/api/v1/registry/join with explicit kid…

How the agent worked 573 events · 255 tool calls · 2h 25m
2h 25mDuration
255Tool calls
107Reasoning steps
573Events
19Dead-ends
Agent activity over 2h 25m
Support
11
Repro
371
Judge
34
Variant
152
Verify
1
0:00145:11

Root Cause and Exploit Chain for CVE-2026-82329

Versions: (vendor advisory): 7.111.4–7.111.20, 7.117.0–7.117.27, 7.125.0–7.125.19, 7.133.0–7.133.28, 7.146.0–7.146.36, 7.161.0–7.161.19. Fixed: 7.111.21 / 7.117.28 / 7.125.20 / 7.133.29 / 7.146.38 / 7.161.20.

JFrog Artifactory's Access service, in default configuration, registered a blank (empty-string) join key in its "additional join keys" verification cache. Join keys are the HMAC secrets used to authenticate cluster-join requests at the unauthenticated endpoint POST /access/api/v1/registry/join. Because JoinKeyUtils.getSigningKey("") pkcs7-pads the empty key to the constant 32 × 0x20, every vulnerable instance accepts a join JWT signed with an attacker-known key. A successful join returns a never-expiring service admin token (scope: "admin") for an attacker-chosen service id, which is then usable to dump users, reset the built-in administrator's password, and mint platform-wide admin user tokens — full administrative takeover starting from zero valid credentials. Fixed in 7.146.38 (and corresponding branches) by rejecting blank join keys.

  • Component: JFrog Access service bundled with self-hosted JFrog Artifactory (verified on artifactory-jcr 7.146.25; internal Access 7.176.x).
  • Affected versions (vendor advisory): 7.111.4–7.111.20, 7.117.0–7.117.27, 7.125.0–7.125.19, 7.133.0–7.133.28, 7.146.0–7.146.36, 7.161.0–7.161.19. Fixed: 7.111.21 / 7.117.28 / 7.125.20 / 7.133.29 / 7.146.38 / 7.161.20.
  • Risk: CVSS 9.8 Critical (AV:N/AC:L/PR:N/UI:N). Any unauthenticated network attacker can obtain administrative control of the platform (user management, admin credential reset, admin token issuance), leading to full compromise of hosted artifacts and CI/CD supply chain.

Impact Parity

  • Disclosed/claimed maximum impact: unauthenticated authentication bypass → administrative takeover (authz_bypass, CVSS C:H/I:H/A:H).
  • Reproduced impact in this run: identical — zero-credential admin takeover demonstrated end-to-end against the real product:
    1. POST /access/api/v1/registry/join with a JWT signed with HMAC-SHA256 key 20*32HTTP 201, service admin token (sub=jfrt@cve202682329poc…, scp=admin).
    2. GET /access/api/v1/users with that token → HTTP 200, full user list (including admin record).
    3. PUT /access/api/v1/users/adminHTTP 200, built-in admin password reset to an attacker-chosen value (account takeover).
    4. POST /access/api/v1/tokens {"username":"admin","scope":"applied-permissions/admin"}HTTP 200, admin user token (sub=jfac@…/users/admin, scp=applied-permissions/admin, aud=*@*).
    5. GET /artifactory/api/system/info (admin-only) with that token → HTTP 200 with full system internals.
  • Parity: full. No step used any pre-existing credential, account, or token; the chain starts from a raw unauthenticated HTTP request.

Root Cause

The fix was isolated by binary-diffing artifactory-jcr:7.146.36 (last vulnerable) against artifactory-jcr:7.146.38 (fixed). The entire payload difference is the Access service (7.176.27 → 7.176.28), and within it exactly two security-relevant classes changed (the rest are manifests/UI bundles):

  1. org/jfrog/access/server/startup/JoinKeyAccess.classtryResolveJoinKeys():
    - Arrays.stream(joinKey.get().split(",")).map(String::trim).forEach(jKey -> {
    + Arrays.stream(joinKey.get().split(",")).map(String::trim).filter(Strings::isNotBlank).forEach(jKey -> {
    
  2. org/jfrog/access/token/JoinKeyHashPair.class — constructor:
    + if (joinKey == null || joinKey.isBlank()) {
    +     throw new IllegalArgumentException("Join key must not be null or blank");
    + }
    

Why the bug fires in default configuration:

  • JoinKeyAccess.tryResolveJoinKeys() resolves shared.security.additionalJoinKeys. When unset (default), resolveJoinKeys() returns "" wrapped in a vavr Try. The guard if (!joinKey.isEmpty()) calls Try.isEmpty(), which tests for failure/null — not string emptiness — so the empty default proceeds to "".split(",")[""], and a JoinKeyHashPair("") (blank join key) is registered in the additional-join-keys map under kid = sha256("") = e3b0c442…b855.
  • JoinKeyUtils.getSigningKey("")hexDecodeAndPad("", 32) → pkcs7-pads to the constant 32-byte key 0x20 0x20 … 0x20publicly derivable, identical on every default installation.
  • The unauthenticated RegistryNoAuthResource.join (POST /access/api/v1/registry/join) → JoinServiceImpl.getValidatedJwtToken()getJoinKey(jwt)joinKeyAccess.getTokenSignatureVerifiers(kid): with no kid claim it tries the main join key plus every additional join key (including the blank one); with kid=e3b0c442… it selects the blank key directly. An HS256 JWT signed with 32 × 0x20 therefore verifies.
  • On verification, ServiceTokenProviderImpl.getToken(serviceId) issues TokenSpec … .scope("admin") .expiresIn(0) via createInternalTokenWithoutAuthAndNotify — a platform-trusted, never-expiring service admin token for the attacker-chosen service_id claim.

So one unauthenticated POST yields admin-level identity; trivial follow-ups (PUT /access/api/v1/users/admin, POST /access/api/v1/tokens) convert it into full administrative takeover of Artifactory.

Reproduction Steps

  1. bundle/repro/reproduction_steps.sh (self-contained; requires Docker, curl, python3).
  2. The script:
    • Pulls releases-docker.jfrog.io/jfrog/artifactory-jcr:7.146.25 (vulnerable), :7.146.38 (fixed), and postgres:16-alpine (7.146.x refuses to start on the legacy embedded Derby DB).
    • Boots each Artifactory with a default-config system.yaml (external PostgreSQL only; no join key / additional join keys configured) plus a generated master.key, using docker create + docker cp + docker start (single-file bind mounts break JFrog's atomic system.yaml rewrite).
    • Runs bundle/repro/exploit_join_bypass.py against each instance: blank-key JWT join, Access admin operations, admin password reset, admin token mint, admin-only Artifactory API call, plus built-in controls (anonymous token mint must 401; wrong-signature join must 400).
    • Writes per-run evidence JSON, image IDs, version files, and runtime_manifest.json.
  3. Expected evidence: vulnerable instance → join HTTP 201 with scp=admin token, admin takeover steps all 200, exploit JSON "exploited": true, script exit 0; fixed instance → join HTTP 400 (JWT's signature does not match the server's join key), "exploited": false.

Evidence

  • bundle/artifacts/http/vuln_exploit.json — full request/response transcript of the successful exploit against 7.146.25 (join 201 + scp=admin token claims; users dump 200; admin password reset 200; admin user token claims sub=jfac@…/users/admin, scp=applied-permissions/admin; /artifactory/api/system/info 200; anonymous controls 401; wrong-signature join 400).
  • bundle/artifacts/http/fixed_exploit.json — identical attack against 7.146.38 rejected at the join step (HTTP 400, "exploited": false).
  • bundle/artifacts/diff/JoinKeyAccess.diff, bundle/artifacts/diff/JoinKeyHashPair.diff (+ full decompiled classes) — the two-class security patch between 7.146.36 and 7.146.38.
  • bundle/logs/reproduction_steps.log — orchestration log; bundle/logs/art-{vuln,fixed}-docker.log, art-{vuln,fixed}-access-join.log — service-side logs.
  • bundle/artifacts/vuln_image_id.txt / fixed_image_id.txt, vuln_version.txt / fixed_version.txt — tested target identity.
  • Environment: Docker (rootless), postgres:16-alpine sidecar, artifactory-jcr:7.146.25 (Access 7.176.15) vs artifactory-jcr:7.146.38 (Access 7.176.28), linux x86_64.

Recommendations / Next Steps

  • Upgrade self-hosted Artifactory to 7.111.21 / 7.117.28 / 7.125.20 / 7.133.29 / 7.146.38 / 7.161.20 or later (per branch).
  • Interim mitigation: restrict network access to the Access/router endpoints (/access/api/v1/registry/*) to trusted networks; audit access_nodes/access_audit for unexpected service registrations and tokens (scp=admin with unknown jfrt@… subjects), and rotate the join key, master key, and the admin password after upgrading.
  • Fix approach (already shipped): reject null/blank join keys in JoinKeyHashPair and filter blank entries when parsing additionalJoinKeys. Additionally consider requiring a kid and binding join tokens to node_id/topology registration, and rate-limiting/auditing the no-auth join endpoint.
  • Testing: regression test that a default install has no additional join keys (/access/api/v1/system/security/join_key children) and that registry/join rejects empty-key HMAC JWTs.

Additional Notes

  • Idempotency: the script tears down and recreates all containers/network each run and was executed twice consecutively with identical results (vulnerable exploited, fixed blocked). Each run generates fresh master keys, databases, node ids, and attacker service ids.
  • Limitations: verification used the JCR (Container Registry) image; repository-management REST (/api/repositories) is Pro-gated in JCR, so admin takeover was demonstrated via Access admin APIs + admin token mint + the admin-only /artifactory/api/system/info endpoint instead of repository creation. The vulnerable code lives in the shared Access service, so Pro/ProX distributions are equally affected.
  • The 30-second iat freshness check on join tokens (MAX_REQUEST_AGE_IN_SECONDS) is honored by minting the JWT at exploit time.

Variant Analysis & Alternative Triggers for CVE-2026-82329

Versions: (vendor advisory): 7.111.x <7.111.21, 7.117.x <7.117.28, 7.125.x <7.125.20, 7.133.x <7.133.29, 7.146.x <7.146.38, 7.161.x <7.161.20.

The parent reproduction exploited the unauthenticated endpoint POST /access/api/v1/registry/join. This variant stage performed static sink-coverage analysis on the extracted Access service (7.176.15 vulnerable vs 7.176.28 fixed) and found that the same vulnerable sink (JoinServiceImpl.getValidatedJwtTokengetJoinKeyJoinKeyAccess.getTokenSignatureVerifiers, which trusts the auto-registered blank additional join key, kid sha256("") = e3b0c442…b855) is reachable through additional unauthenticated entry points and key-selection branches the parent PoC did not exercise:

  • Variant A — POST /access/api/v1/registry/join/router (second no-auth endpoint in RegistryNoAuthResource, joinRouter()). Confirmed on 7.146.25: HTTP 200, wrapper JWT carrying a never-expiring scp=admin service token in its token claim → full admin takeover re-demonstrated.
  • Variant B — POST /access/api/v1/registry/join/router?override=true (override branch skipping node-id/IP validation). Confirmed on 7.146.25.
  • Variant C — POST /access/api/v1/registry/join with explicit kid=e3b0c442… (kid-selected branch of JoinKeyAccess.getRelevantJoinKeys, vs the no-kid try-all branch used by the parent exploit). Confirmed on 7.146.25: HTTP 201.

All three variants were then re-run against the fixed build 7.146.38: all rejected with HTTP 400. Therefore this stage confirms a distinct alternate trigger (variant), but NOT a bypass — the shipped fix (reject blank join keys in JoinKeyHashPair + filter blank entries in JoinKeyAccess.tryResolveJoinKeys) covers every entry point and data path found, because all of them funnel through the single shared sink that was patched.

Fix Coverage / Assumptions

The fix (Access 7.176.27 → 7.176.28, shipped in Artifactory 7.146.38 et al.) consists of exactly two changes:

  1. JoinKeyAccess.tryResolveJoinKeys(): .map(String::trim).filter(Strings::isNotBlank) when parsing shared.security.additionalJoinKeys.
  2. JoinKeyHashPair.<init>: throw new IllegalArgumentException when the join key is null or blank.

Invariant the fix relies on: all consumers of additional join keys go through JoinKeyHashPair / the additionalJoinKeys cache, i.e. blank keys can never enter the verification key set regardless of entry point. This stage verified the invariant holds:

  • Byte-level/decompiled comparison shows JoinServiceImpl, RegistryNoAuthResource, RegistryResource, and SecuritySubResource are identical between the vulnerable and fixed builds — only JoinKeyAccess (and JoinKeyHashPair in access-common-api) changed.
  • Constant-pool scan of all Access server jars shows the join-key verification sink (JoinKeyAccess.getTokenSignatureVerifiers, JoinKeyUtils.getSigningKey, JoinKeyHashPair) is consumed only by JoinServiceImpl; JoinService is referenced only by RegistryNoAuthResource (network-facing) and TopologyServiceImpl (internal). No gRPC or other REST resource reaches the sink.

What the fix covers: both no-auth endpoints (join, join/router), both key-selection branches (no-kid try-all, explicit-kid lookup), and even a hypothetical admin misconfiguration (additionalJoinKeys containing blank/whitespace entries would now throw at parse time).

What the fix does NOT cover (out of scope, requires admin-level config control): an administrator who deliberately configures a short/guessable non-blank hex join key (e.g. 00) would still create a weak key, since JoinKeyUtils.getSigningKey pkcs7-pads short keys deterministically. This crosses no attacker trust boundary by itself (setting join keys is an admin operation), so it is not a variant of this CVE — but enforcing a minimum join-key entropy would be worthwhile hardening.

Variant / Alternate Trigger

Same root cause (blank additional join key accepted by default), same sink, different entry point / data path:

ID Entry point Code path Vuln 7.146.25 Fixed 7.146.38
A POST /access/api/v1/registry/join/router RegistryNoAuthResource.joinRouterJoinServiceImpl.joinRoutergetValidatedJwtTokengetJoinKey (no-kid try-all incl. blank key) → registerWithcombineTokenAndCertificate (wrapper JWT with admin token in token claim) HTTP 200, admin takeover HTTP 400
B POST /access/api/v1/registry/join/router?override=true same as A, override branch skips validateNodeIdAndIP HTTP 200, admin takeover HTTP 400
C POST /access/api/v1/registry/join (explicit kid claim) RegistryNoAuthResource.joinjoingetValidatedJwtTokengetJoinKeygetRelevantJoinKeys(kid) kid-selected branch (direct blank-key hit) HTTP 201, admin takeover HTTP 400

Variant-specific notes:

  • joinRouter's validateCheckUrl is a no-op when the check_url claim is omitted (StringUtils.isEmpty guard), so no attacker-hosted callback server is needed.
  • validateNodeIdAndIP (non-override path, access-topology mode) is satisfied with fresh random node_id/node_ip claims; ?override=true skips it entirely.
  • The router-join response is text/plain: a JWT signed with the (blank) join key whose token custom claim carries the inner never-expiring scp=admin service token — trivially decoded by the attacker.
  • The wrapper JWT additionally embeds the platform root CA certificate (root_cert claim), a minor extra information disclosure of the variant endpoint.

Rule-out (no further real candidates exist): the sink has exactly one consumer (JoinServiceImpl) reachable from exactly one no-auth resource (RegistryNoAuthResource) exposing exactly two endpoints; both endpoints and both key-selection branches were tested. A whitespace-only additionalJoinKeys entry would collapse to the same blank key (trim → blank) and requires admin config access anyway (no trust-boundary crossing). Testing more payload permutations would only relabel the same trigger.

  • Component: JFrog Access service bundled with self-hosted JFrog Artifactory (tested on artifactory-jcr 7.146.25 / Access 7.176.15 vs 7.146.38 / Access 7.176.28).
  • Affected versions (vendor advisory): 7.111.x <7.111.21, 7.117.x <7.117.28, 7.125.x <7.125.20, 7.133.x <7.133.29, 7.146.x <7.146.38, 7.161.x <7.161.20.
  • Risk: CVSS 9.8 — unauthenticated remote administrative takeover. The join/router variant additionally returns the platform root CA certificate to the unauthenticated attacker.

Impact Parity

  • Disclosed/claimed maximum impact (parent): unauthenticated auth bypass → administrative takeover (authz_bypass, C:H/I:H/A:H).
  • Reproduced via variants: identical. For each variant on 7.146.25, with zero credentials: service admin token obtained (sub=jfrt@cve202682329var…, scp=admin) → GET /access/api/v1/users 200 → POST /access/api/v1/tokens mints admin user token (sub=jfac@…/users/admin, scp=applied-permissions/admin, aud=*@*) → GET /artifactory/api/system/info 200 (admin-only).
  • Parity: full. Nothing claimed was left undemonstrated; the fixed build blocks all variants at the join step.

Root Cause

Identical to the parent RCA: default configuration registers a blank join key in the additional-join-keys cache because Try.isEmpty() does not test string emptiness (JoinKeyAccess.tryResolveJoinKeys), and JoinKeyHashPair accepted blank keys; JoinKeyUtils.getSigningKey("") pkcs7-pads to the attacker-known constant 32 × 0x20. This stage adds the sink-coverage proof that join/router (and the explicit-kid branch) hit the same unpatched code — and that the two-class fix closes all of them. Fix reference: JFrog security advisories (CVE-2026-82329, published 2026-08-28); binary diff 7.146.36 → 7.146.38 (Access 7.176.27 → 7.176.28), see bundle/artifacts/diff/.

Reproduction Steps

  1. bundle/vuln_variant/reproduction_steps.sh (self-contained; Docker, curl, python3). Idempotent; executed three times with identical results (final two runs after a logging fix: exit 1).
  2. The script boots PostgreSQL + vulnerable artifactory-jcr:7.146.25 + fixed artifactory-jcr:7.146.38 (default config, no join keys configured), then runs bundle/vuln_variant/exploit_join_router_variant.py in modes router, router-override, join-kid against both instances.
  3. Expected evidence: vulnerable → each variant returns a service admin token and full takeover steps succeed ("exploited": true); fixed → each variant rejected at the join step with HTTP 400. Exit 0 would mean a variant reproduces on the fixed build (true bypass); actual exit 1 = variants confirmed on vulnerable only, no bypass.

Evidence

  • bundle/artifacts/variant_http/vuln_{router,router-override,join-kid}.json — full request/response transcripts of the three successful variant exploits against 7.146.25 (200/200/201 at the join step, scp=admin token claims, admin takeover steps all 200).
  • bundle/artifacts/variant_http/fixed_{router,router-override,join-kid}.json — identical attacks against 7.146.38, all HTTP 400, "exploited": false.
  • bundle/logs/vuln_variant/reproduction_steps.log — orchestration log (three runs); art-var-{vuln,fixed}-docker.log — service logs; docker_pull.log; vuln_version.txt / fixed_version.txt — tested target identity (artifactory.version=7.146.25 / 7.146.38).
  • bundle/vuln_variant/decomp/ — extracted Access jars (7.176.15 / 7.176.28), decompiled sources proving: (a) RegistryNoAuthResource exposes two no-auth endpoints, (b) JoinServiceImpl is the sole sink consumer and is identical across versions, (c) validateCheckUrl is skippable by omitting check_url, (d) fix is confined to JoinKeyAccess/JoinKeyHashPair.
  • Environment: rootless Docker, postgres:16-alpine sidecar, linux x86_64.

Recommendations / Next Steps

  • No fix extension required: the shipped patch covers all discovered variants; the coding stage can rely on the two-class fix as complete for this root cause. Regression tests should cover both no-auth endpoints (join and join/router) and both key-selection branches (no-kid, explicit kid=e3b0c442…) — the router endpoint is the one most likely to be forgotten by a test suite.
  • Hardening ideas: enforce minimum join-key entropy/length in JoinKeyHashPair (pkcs7-padding silently upgrades short hex keys to deterministic keys); require a kid claim on join requests; bind join tokens to topology/node registration; rate-limit and audit /access/api/v1/registry/*; alert on scp=admin tokens issued to unknown jfrt@… subjects.
  • Post-upgrade: rotate join key, master key, and admin password; audit access_nodes for rogue registrations (including REGISTERING router nodes, which variant A/B inserts).

Additional Notes

  • Idempotency: the script recreates network/containers/databases/keys each run; three consecutive executions produced identical verdicts (vuln: all 3 variants exploited; fixed: all 3 blocked). Runs 2 and 3 used the final script and exited 1 (no bypass).
  • First-run correction: the initial script version had a verdict-parsing bug (command substitution captured tee output whose timestamps contained :0, producing a false "BYPASS" conclusion). This was fixed by routing exploit output to stderr/log only; the corrected verdict is definitive and was reproduced twice.
  • Limitations: JCR image used (Pro repository APIs gated); the vulnerable code lives in the shared Access service, so the variants apply equally to Pro/ProX. No git commit SHA exists for the proprietary fixed build; exact identity is pinned by image tag + image ID + embedded artifactory.product.version.properties.

CVE-2026-82329 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:002:27
0:00
session startedaccounts/fireworks/models/kimi-k3 · CVE-2026-82329 · REPRO-20
0:08
0:10
web search
0:20
0:54
1:23
1:23
extract_facts
no facts extracted
1:25
1:25
supportclaim_contract
1:31
1:31
1:31
1:37
1:37
1:37
1:37
1:48
1:48
$ls -la /pruva/project-cache/ 2>/dev/null; echo ---; docker info 2>&1 | head -5; echo ---; which docker dockerd; echo ---; free -g | head -2; df -h / /pruva 2>/dev/null | head -5
0.1s
total 4
drwx------ 4 vscode vscode   80 Sep  1 05:40 .
drwxr-xr-x 3 root   root   4096 Sep  1 05:40 ..
drwx------ 2 vscode vscode   60 Sep  1 05:40 .pruva
drwx------ 2 vscode vscode   40 Sep  1 05:40 repo-mirrors
---
Client:
 Version:    29.1.3
1:48
1:52
1:52
$docker info 2>&1 | grep -E "Server|ERROR|error" | head -10; echo ---; ps aux | grep -i dockerd | grep -v grep; echo ---; cat /pruva/project-cache/.pruva/* 2>/dev/null | head -50; ls /pruva/project-cache/repo-mirrors/
0.1s
Server:
 Server Version: 27.5.1
---
---
{
  "schema_version": 1,
  "entries": [
    {
2:01
2:01
2:02
web search
2:14
2:14
2:26
2:27
web search

Artifacts and Evidence for CVE-2026-82329

Scripts, logs, diffs, and output captured during the reproduction.

bundle/artifacts/diff/JoinKeyAccess.diff0.8 KB
bundle/artifacts/diff/JoinKeyHashPair.diff0.5 KB
bundle/artifacts/fixed_image_id.txt0.1 KB
bundle/artifacts/fixed_version.txt0.2 KB
bundle/artifacts/http/fixed_exploit.json1.0 KB
bundle/artifacts/http/vuln_exploit.json5.5 KB
bundle/artifacts/vuln_image_id.txt0.1 KB
bundle/artifacts/vuln_version.txt0.2 KB
bundle/logs/reproduction_steps.log3.4 KB
bundle/repro/exploit_join_bypass.py7.0 KB
bundle/repro/rca_report.md9.6 KB
bundle/repro/reproduction_steps.sh9.9 KB
bundle/repro/runtime_manifest.json1.9 KB
bundle/repro/validation_verdict.json1.5 KB
bundle/artifacts/variant_http/fixed_join-kid.json1.2 KB
bundle/artifacts/variant_http/fixed_router-override.json1.1 KB
bundle/artifacts/variant_http/fixed_router.json1.1 KB
bundle/artifacts/variant_http/vuln_join-kid.json4.8 KB
bundle/artifacts/variant_http/vuln_router-override.json6.1 KB
bundle/artifacts/variant_http/vuln_router.json6.1 KB
bundle/logs/vuln_variant/fixed_version.txt0.2 KB
bundle/logs/vuln_variant/reproduction_steps.log9.9 KB
bundle/logs/vuln_variant/vuln_version.txt0.2 KB
bundle/vuln_variant/decomp/src-vuln/org/jfrog/access/server/rest/resource/registry/RegistryNoAuthResource.java2.5 KB
bundle/vuln_variant/exploit_join_router_variant.py7.7 KB
bundle/vuln_variant/patch_analysis.md4.5 KB
bundle/vuln_variant/rca_report.md11.7 KB
bundle/vuln_variant/reproduction_steps.sh7.3 KB
bundle/vuln_variant/root_cause_equivalence.json3.1 KB
bundle/vuln_variant/runtime_manifest.json2.6 KB
bundle/vuln_variant/source_identity.json1.6 KB
bundle/vuln_variant/validation_verdict.json3.7 KB
bundle/vuln_variant/variant_manifest.json5.2 KB
08 · How to Fix

How to Fix CVE-2026-82329

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-82329 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-82329

Is CVE-2026-82329 exploitable?

Yes. Pruva independently reproduced CVE-2026-82329 and verified the exploit fires end-to-end in a sandboxed environment. A runnable proof-of-concept script and the full agent transcript are on this page (reproduction REPRO-2026-00341).

How severe is CVE-2026-82329?

CVE-2026-82329 is rated critical severity.

What type of vulnerability is CVE-2026-82329?

CVE-2026-82329 is classified as CWE-287 Improper Authentication (Improper Authentication), a Auth Bypass vulnerability.

How can I reproduce CVE-2026-82329?

Pruva provides a verified reproduction script on this page. Download it and run it inside an isolated environment such as a container or virtual machine — never against production. The reproduction was confirmed end-to-end by Pruva's automated agents.

Is the CVE-2026-82329 reproduction verified?

Yes. Pruva reproduced CVE-2026-82329 with high confidence in a sandboxed environment, capturing the full agent transcript and artifacts as evidence.
11 · References

References for CVE-2026-82329

Authoritative sources for CVE-2026-82329 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.