Skip to content

Instantly share code, notes, and snippets.

@pyuysig
Last active June 13, 2026 15:42
Show Gist options
  • Select an option

  • Save pyuysig/92e631298ec28d3e6967ad1f2038e75d to your computer and use it in GitHub Desktop.

Select an option

Save pyuysig/92e631298ec28d3e6967ad1f2038e75d to your computer and use it in GitHub Desktop.
Reference for CVE-2026-50890

Summary

grocy 4.6.0 concatenates the authenticated product-group query parameter into the stock spending report SQL when group-by=product is used. A logged-in user can inject SQL into the report query path.

Details

StockReportsController::Spendings handles /stockreports/spendings. When group-by=product and product-group is neither all nor ungrouped, the controller appends the submitted product-group value into the SQL WHERE clause instead of validating it as a product group identifier or binding it as a parameter.

The resulting SQL reaches Grocy\Services\DatabaseService::ExecuteDbQuery(). In the audited path, the raw SQL is executed before query results are fetched, so attacker-controlled SQL can affect the report query.

A previously explored custom include code-execution chain was not confirmed on the current target. Exact custom_js.html and custom_css.html attachment attempts hit file is not a database errors, so this advisory is limited to the confirmed SQL injection boundary.

PoC

  1. Log in to grocy 4.6.0 with a normal authenticated account.
  2. Request /stockreports/spendings?group-by=product and note the normal report behavior for a valid product-group value.
  3. Repeat the request with a crafted product-group value that terminates the pg.id = ... expression and adds a SQLite read probe such as sqlite_version() or pragma_database_list in the report query.
  4. Observe the report output or database error change according to the injected SQL, including returned SQLite version or database path data in the validated probe.
  5. Confirm that the proof stops at SQL injection on the current target because the custom include write path returns file is not a database.

Impact

The observed result is authenticated SQL injection in the stock spending report. A logged-in attacker can read or alter data reachable by the application's SQLite connection, subject to database permissions and the exact injected statement behavior. Code execution through the custom include path was not confirmed on the current target.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment