Security incident · CVE-2026-72701
Grav: Non constant time nonce comparison in Utils::verifyNonce() used for CSRF protection
Published Sep 17, 2026 · catalog updated Oct 26, 2026 · Grav: Non constant time
Last checked Oct 29, 2026. A connected source was read within the last 7 days.
Check if you run it
No confirmed exploitation is on record for CVE-2026-72701. EPSS is 0.22%. Act only if a listed version of Grav: Non constant time is installed.
Gaps on this record
- The stored product name is a package slug. The name on this page is taken from the title (Grav: Non constant time).
- No vendor fix or required action is stored. Compare the linked advisory before you change production.
- Severity
- Low3.7
- Known exploitation
- Not in CISA/VulnCheck KEV
- EPSS
- 0.22%
- Remediation
- Advisory link
- Affected products
- Packagist getgrav/grav
## Summary , the core function Grav and its plugins use to validate CSRF nonces, compares the submitted nonce to the expected value with PHP's operator instead of . on strings short circuits at the first differing byte, so the comparison time leaks how many leading bytes of a guess are correct. This is CWE-208, Observable Timing Discrepancy. The codebase already knows to avoid this pattern. is used for the equivalent purpose in four other places I found: , , (the webhook token check), and . is the one place I found that still uses a plain equality check for a secret comparison. ## Affected product and version Product: Grav CMS, getgrav/grav Confirmed present in: 2.0.15, commit c2b46866857a93a0aa7048e7ed707ed3ed45dbc3 ## Affected code , lines 1512 to 1521: The nonce itself is , computed in the private a few lines above. is an installation level secret. So the value being compared with is a value derived from a secret, which is exactly the case exists for. ## Proof of concept, verified, real output I could not exploit this end to end over a real network from this sandbox, since that requires a live deployment and a timing measurement setup outside a single machine. What I did verify directly, by running real code, is that the underlying primitive this function relies on, PHP's string comparison, is not constant time in the PHP build actually used here, and that a measurable timing signal is still present at the exact length Grav's nonces have, 32 hex characters, an md5 digest. Step 1, confirm PHP build: Step 2, benchmark script, measures the median time of over many trials, once with a long string to establish a clean signal, once at the real 32 byte nonce length: Step 3, run it three times to confirm the result is reproducible and not noise: Actual output, run 1: Actual output, run 2: Actual output, run 3: Interpretation, stated honestly. At 4096 bytes the effect is unambiguous and consistent across three independent runs, a mismatch near the end of the string takes
Are you affected?
Enter the version you run. The result uses only the ranges stored on this record.
The check returns affected, not affected, or incomplete. It does not guess a version that is missing from the record.
- Packagist getgrav/grav0 → 2.0.16
How to fix CVE-2026-72701
Upgrade
CVE-2026-72701 lists a fix boundary at 2.0.16. Compare the installed build with that boundary before you change production.
Version check
Fixed in 2.0.16
Advisory
Open the cve_org record and follow its fix.
Official advisories
What to do
Three questions, each answered from this record only. Confirm the vendor advisory before you patch.
Should you patch?
No confirmed exploitation is on record for CVE-2026-72701. EPSS is 0.22%. Act only if a listed version of Grav: Non constant time is installed.
Which versions are affected?
Compare what you have installed with 0 → 2.0.16. Compare the installed version with the linked vendor advisory before you change production.
What should an analyst verify?
CWE-208. EPSS 0.22%. There is no CISA KEV listing. No Exploit-DB or Metasploit reference is linked. Use the source links for the original advisory.
Code
The project this record applies to. Exploit listings stay in References.
Timeline
Detection, updates, and resolution for this record.
Sep 17, 2026 · GitHub Advisory Database
Detected
## Summary , the core function Grav and its plugins use to validate CSRF nonces, compares the submitted nonce to the expected value with PHP's operator instead of . on strings short circuits at the first differing byte, so the comparison time leaks how many leading bytes of a guess are correct. This is CWE-208, Observable Timing Discrepancy. The codebase already knows to avoid this pattern. is use
Oct 26, 2026 · GitHub Advisory Database
Fix available
getgrav/grav fixed in 2.0.16
Oct 26, 2026 · GitHub Advisory Database
Fix available
getgrav/grav fixed in 2.0.16
Oct 26, 2026 · GitHub Advisory Database
Updated
## Summary , the core function Grav and its plugins use to validate CSRF nonces, compares the submitted nonce to the expected value with PHP's operator instead of . on strings short circuits at the first differing byte, so the comparison time leaks how many leading bytes of a guess are correct. This is CWE-208, Observable Timing Discrepancy. The codebase already knows to avoid this pattern. is use
Sources
- CVE.orgVulnerability recordCVE-2026-72701
Official CVE identifier
cve.org - GitHub Advisory DatabasePackage advisoryGHSA-38p6-h87p-r4cg
GitHub Advisory Database record mirrored by OSV.
github.com - OpenSSF OSV / OSV ScannerPackage advisoryGHSA-38p6-h87p-r4cg
Grav: Non constant time nonce comparison in Utils::verifyNonce() used for CSRF protection
osv.dev
References
Freshness
Last verified in this catalog Oct 29, 2026. Significant claims (KEV, EPSS, CVSS, affected ranges) come from the source rows above — open the original publisher for the authoritative advisory.
- CVE.orgOct 27, 2026
- GitHub Advisory DatabaseOct 26, 2026
- OpenSSF OSV / OSV ScannerOct 26, 2026