Grav Plugin Api
Monthly
JWT bearer token leakage in the Grav API Plugin for Grav CMS (prior to 1.0.0-rc.16) exposes valid access tokens to any party with access to server logs, proxy logs, CDN logs, browser history, or Referer headers. The JwtAuthenticator::extractBearerToken() method accepted tokens supplied via the ?token= URL query parameter on every /api/v1 route - including state-changing endpoints - rather than restricting token-in-URL to the file-download routes where it is technically necessary. An attacker who obtains a token from those secondary log sources can replay it with the full API privileges of the original token owner. No active exploitation (CISA KEV) or public exploit code has been identified at time of analysis.
Permissive CORS misconfiguration in the Grav API Plugin (all versions prior to 1.0.0-rc.16) allows cross-origin JavaScript on any attacker-controlled website to submit a stolen JWT via Authorization or X-API-Token headers and read full authenticated API responses, enabling data exfiltration and account modification with the token owner's privileges. The wildcard Access-Control-Allow-Origin: * header was returned by default for all /api/v1 endpoints - including authenticated ones - bypassing browser Same-Origin Policy protections entirely. A secondary vector existed via URL query-string token acceptance (?token=) on general API routes, leaking JWTs into server logs and Referer headers where they could be harvested and then weaponized via the CORS bypass. No public exploit code has been identified at time of analysis, and no CISA KEV listing is present.
Scope enforcement is entirely absent in the Grav API Plugin prior to 1.0.6, meaning any scoped API key silently exercises its issuing account's full permissions rather than the declared restricted subset. Holders of keys deliberately issued narrow read-only scopes - including third-party integrations and external services - can perform all write, delete, and administrative operations that the key's owning account is authorized for. No public exploit has been identified at time of analysis, but the vulnerability is exploitable by any valid API key holder over the network without user interaction, making supply-chain and insider-threat scenarios the primary risk vectors.
Privilege escalation in Grav API Plugin (all versions before 1.0.6) allows any authenticated user holding the api.users.write permission to mint API keys bound to super-administrator accounts, bypass key scope enforcement, and gain full persistent super-admin access - including the ability to rotate or disable two-factor authentication on targeted accounts. Three endpoints in UsersController - createApiKey(), generate2fa(), and disable2fa() - omitted the accessGrantsSuper() target authorization check that all sibling user mutation endpoints correctly enforced, creating an unguarded escalation path. No active exploitation has been confirmed (not in CISA KEV), and no public exploit code has been identified at time of analysis, though the fix commit is publicly visible and the attack path is structurally a single authenticated API call.
Server-Side Request Forgery in the Grav API plugin (grav-plugin-api) for Grav CMS before 1.0.6 lets a caller holding the api.webhooks.write permission register webhook URLs that the server dereferences with no protocol allow-listing. Because WebhookController.php validates the URL only with FILTER_VALIDATE_URL and WebhookDispatcher.php builds cURL without CURLOPT_PROTOCOLS/CURLOPT_REDIR_PROTOCOLS, an attacker can force the server to fetch file://, gopher://, dict://, and private/link-local targets, exfiltrating local files and internal HTTP responses including cloud metadata credentials. There is no public exploit identified at time of analysis and it is not in CISA KEV, but the root cause and fix are confirmed in the vendor advisory and commit.
Stored cross-site scripting in the Grav API Plugin (all versions prior to 1.0.2) allows an authenticated attacker holding api.media.write permission to upload a malicious SVG file whose embedded JavaScript executes in any victim's browser that opens the file. The upload pipeline in HandlesMediaUploads::processUploadedFile() checks the SVG filename extension but omits the Security::sanitizeSVG() call, so script content passes through unmodified and is later served as Content-Type: image/svg+xml, triggering browser-side execution. Successful exploitation enables session token theft and impersonation of the victim; no public exploit has been identified at time of analysis, and vendor-released patch version 1.0.2 is available.
Stored XSS in Grav CMS's grav-plugin-api (Admin2) allows a low-privileged editor to persist malicious JavaScript in page content via the PATCH /pages API endpoint, which then executes in any administrator's or visitor's browser when the affected page is loaded. The root cause is that the API's partial-field validation path (validateChangedFields()) ran only type and required-field checks but omitted the XSS safety gate (Validation::checkSafety()), a check the classic Admin interface correctly enforced - creating a trust-boundary bypass exclusive to the REST API path. Publicly available exploit code exists via the Fluid Attacks advisory and the vendor's own regression test suite; no active exploitation (CISA KEV) has been confirmed.
JWT bearer token leakage in the Grav API Plugin for Grav CMS (prior to 1.0.0-rc.16) exposes valid access tokens to any party with access to server logs, proxy logs, CDN logs, browser history, or Referer headers. The JwtAuthenticator::extractBearerToken() method accepted tokens supplied via the ?token= URL query parameter on every /api/v1 route - including state-changing endpoints - rather than restricting token-in-URL to the file-download routes where it is technically necessary. An attacker who obtains a token from those secondary log sources can replay it with the full API privileges of the original token owner. No active exploitation (CISA KEV) or public exploit code has been identified at time of analysis.
Permissive CORS misconfiguration in the Grav API Plugin (all versions prior to 1.0.0-rc.16) allows cross-origin JavaScript on any attacker-controlled website to submit a stolen JWT via Authorization or X-API-Token headers and read full authenticated API responses, enabling data exfiltration and account modification with the token owner's privileges. The wildcard Access-Control-Allow-Origin: * header was returned by default for all /api/v1 endpoints - including authenticated ones - bypassing browser Same-Origin Policy protections entirely. A secondary vector existed via URL query-string token acceptance (?token=) on general API routes, leaking JWTs into server logs and Referer headers where they could be harvested and then weaponized via the CORS bypass. No public exploit code has been identified at time of analysis, and no CISA KEV listing is present.
Scope enforcement is entirely absent in the Grav API Plugin prior to 1.0.6, meaning any scoped API key silently exercises its issuing account's full permissions rather than the declared restricted subset. Holders of keys deliberately issued narrow read-only scopes - including third-party integrations and external services - can perform all write, delete, and administrative operations that the key's owning account is authorized for. No public exploit has been identified at time of analysis, but the vulnerability is exploitable by any valid API key holder over the network without user interaction, making supply-chain and insider-threat scenarios the primary risk vectors.
Privilege escalation in Grav API Plugin (all versions before 1.0.6) allows any authenticated user holding the api.users.write permission to mint API keys bound to super-administrator accounts, bypass key scope enforcement, and gain full persistent super-admin access - including the ability to rotate or disable two-factor authentication on targeted accounts. Three endpoints in UsersController - createApiKey(), generate2fa(), and disable2fa() - omitted the accessGrantsSuper() target authorization check that all sibling user mutation endpoints correctly enforced, creating an unguarded escalation path. No active exploitation has been confirmed (not in CISA KEV), and no public exploit code has been identified at time of analysis, though the fix commit is publicly visible and the attack path is structurally a single authenticated API call.
Server-Side Request Forgery in the Grav API plugin (grav-plugin-api) for Grav CMS before 1.0.6 lets a caller holding the api.webhooks.write permission register webhook URLs that the server dereferences with no protocol allow-listing. Because WebhookController.php validates the URL only with FILTER_VALIDATE_URL and WebhookDispatcher.php builds cURL without CURLOPT_PROTOCOLS/CURLOPT_REDIR_PROTOCOLS, an attacker can force the server to fetch file://, gopher://, dict://, and private/link-local targets, exfiltrating local files and internal HTTP responses including cloud metadata credentials. There is no public exploit identified at time of analysis and it is not in CISA KEV, but the root cause and fix are confirmed in the vendor advisory and commit.
Stored cross-site scripting in the Grav API Plugin (all versions prior to 1.0.2) allows an authenticated attacker holding api.media.write permission to upload a malicious SVG file whose embedded JavaScript executes in any victim's browser that opens the file. The upload pipeline in HandlesMediaUploads::processUploadedFile() checks the SVG filename extension but omits the Security::sanitizeSVG() call, so script content passes through unmodified and is later served as Content-Type: image/svg+xml, triggering browser-side execution. Successful exploitation enables session token theft and impersonation of the victim; no public exploit has been identified at time of analysis, and vendor-released patch version 1.0.2 is available.
Stored XSS in Grav CMS's grav-plugin-api (Admin2) allows a low-privileged editor to persist malicious JavaScript in page content via the PATCH /pages API endpoint, which then executes in any administrator's or visitor's browser when the affected page is loaded. The root cause is that the API's partial-field validation path (validateChangedFields()) ran only type and required-field checks but omitted the XSS safety gate (Validation::checkSafety()), a check the classic Admin interface correctly enforced - creating a trust-boundary bypass exclusive to the REST API path. Publicly available exploit code exists via the Fluid Attacks advisory and the vendor's own regression test suite; no active exploitation (CISA KEV) has been confirmed.