/

CVE-2026-71236

Severity:

HIGH RISK

(8.7)

Stored XSS (CWE-79) in Grocy API Request Controller

CVE-2026-71236

Received

Vulnerability type

Category:

Stored Cross-Site Scripting

CWE:

CWE-79

Impact:

Stored Cross-Site Scripting and unauthorized browser actions

Severity:

HIGH RISK

(8.7)

CVSS version:

3.1

Catch this CVE while code is being written

Detect vulnerable code directly in pull requests, so CVEs are fixed before merge.

Summary

Grocy's API request-body parser can undo HTML entity encoding after input has been purified, allowing dangerous markup to be reconstructed in stored field values. When affected data is later rendered without re-sanitization, an attacker may execute script in the context of users viewing products, recipes, stock, users, chores, or other records.

Affected context

The vulnerability occurs in Grocy deployments where API-writable fields pass through the affected request-body parsing path and are subsequently displayed by application views without an additional context-appropriate output encoding or sanitization step. Risk depends on whether an attacker can submit or modify records through an exposed API and whether other users or administrators later view the stored content.

Exploit preconditions

  • Attack surface: Grocy API endpoints that accept writable request-body fields
  • Required access: Ability to submit or modify API data, subject to the deployment's authentication and authorization controls
  • Trigger point: Request-body parsing followed by storage and later rendering of the affected value
  • Why exploitation is possible: HTMLPurifier output is manually double-decoded, reconstructing markup that the purifier had encoded to prevent active HTML or script content

Why this happens

The underlying bug is an inconsistent sanitization pipeline. After HTMLPurifier neutralizes potentially active markup by entity-encoding it, subsequent replacements convert encoded ampersands, angle brackets, and related sequences back into live characters.

This defeats the intended protection and maps to CWE-79: Improper Neutralization of Input During Web Page Generation, because attacker-controlled content can survive storage and become executable when inserted into a browser-rendered context.

Potential impact

  • An attacker may execute JavaScript in the browser of a user viewing a poisoned record.
  • A malicious value could perform actions available to the victim's session.
  • Administrative users may be targeted through stored content in commonly viewed records.
  • Sensitive information accessible to the victim's browser session could be exposed.
  • Stored malicious content could affect multiple users and persist until removed.

General mitigation guidance

Mitigation generally focuses on preserving a single, well-defined output-safety model throughout the data lifecycle.

Common defensive patterns include:

  • Avoiding manual entity decoding after sanitization.
  • Applying context-specific output encoding at every HTML, attribute, URL, or script insertion point.
  • Treating API input as untrusted even when it has passed an input purifier.
  • Using allowlisted, context-aware sanitization only where rich text is explicitly required.
  • Separating stored data from rendered markup and enforcing safe rendering primitives.
  • Limiting API permissions and applying least privilege to accounts that can modify records.
  • Using browser security controls such as an appropriately restrictive Content Security Policy as defense in depth.

How teams detect issues like this

Detection approaches can include:

  • Static analysis for manual replacements that decode HTML entities after sanitization.
  • Code review checks for values sanitized once and later rendered without context-specific encoding.
  • Tests that submit encoded markup and verify that it remains inert after parsing, storage, and rendering.
  • Dynamic application testing across API-writable fields and all views that display them.
  • Policy enforcement requiring approved output-encoding or sanitization utilities at rendering boundaries.
  • Neutral automated code-review tools that flag dangerous decode-after-sanitize data flows.

Sources

SourceLink
github.comgithub.com/grocy/grocy

Frequently asked

questions

It may be exploitable through the API when that interface is reachable and an attacker can modify writable records. The practical scope depends on authentication, authorization, network exposure, and which records are viewed by other users.

Usually, the attacker needs whatever permissions the deployment requires to write API data. If an endpoint permits unauthenticated writes, the exposure could be broader.

Remove the decode-after-sanitize behavior and apply context-appropriate output encoding at the point where values are rendered. Rich-text fields should use a narrowly defined allowlist rather than generic decoding.

Maintain clear trust boundaries, avoid mixing sanitization with manual entity transformations, test complete input-to-rendering flows, and enforce secure output-handling patterns through code review and automated analysis.

Find out what's already
exploitable in your codebase.