Skip to content

CVE-2026-57947: Verified Reproduction

CVE-2026-57947: Pinpoint through 3.1.0 allows authenticated users to register internal webhook URLs, leading to SSRF when alarm webhooks are delivered.

CVE-2026-57947 is verified against pinpoint-apm/pinpoint · maven. Affected versions: <= 3.1.0 (affected from 0 through 3.1.0). Fixed in Not specified in advisory; GitHub issue milestone 3.1.1; no fixed commit identified. Vulnerability class: SSRF. This medium reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00253.

REPRO-2026-00253 pinpoint-apm/pinpoint · maven SSRF Jul 6, 2026 CVE entry .txt
Severity
MEDIUM
CVSS
6.3
Confidence
HIGH
Reproduced in
59m 13s
Tool calls
338
Spend
$7.79
01 · Overview

What Is CVE-2026-57947?

CVE-2026-57947 is a medium-severity (CVSS 6.3) server-side request forgery (CWE-918) in Pinpoint. An authenticated user can register webhook URLs that resolve to internal hosts or cloud metadata endpoints, and when an alarm fires Pinpoint issues the request. Pruva reproduced it (reproduction REPRO-2026-00253).

02 · Severity & CVSS

CVE-2026-57947 Severity & CVSS Score

CVE-2026-57947 is rated medium severity, with a CVSS base score of 6.3 out of 10.

MEDIUM threat level
6.3 / 10 CVSS base
Weakness CWE-918 — Server-Side Request Forgery (SSRF)

Medium — meaningful risk under specific conditions. Schedule a fix in the normal cycle.

03 · Affected Versions

Affected pinpoint-apm/pinpoint Versions

pinpoint-apm/pinpoint · maven versions <= 3.1.0 (affected from 0 through 3.1.0) are affected.

How to Reproduce CVE-2026-57947

$ pruva-verify REPRO-2026-00253
or curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00253/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-57947

Server-side request forgery — reproduced
  • reached the target end-to-end
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

authenticated user registers an arbitrary webhook URL through /api/webhook or /api/application/webhook

Attack chain
  1. POST /api/webhook (or /api/application/webhook) stores internal URL; alarm batch job sends HTTP POST to that URL
How the agent worked 921 events · 338 tool calls · 59 min
59 minDuration
338Tool calls
285Reasoning steps
921Events
3Dead-ends
Agent activity over 59 min
Support
17
Hypothesis
2
Repro
655
Judge
27
Variant
216
0:0059:13

Root Cause and Exploit Chain for CVE-2026-57947

Versions: Pinpoint through 3.1.0 (per CVE record and VulnCheck advisory)

