CVE-2025-70849 Overview
CVE-2025-70849 is an arbitrary file upload vulnerability in stefanprodan/podinfo through version 6.9.0. Unauthenticated attackers can upload arbitrary files by sending a crafted POST request to the /store endpoint. The application renders uploaded content without a restrictive Content-Security-Policy (CSP) header and without adequate Content-Type validation. This combination produces a Stored Cross-Site Scripting (XSS) condition, tracked under [CWE-79].
Podinfo is a popular Kubernetes demo and reference microservice used widely for GitOps testing, progressive delivery demonstrations, and cluster bootstrapping. Stored XSS in this component can compromise sessions of users who view the rendered content.
Critical Impact
Unauthenticated attackers can upload attacker-controlled content to the /store endpoint and trigger Stored XSS in any browser that renders the response.
Affected Products
- stefanprodan/podinfo versions up to and including 6.9.0
- Podinfo deployments running on Kubernetes clusters
- Any environment exposing the podinfo /store endpoint to untrusted networks
Discovery Timeline
- 2026-02-03 - CVE-2025-70849 published to the National Vulnerability Database (NVD)
- 2026-02-11 - Last updated in NVD database
Technical Details for CVE-2025-70849
Vulnerability Analysis
The vulnerability combines two distinct weaknesses in podinfo. First, the /store endpoint accepts POST requests from unauthenticated clients and persists the supplied payload without sanitization or strict content validation. Second, when the stored content is retrieved and served back, podinfo returns it without a restrictive Content-Security-Policy header. The response also lacks adequate Content-Type enforcement.
A browser receiving the response interprets attacker-supplied HTML or JavaScript as active content. This results in Stored XSS, where the malicious payload executes in the security context of the podinfo origin. Attackers can steal session tokens, perform actions on behalf of authenticated viewers, or pivot to other resources hosted on the same origin.
Root Cause
The root cause is twofold. The /store endpoint lacks authentication and input validation, allowing arbitrary payloads. The HTTP response handler omits the Content-Security-Policy header and does not force a safe Content-Type such as application/octet-stream or text/plain with X-Content-Type-Options: nosniff. Browsers therefore render the attacker payload as HTML or JavaScript.
Attack Vector
The attack requires network access to the podinfo /store endpoint and user interaction to view the malicious resource. An attacker sends a crafted POST request containing HTML or JavaScript to /store. The server persists the payload and assigns a retrievable identifier. The attacker then distributes the resulting URL through phishing, social engineering, or links embedded in trusted contexts. When a victim opens the URL, the payload executes in their browser.
No verified exploit code is publicly available beyond the proof-of-concept referenced in the GitHub Gist PoC Repository. The technical mechanism is described in prose above rather than reproduced as runnable code.
Detection Methods for CVE-2025-70849
Indicators of Compromise
- POST requests to the /store endpoint of podinfo containing HTML tags, <script> elements, or JavaScript event handlers in the request body.
- HTTP responses from podinfo that include user-supplied content without a Content-Security-Policy header.
- Unexpected outbound requests from user browsers shortly after retrieving content from podinfo-hosted URLs.
- Stored objects in podinfo state containing payloads with javascript: URIs, onerror=, onload=, or encoded script fragments.
Detection Strategies
- Inspect ingress and service mesh logs for POST requests to /store originating from external or untrusted source IP ranges.
- Apply web application firewall (WAF) signatures that flag XSS payload patterns in request bodies targeting podinfo routes.
- Correlate file upload events with subsequent GET requests to the same resource path from different client IPs to identify exploitation chains.
Monitoring Recommendations
- Enable verbose HTTP access logging on Kubernetes ingress controllers fronting podinfo deployments.
- Forward podinfo and ingress telemetry to a centralized data lake for retrospective hunting against the indicators above.
- Track anomalous spikes in /store POST volume and unique source IPs interacting with the endpoint.
How to Mitigate CVE-2025-70849
Immediate Actions Required
- Restrict network exposure of podinfo so the /store endpoint is unreachable from untrusted networks. Use NetworkPolicy or ingress rules to limit access to internal testing namespaces.
- Remove or disable podinfo from production-adjacent clusters where it is not actively required for demonstration or testing.
- Audit existing podinfo state for previously stored payloads containing HTML or JavaScript and purge suspicious entries.
Patch Information
No vendor advisory URL is listed in the NVD record at the time of publication. Monitor the upstream stefanprodan/podinfo repository for releases beyond 6.9.0 that address the missing CSP, Content-Type enforcement, and unauthenticated /store upload behavior. Refer to the GitHub Gist PoC Repository for the technical context cited by the CVE record.
Workarounds
- Deploy an ingress-level WAF rule that blocks POST requests to /store containing <script, onerror=, onload=, or javascript: substrings.
- Inject a restrictive Content-Security-Policy response header at the ingress or service mesh layer, for example default-src 'none'; script-src 'none'; frame-ancestors 'none'.
- Force the Content-Type of /store responses to text/plain and add X-Content-Type-Options: nosniff via ingress annotations to prevent browser sniffing.
- Require authentication in front of podinfo using an OAuth2 proxy or service mesh authorization policy.
# Example: Kubernetes NetworkPolicy restricting podinfo ingress to a trusted namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: podinfo-restrict-store
namespace: podinfo
spec:
podSelector:
matchLabels:
app: podinfo
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
trust: internal
ports:
- protocol: TCP
port: 9898
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


