Repository navigation
Conversation
QA suite — failed ❌1 of 2 checks failed. The rest passed. 0 passed · 1 failed · 1 skipped · 0 flaky · 68s What failed1. authenticateWhat should happen: Logged in as "admin" at http://127.0.0.1:9400 but wp-admin never rendered, with no login error and no PHP fatal on the page. This was retried 1 time and failed every time. 1 screenshot and 1 trace of this failure are in the report linked at the bottom. Technical detailLocation: Likely cause: the element never appeared, so the test gave up waiting for it. Check the selector at tests/e2e/auth.setup.ts:108. Either this change altered the markup it looks for, or the page needs a state (a menu, a widget, demo content) that a fresh site never seeds. See it for yourselfDownload the full report ( Replaying a failure step by step (developers)The archive also carries a Playwright trace — every click, the page at each step, network and console. From the unzipped folder: It needs that command rather than opening the file directly: a trace viewer cannot start from a Automated check — no AI involved. It runs the tests in this branch. |
There was a problem hiding this comment.
🟢 Approval recommended
The focused changes address the documented bypass, and no unresolved issues were identified.
0 open findings
What changed in this PR
This PR closes the described unauthenticated upload restriction bypass in Everest Forms’ upload handlers.
Changes:
- Rejects field IDs that do not identify an upload field in the submitted form.
- Adds HTML-related extensions to the upload blacklist.
| File | Description |
|---|---|
includes/abstracts/class-evf-form-fields-upload.php |
Validates upload field IDs and expands the extension blacklist. |
🧠 Review effort: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
@saurab018 Please verify the PR |
|
Build for ⬇️ Download everest-forms.zip (11M) Installs directly via Plugins → Add New → Upload Plugin. A later push only rebuilds this if its commit message includes |
|
CI note:
I ran phpcs locally on the changed file. There are no new violations: 83 findings before and after, none on the changed lines. I'm leaving the CI changes out of this security fix. They need a separate PR to bump the cache action and regenerate |
All Submissions:
Changes proposed in this Pull Request:
Security fix for an unauthenticated upload restriction bypass reported via Global Payments' bug bounty (internal ref: themegrill/everest-forms-pro#1232).
Root cause
wp_ajax_nopriv_everest_forms_upload_fileis public by design (front-end forms).ajax_validate_form_field()only verified that the form exists and is published, and never that the submittedfield_idbelongs to that form. With a non-existentfield_id,$this->field_datawas empty, so the field's "Allowed File Extensions" list was skipped andget_extensions()fell back to all WordPress-allowed types minus$blacklist.$blacklisthadhtmbut nothtml, so an.htmlfile was accepted intouploads/everest_forms_uploads/tmp/and served from the site origin (stored XSS).Fix
ajax_validate_form_field()now rejects the request unlessfield_idexists in the form and is of typefile-uploadorimage-upload. This also coversremove_file.html,xhtml,shtml,phtmlto$blacklistas defense in depth.Closes # .
How to test the changes in this Pull Request:
Setup: create a published form with a File Upload field restricted to
pdf,jpg(note its field id from the form markup, e.g.abc-1) and its form id..jpgthrough the field. Expected: succeeds, and the file appears inwp-content/uploads/everest_forms_uploads/tmp/.curl -F action=everest_forms_upload_file -F form_id=<ID> -F field_id=<REAL_FIELD_ID> -F file=@test.html http://site/wp-admin/admin-ajax.phpExpected:
File type is not allowed.field_id=does-not-exist. Expected:Something went wrong, please try again.(success:false), and no file intmp/. Before the fix this returned a URL-able.htmlfile.field_idof a non-upload field in the same form (e.g. a text field). Expected: rejected.test.html. Expected:File type is not allowed.everest_forms_remove_filecall with a bogusfield_id. Expected: rejected..png. Expected: succeeds.Types of changes:
Other information:
Note: the image-upload field does not enforce the image-only type list server-side when no extensions are set (client-side only). Out of scope here; may be a follow-up.
Changelog entry