Add CVE-2026-3576 - Planyo Online Reservation System <= 3.0 - Arbitrary File Read - #16899
Merged
Merged
Conversation
…ry File Read ulap.php is reachable without WordPress bootstrapping or authentication and validates only the host of the supplied URL, never the scheme, so a file://localhost/ URL passes the allowlist and is read back through the file:// wrapper. Detection is a single unauthenticated GET matched on the /etc/passwd oracle. A patched 3.1 install still answers 200 with an error body, so the status code alone is not a discriminator and the regex carries the match.
ritikchaddha
approved these changes
Aug 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Information
<= 3.0Arbitrary File Read (http/cves/2026/CVE-2026-3576.yaml)ulap.php, an "Ultra Light AJAX Proxy" that is served directly and never bootstraps WordPress, so there is no nonce, capability check or authentication of any kind.send_http_post()parses the supplied URL and validates only the host against an allowlist that includeslocalhost, but it never validates the scheme. Afile://localhost/...URL therefore passes the host check and is handed tocurl_init()/fopen(), both of which honour thefile://wrapper, returning arbitrary local file contents in the response body. All versions up to and including3.0are affected. This is fixed in3.1, which added an explicithttp/httpsscheme check.GETand performs no writes, no state change and no uploads.Template validation
wordpress:php8.2-apachewith plugintags/2.9wordpress:php8.2-apachewith plugintags/3.1Additional Details
Lab (official WordPress image, plugin dropped in from the plugin SVN):
True Positive (plugin 2.9):
True Negative (plugin 3.1, patched):
Note for reviewers: the patched build still returns HTTP 200, with the body
Error: Only HTTP(S) URLs are allowed. A status-only matcher would therefore false-positive on every patched install. Theroot:[x*]?:0:0:regex is the load-bearing condition, combined withcontent_typeand status undercondition: and.Additional negative controls, all confirmed non-matching:
200Error: Only HTTP(S) URLs are allowed302404file://evil/etc/passwd200Error: Call to ... not allowedulap_urlparameter200, 0 bytesA note on the template shape: most recent WordPress plugin templates gate the exploit behind a
readme.txtversion check. That is not usable here, because this plugin publishesStable tag: trunkinreadme.txton tags 2.6, 2.9 and 3.1, socompare_versionswould extract nothing and the template would never fire. The/etc/passwdoracle is conclusive on its own, so the template stays at a single request.Classification follows the NVD record exactly, including
CWE-20and theS:C/C:L/I:L7.2 vector. Those are Wordfence secondary metrics, as the record carries no NVD primary score and no CPE block.Discovery queries:
body="/plugins/planyo-online-reservation-system/"Additional References: