Repository navigation
Fixed - Security: SQLi in datagrid, image-ZIP import RCE, installer takeover + hardening - #533
Merged
Merged
Conversation
…akeover + hardening - Validate locale/channel scope codes and escape JSON_EXTRACT path segments (SQLi, CWE-89) - Gate roles.store/roles.update/users.update mutator routes in ACL (authz bypass / priv-esc, CWE-862) - Per-entry image allowlist + MIME check on ZIP import extraction, preserve subfolders, zip-slip guard (stored XSS/RCE, CWE-434) - Persistent core_config install-completed flag + backfill migration; DB-populated guard on destructive install endpoints (unauth installer takeover, CWE-306) - Neutralize CSV/formula injection in export (skip numeric); throttle admin login; password min:8; remove forgot-password user enumeration
There was a problem hiding this comment.
Pull request overview
Security-focused hardening across Core/Admin/Installer/DataTransfer to close multiple reported vulnerabilities (SQL injection in DataGrids, unsafe ZIP image extraction, installer takeover, ACL route gaps, and auth/export hardening).
Changes:
- Prevent SQLi via request-supplied locale/channel by validating scope codes in
Coreand escaping JSON path segments in DB grammars (plus regression tests, including Playwright). - Seal installer endpoints using a persistent DB “installed” flag + backfill migration, and add additional guards on destructive installer steps (with feature tests).
- Harden import/export/auth flows: safe image-ZIP extraction, CSV/XLSX formula-injection neutralization, login/forgot-password throttling, stronger password rules, and non-enumerating forgot-password responses; add ACL entries/tests for mutator routes.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/e2e-pw/tests/08-security/category-locale-sqli.spec.js | Adds Playwright regression coverage for locale-driven SQLi against the category grid. |
| packages/Webkul/Installer/tests/Feature/InstallerSecurityTest.php | Updates test setup/teardown to clear the new persistent installer flag. |
| packages/Webkul/Installer/tests/Feature/InstallerDbStateGateTest.php | New test ensuring installer endpoints remain sealed when the storage marker is missing but DB indicates installed. |
| packages/Webkul/Installer/src/Http/Middleware/CanInstall.php | Treats installation as completed when either storage marker exists or DB flag indicates installed. |
| packages/Webkul/Installer/src/Http/Controllers/InstallerController.php | Adds DB-state guard to prevent destructive installer steps from being replayed on populated DBs; persists DB installed flag. |
| packages/Webkul/Installer/src/Helpers/DatabaseManager.php | Introduces persistent core_config “installer.installed” flag (read + write helpers). |
| packages/Webkul/Installer/src/Console/Commands/Installer.php | Ensures CLI installer also persists the DB installed flag. |
| packages/Webkul/DataTransfer/tests/Unit/Buffer/FileBufferFormulaInjectionTest.php | New unit tests for CSV/XLSX formula-injection neutralization logic. |
| packages/Webkul/DataTransfer/src/Buffer/FileBuffer.php | Implements formula-injection escaping for dangerous string cell prefixes while preserving numeric values. |
| packages/Webkul/Core/tests/Unit/ScopeCodeInjectionTest.php | Adds unit coverage for scope code validation and JSON path escaping in grammars. |
| packages/Webkul/Core/src/Helpers/Database/Grammars/PostgresGrammar.php | Escapes JSON path segments and int-casts order-by lists to reduce injection risk. |
| packages/Webkul/Core/src/Helpers/Database/Grammars/MySQLGrammar.php | Escapes JSON path segments and int-casts FIELD() order-by IDs to reduce injection risk. |
| packages/Webkul/Core/src/Database/Migrations/2026_07_01_000000_backfill_installer_installed_flag.php | Backfills the persistent installer-installed flag for already-installed instances. |
| packages/Webkul/Core/src/Core.php | Validates request locale/channel codes before using them in raw-SQL-building paths. |
| packages/Webkul/Admin/tests/Feature/DataTransfer/ImageZipImportSecurityTest.php | New feature tests for safe ZIP extraction (block scripts, preserve subfolders). |
| packages/Webkul/Admin/tests/Feature/Catalog/CategoryDataGridLocaleInjectionTest.php | New feature tests asserting locale payloads can’t inject into JSON_EXTRACT paths. |
| packages/Webkul/Admin/tests/Feature/Auth/PasswordPolicyAndEnumerationTest.php | New tests for min password length and forgot-password non-enumeration. |
| packages/Webkul/Admin/tests/Feature/Auth/LoginThrottleTest.php | New test verifying login throttle kicks in after repeated attempts. |
| packages/Webkul/Admin/tests/Feature/Acl/Settings/RoleUserAuthorizationTest.php | New tests ensuring mutator routes are ACL-gated (roles/users privilege escalation prevention). |
| packages/Webkul/Admin/src/Routes/auth-routes.php | Applies throttle middleware to login and forgot-password POST routes. |
| packages/Webkul/Admin/src/Http/Requests/UserForm.php | Enforces minimum password length for admin user create/update. |
| packages/Webkul/Admin/src/Http/Controllers/User/ResetPasswordController.php | Raises reset-password minimum length to 8. |
| packages/Webkul/Admin/src/Http/Controllers/User/ForgetPasswordController.php | Removes user enumeration by always responding with success messaging. |
| packages/Webkul/Admin/src/Http/Controllers/Settings/DataTransfer/ImportController.php | Replaces full ZIP extraction with allowlisted, MIME-checked per-entry extraction and zip-slip protections. |
| packages/Webkul/Admin/src/Config/acl.php | Adds missing ACL route mappings for mutator routes (store/update) for roles/users. |
- orderByField: quote non-numeric ids instead of int-casting them (both grammars) so string-keyed ordering still works - isMarkedInstalled: drop the .env-file check so the DB install flag still seals containerized/env-var deployments without a .env on disk - isFormulaValue: also escape values whose first non-whitespace char is a formula char (e.g. leading-space '=SUM(...)') - image-ZIP import: default max entry size to 15MB so the size cap no longer rejects every image when unset - CategoryDataGridLocaleInjectionTest: make JSON-path assertions dialect-agnostic (fixes PostgreSQL Pest failure)
This was referenced Jul 1, 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.
Issue Reference
Security fixes for SQL injection (CWE-89), image-ZIP import RCE/stored-XSS (CWE-434), unauthenticated installer takeover (CWE-306), plus authz and hardening findings.
Description
locale/channel: validate scope codes (/^[a-zA-Z0-9_-]+$/) inCore::getRequested{Locale,Channel}Code; escape single quotes inMySQLGrammar/PostgresGrammar::jsonExtractpath segments; int-castorderByFieldids.roles.store,roles.update,users.updatemutator routes, so any low-privilege admin could create an all-permission role or reassign their own role. Added the missingacl.phpentries.uploadImagesZipextracted all inner files into the public web root. NowextractImageEntrieskeeps only allowlisted image extensions with a real-MIME check, preserves subfolders, and blocks zip-slip.storage/installedmarker. Added a persistentcore_configinstall-completed flag (+ backfill migration for already-installed instances) and a DB-populated guard on the destructive endpoints.min:8; remove forgot-password user enumeration.How To Test This?
New regression tests cover every fix (unit + feature + a Playwright SQLi spec). All pass;
vendor/bin/pint --testclean.Documentation
Branch Selection
Pint
Passed (
vendor/bin/pint --test).Tailwind Reordering
N/A — no frontend/Blade class changes.