Pinpoint 3.1.0 allows any authenticated user (minimum ROLE_USER) to register arbitrary webhook URLs through the /api/webhook and /api/application/webhook endpoints. The URL validation in WebhookController.validateURL() only checks that the supplied string is syntactically a valid URL (new URL(...).toURI()), with no filtering of private IP ranges, loopback addresses, or link-local metadata endpoints. The same lack of SSRF protection exists in the batch alarm sender (WebhookSenderImpl.validateURL()). When an alarm rule fires, the Pinpoint batch server performs a real HTTP POST to every registered webhook URL, so an attacker can coerce the server into sending requests to internal services such as 127.0.0.1 or 169.254.169.254.

  • Package/component affected: maven:com.navercorp.pinpoint:pinpoint-web (also pinpoint-batch, which contains the alarm sender)
  • Affected versions: Pinpoint through 3.1.0 (per CVE record and VulnCheck advisory)
  • Risk level and consequences: Medium-to-high. A authenticated user can force the Pinpoint server to issue server-side requests to internal network resources, including cloud metadata endpoints (e.g., AWS IMDSv1 http://169.254.169.254/). The webhook payload contains user-group member details, so a controlled internal endpoint can also exfiltrate names, e-mails, and phone numbers. This enables internal port scanning, metadata credential theft, and lateral movement from the Pinpoint server IP.

Impact Parity

  • Disclosed/claimed maximum impact: SSRF — the server makes unauthorized outbound HTTP requests to internal/attacker-controlled URLs when alarm thresholds are breached.
  • Reproduced impact from this run: The reproduction started the real pinpointdocker/pinpoint-web:3.1.0 container, authenticated as a non-admin user, registered webhooks pointing to http://169.254.169.254/..., http://127.0.0.1/..., and a controlled internal listener (http://ssrf-listener:9999/callback). It then started the real pinpointdocker/pinpoint-batch:3.1.0 alarm job and observed the batch server make a real HTTP POST to the controlled listener.
  • Parity: full for the SSRF claim — the server-side request was demonstrated end-to-end across the real product.
  • Not demonstrated: Actual extraction of cloud metadata credentials, because no live metadata service was present in the sandbox. The listener stands in for the attacker-controlled internal endpoint and proves the server-side request path.

Root Cause

The vulnerable code is in the webhook module of Pinpoint 3.1.0:

  • webhook/src/main/java/com/navercorp/pinpoint/web/webhook/controller/WebhookController.java (lines 117–120):

    private void validateURL(Webhook webhook) throws MalformedURLException, URISyntaxException {
        URL u = new URL(webhook.getUrl());
        webhook.setUrl(u.toURI().toString());
    }
    

    This only validates URL syntax. It does not reject 127.0.0.1, 169.254.169.254, 10.0.0.0/8, etc.

  • batch-alarmsender/src/main/java/com/navercorp/pinpoint/batch/alarm/sender/WebhookSenderImpl.java (lines 132–135):

    private String validateURL(String url) throws MalformedURLException, URISyntaxException {
        URL u = new URL(url);
        return u.toURI().toString();
    }
    

    The same missing checks are applied before the alarm sender calls restTemplate.exchange(validatedUrl, HttpMethod.POST, httpEntity, String.class).

There is no post-DNS guard, no IP allowlist/denylist, and no redirect protection. Any scheme/host/address accepted by java.net.URL is accepted by the application.

The issue was disclosed as GitHub issue #13857 ("Webhook URL missing SSRF protection allows authenticated users to reach internal network resources"). A patched version is not explicitly stated in the advisory, but the issue is closed against the 3.1.1 milestone.

Reproduction Steps

The full reproduction is captured in bundle/repro/reproduction_steps.sh. At a high level it:

  1. Brings up the real Pinpoint backend (pinpoint-hbase:3.1.0, MySQL, ZooKeeper, Redis) and the vulnerable pinpoint-web:3.1.0 container with basic authentication enabled.
  2. Inserts a fake application row into the HBase ApplicationIndex table so the alarm batch job recognises the target application.
  3. Starts a controlled internal HTTP listener (ssrf-listener) inside the same Docker network.
  4. Authenticates as testuser (a user with only ROLE_USER) and registers three webhooks:
    • http://169.254.169.254/latest/meta-data/iam/security-credentials/
    • http://127.0.0.1:9999/ssrf-poc
    • http://ssrf-listener:9999/callback (via the /api/application/webhook variant)
  5. Verifies that all three internal URLs are stored in the database via GET /api/webhook?applicationId=<app>.
  6. Authenticates as adminuser, creates a user group, and creates an alarm rule (TOTAL COUNT, threshold 0) linked to the listener webhook with webhookSend=true.
  7. Starts the real pinpoint-batch:3.1.0 container with alarmJob enabled and waits for the batch server to deliver a POST to the controlled listener.

Expected evidence:

  • Registration responses contain {"result":"SUCCESS"} and the stored webhook list contains the internal URLs.
  • bundle/logs/ssrf-listener.log shows a POST request from Apache-HttpClient/5.4.4 (Java/17.0.19) to /callback.
  • bundle/logs/ppssrf-batch.log shows Successfully sent webhook : Webhook{...url='http://ssrf-listener:9999/callback'...}.

Evidence

  • bundle/logs/reproduction_steps.log — full console output of the reproduction, including 401 for unauthenticated access, successful login, webhook registrations, and the listener receiving the POST.
  • bundle/logs/ppssrf-web.log — Pinpoint Web startup logs showing the active Spring profiles (release, basicLogin) and the vulnerable webhookEnable=true configuration.
  • bundle/logs/ppssrf-batch.log — batch alarm job logs showing the TOTAL COUNT checker detecting the alarm and the successful webhook send:
    ResponseCountChecker result is true for application (test-app-...). value is 0. (threshold : 0).
    Successfully sent webhook : Webhook{webhookId='12'...url='http://ssrf-listener:9999/callback'...}
    
  • bundle/logs/ssrf-listener.log — the controlled listener records the server-side POST:
    LISTENER_POST path=/callback headers={...'User-Agent': 'Apache-HttpClient/5.4.4 (Java/17.0.19)'...}
    LISTENER "POST /callback HTTP/1.1" 200 -
    
  • bundle/repro/artifacts/stored_webhooks.json — JSON list of stored webhooks, including http://169.254.169.254/... and http://127.0.0.1:9999/ssrf-poc.
  • bundle/repro/artifacts/register_metadata.json, register_loopback.json, register_listener.json — each contains {"result":"SUCCESS"}.
  • bundle/repro/artifacts/create_alarm.json — alarm rule created with webhookSend=true and linked to the listener webhook.

Recommendations / Next Steps

  1. Fix approach: Add a strict URL validator that rejects private/reserved/loopback/link-local IP addresses and metadata endpoints both at registration time and in the batch sender. A robust fix should also:
    • Resolve the hostname to IP addresses and check the resolved set against an allowlist/denylist (post-DNS guard).
    • Disable HTTP redirects or validate redirect targets.
    • Optionally require an explicit allowlist of webhook domains/IPs configurable by the operator.
  2. Upgrade guidance: Upgrade to a patched release > 3.1.0 once available. Until then, restrict access to the /api/webhook and /api/alarmRule endpoints and apply network-level egress controls on the Pinpoint server.
  3. Testing recommendations: Regression tests should assert that 127.0.0.1, 169.254.169.254, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, and ::1 are rejected by the webhook registration endpoint, and that the alarm sender does not send to those addresses even when already stored in the database.

Additional Notes

  • Idempotency: The script uses a unique timestamp suffix for the application name, user group, and HBase row qualifier, so repeated runs do not collide with leftover MySQL/HBase state. Two consecutive executions with REUSE_STACK=1 both completed successfully.
  • Limitations: The reproduction seeds a fake ApplicationIndex row in HBase so the alarm batch job recognises the target application. In a real deployment this row is created automatically when a Pinpoint agent reports for the application. Seeding the row is a sandbox-only convenience and does not change the vulnerability path.
  • Clean-run note: A full clean run requires several minutes for the HBase container to bootstrap. The script is designed to perform that bootstrap automatically when REUSE_STACK is not set.

CVE-2026-57947 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:001:28
0:00
session startedaccounts/fireworks/models/kimi-k2p7-code · CVE-2026-57947 · REPRO-20
0:04
0:06
web search
0:09
web search
0:12
0:14
web search
0:16
web search
0:20
0:21
0:54
0:54
extract_facts
no facts extracted
0:56
0:56
0:56
supportrepro
1:16
1:19
1:19
1:19
1:20
1:20
1:20
1:21
1:22
1:22
1:23
1:23
1:28
1:28
1:28
$docker ps && echo docker available
0.1s
{"cwd":"/data/pruva/runs/37f6347b-a435-4fc6-8a66-89724db7070e","duration_ms":124,"exit_code":0,"stderr":"","stdout":"CONTAINER ID   IMAGE                                                  COMMAND                   CREATED          STATUS                    PORTS                                                                                                                                                                                                                                                                        NAMES\ncf8c5fcf1692   wordpress:php8.2-apache                                \"docker-entrypoint.s…\"    3 minutes ago    Up 3 minutes              0.0.0.0:18083->80/tcp, [::]:18083->80/tcp                                                                                                                                                                                                                                    blocksy_test-wp_vuln-1\n3ffa4688f443   wordpress:php8.2-apache                                \"docker-entrypoint.s…\"    4 minutes ago    Up 3 minutes              0.0.0.0:18082->80/tcp, [::]:18082->80/tcp                                                    … [truncated]
08 · How to Fix

How to Fix CVE-2026-57947

Upgrade pinpoint-apm/pinpoint · maven to Not specified in advisory; GitHub issue milestone 3.1.1; no fixed commit identified or later.

Coming soon

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

10 · FAQ

FAQ: CVE-2026-57947

How is CVE-2026-57947 triggered?

An authenticated user registers a webhook pointing at an internal or metadata URL; when the associated alarm fires, Pinpoint's server sends the outbound request to that attacker-chosen internal target, yielding SSRF.

Which versions of Pinpoint are affected by CVE-2026-57947?

pinpoint-apm/pinpoint versions through 3.1.0 (from 0 through 3.1.0) are affected. The GitHub issue milestone references 3.1.1, but no fixed commit was identified in the advisory — track the project's fix and restrict webhook targets in the meantime.

How can I reproduce CVE-2026-57947?

Download the verified script from this page and run it in an isolated environment against Pinpoint 3.1.0. As an authenticated user it registers a webhook pointing at an internal canary and triggers the alarm, showing Pinpoint's server fetch the internal URL.
11 · References

References for CVE-2026-57947

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