Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-71236

CVE-2026-71236: Grocy API XSS Vulnerability

CVE-2026-71236 is a stored XSS flaw in Grocy's API that allows attackers to inject malicious scripts through double-decoding of HTML entities. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-71236 Overview

CVE-2026-71236 is a stored Cross-Site Scripting (XSS) vulnerability [CWE-79] in Grocy, an open-source ERP system for household grocery and chore management. The flaw resides in the API request-body parser at controllers/Api/BaseApiController.php, specifically the GetParsedAndFilteredRequestBody function. The parser sanitizes input with HTMLPurifier, then manually reverses the entity encoding that HTMLPurifier applied to neutralize dangerous markup. This double-decode reconstructs live HTML and script tags, reintroducing stored XSS across API-writable fields including products, recipes, stock, users, and chores.

Critical Impact

Authenticated attackers can inject persistent JavaScript through the API that executes in other users' browsers when affected records are rendered.

Affected Products

  • Grocy (open-source grocery and household management ERP)
  • API endpoints backed by BaseApiController.php
  • All fields written through GetParsedAndFilteredRequestBody (products, recipes, stock, users, chores, and related resources)

Discovery Timeline

  • 2026-08-05 - CVE-2026-71236 published to NVD
  • 2026-08-05 - Last updated in NVD database

Technical Details for CVE-2026-71236

Vulnerability Analysis

Grocy's API layer accepts JSON payloads and delegates sanitization to HTMLPurifier, a well-regarded HTML sanitization library. HTMLPurifier neutralizes script content by encoding dangerous characters as HTML entities such as <, >, and &. After purification completes, the request parser performs a manual string replacement that converts these entities back into their raw characters <, >, and &. The reversal undoes the exact protection HTMLPurifier applied, restoring executable markup that then persists to the database.

Because the tainted values are stored, any subsequent view that renders these fields without re-sanitization triggers script execution in the victim's browser session. The scope change reflected in the CVSS vector indicates that injected script executes in the browsing context of another authenticated user, enabling session compromise and privileged actions across the application.

Root Cause

The root cause is a post-sanitization transformation that inverts the sanitizer's output. HTMLPurifier is designed to emit entity-encoded content as its safe representation. Treating that encoded output as a display artifact to be decoded, rather than the intended safe form, defeats the sanitizer entirely. The pattern violates the principle that sanitizer output must be preserved verbatim before storage.

Attack Vector

An authenticated user with API write permissions submits a payload containing entity-encoded markup such as <script> sequences within any writable field. HTMLPurifier processes the payload and returns encoded output. The parser then decodes the entities back into <script> tags before persistence. When another user, including administrators, loads the affected product, recipe, or user record, the browser parses and executes the attacker-controlled JavaScript.

The vulnerability requires low-privilege authentication and user interaction, since the payload fires only when a victim views the affected record. Successful exploitation permits session token theft, forced state-changing requests through CSRF-style abuse, and lateral pivots within the application.

Detection Methods for CVE-2026-71236

Indicators of Compromise

  • API request bodies containing HTML-entity-encoded script sequences such as <script>, <img onerror=, or <svg onload= targeting Grocy write endpoints.
  • Database rows in products, recipes, stock_log, users, or chores tables containing raw <script>, <iframe>, or event-handler attributes.
  • Unexpected outbound requests from user browsers to attacker-controlled domains after viewing Grocy records.
  • Session anomalies such as new admin actions performed shortly after a low-privilege user submits API updates.

Detection Strategies

  • Inspect stored Grocy records for HTML tags and JavaScript event handlers in fields expected to hold plain text.
  • Deploy Web Application Firewall (WAF) rules that flag entity-encoded script payloads submitted to /api/ endpoints.
  • Correlate API write events with subsequent DOM-based script execution telemetry from browser endpoint agents.

Monitoring Recommendations

  • Log all authenticated POST, PUT, and PATCH requests to Grocy API paths with full request bodies for retrospective review.
  • Alert on Content Security Policy (CSP) violation reports originating from Grocy pages.
  • Monitor for privilege changes or new user accounts created shortly after suspicious API activity.

How to Mitigate CVE-2026-71236

Immediate Actions Required

  • Update Grocy to the latest release once a patched version addressing CVE-2026-71236 is available from the Grocy GitHub repository.
  • Restrict API access to trusted users and rotate API keys for any account whose write access is not strictly required.
  • Audit existing records in API-writable tables for stored HTML or script content and remediate affected rows.

Patch Information

Monitor the Grocy GitHub repository for a release that removes the manual entity-decoding step in GetParsedAndFilteredRequestBody within controllers/Api/BaseApiController.php. The fix must preserve HTMLPurifier's encoded output rather than reversing it before persistence.

Workarounds

  • Apply a local patch removing the <, >, and & string replacements that follow the HTMLPurifier call in BaseApiController.php.
  • Enforce a strict Content Security Policy that blocks inline script execution across the Grocy web interface.
  • Place Grocy behind an authenticating reverse proxy and limit API write scopes to administrative accounts until a patched release is deployed.
bash
# Example restrictive Content-Security-Policy header for a reverse proxy fronting Grocy
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'";

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.