Fix/server side template injection#260
Fix/server side template injection#260ranjanbagisto322 wants to merge 3 commits intounopim:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a Server-Side Template Injection (SSTI) vulnerability in the Export and Import functionality by implementing strict input validation on the code field. The PR also includes unannounced security improvements to the admin account profile update functionality, adding validation for the name field and enhanced file upload security for profile images.
Changes:
- Added regex validation
/^[a-zA-Z0-9_-]+$/to Export and Import code fields to prevent SSTI attacks - Enhanced AccountController with name field validation and redundant file upload validation
- Removed BMP image support from AccountController validation
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| packages/Webkul/Admin/src/Http/Controllers/Settings/DataTransfer/ExportController.php | Added regex validation to the 'code' field in the store method to prevent SSTI payloads |
| packages/Webkul/Admin/src/Http/Controllers/Settings/DataTransfer/ImportController.php | Added regex validation to the 'code' field in the store method to prevent SSTI payloads |
| packages/Webkul/Admin/src/Http/Controllers/User/AccountController.php | Added restrictive validation to 'name' field and manual file validation checks (not mentioned in PR description) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| $this->validate(request(), [ | ||
| 'code' => 'required|unique:job_instances,code', | ||
| 'code' => ['required', 'unique:job_instances,code', 'regex:/^[a-zA-Z0-9_-]+$/'], |
There was a problem hiding this comment.
The validation regex allows hyphens in the code field, but the existing Code validation rule (packages/Webkul/Core/src/Rules/Code.php) used throughout the codebase only allows alphanumeric characters and underscores: /^[a-zA-Z0-9_]+$/. This creates an inconsistency where Export/Import codes can contain hyphens, but other codes in the system (attributes, categories, channels, locales, etc.) cannot. This could lead to confusion and potential issues if code values are expected to be interchangeable or used in similar contexts.
|
|
||
| $this->validate(request(), [ | ||
| 'code' => 'required|unique:job_instances,code', | ||
| 'code' => ['required', 'unique:job_instances,code', 'regex:/^[a-zA-Z0-9_-]+$/'], |
There was a problem hiding this comment.
The SSTI protection is incomplete because the update method (not shown in this diff but at line 155 in the file) only validates that 'code' is 'required', without applying the same regex pattern used in the store method. This means an attacker could create an import with a safe code, then update it with a malicious SSTI payload. Consider also updating the validation in the update method to include the same regex pattern for comprehensive protection.
| $allowedExtensions = ['jpg', 'jpeg', 'png', 'webp', 'svg']; | ||
|
|
||
| if (! in_array(strtolower($uploadedFile->getClientOriginalExtension()), $allowedExtensions)) { | ||
| return back()->withErrors(['image' => 'Invalid file extension']); | ||
| } | ||
|
|
||
| $allowedMimeTypes = [ | ||
| 'image/jpeg', | ||
| 'image/png', | ||
| 'image/webp', | ||
| 'image/svg+xml' | ||
| ]; | ||
|
|
||
| if (! in_array($uploadedFile->getMimeType(), $allowedMimeTypes)) { | ||
| return back()->withErrors(['image' => 'Invalid file type']); | ||
| } | ||
|
|
There was a problem hiding this comment.
While adding the 'image' validation constraint is a security improvement, the manual validation logic at lines 80-96 is redundant. Laravel's built-in 'image' and 'mimes' validators already perform these checks. The getClientOriginalExtension() check can be bypassed by renaming files, and getMimeType() is already validated by Laravel. The ValidationRule 'FileMimeExtensionMatch' used in UserForm.php (line 60) provides a more comprehensive validation that checks both extension and MIME type consistency. Consider using that rule instead for consistency and to avoid code duplication.
| $allowedExtensions = ['jpg', 'jpeg', 'png', 'webp', 'svg']; | |
| if (! in_array(strtolower($uploadedFile->getClientOriginalExtension()), $allowedExtensions)) { | |
| return back()->withErrors(['image' => 'Invalid file extension']); | |
| } | |
| $allowedMimeTypes = [ | |
| 'image/jpeg', | |
| 'image/png', | |
| 'image/webp', | |
| 'image/svg+xml' | |
| ]; | |
| if (! in_array($uploadedFile->getMimeType(), $allowedMimeTypes)) { | |
| return back()->withErrors(['image' => 'Invalid file type']); | |
| } |
| 'password' => 'nullable|min:6|confirmed', | ||
| 'current_password' => 'required|min:6', | ||
| 'image.*' => 'nullable|mimes:bmp,jpeg,jpg,png,webp,svg', | ||
| 'image.*' => 'nullable|image|mimes:jpeg,jpg,png,webp,svg', |
There was a problem hiding this comment.
The validation rule has removed 'bmp' from the allowed image types compared to the original validation, but there's no explanation for this change in the PR description. If 'bmp' support removal is intentional for security reasons, it should be documented. If this is unintentional, it could break existing functionality for users who previously uploaded BMP images.
|
|
||
| $this->validate(request(), [ | ||
| 'name' => 'required', | ||
| 'name' => ['required', 'string', 'max:255', 'regex:/^[a-zA-Z0-9\s]+$/'], |
There was a problem hiding this comment.
The regex pattern for the 'name' field is too restrictive and inconsistent with the codebase's existing convention. The codebase has a dedicated AlphaNumericSpace validation rule (in packages/Webkul/Core/src/Rules/AlphaNumericSpace.php) that allows not only alphanumeric characters and spaces but also apostrophes and Arabic characters using the pattern /^[a-zA-Z0-9\s'\s\p{Arabic}]{1,60}$/iu. This is used in UserForm for validating user names elsewhere in the system. The current regex /^[a-zA-Z0-9\s]+$/ would reject legitimate names with apostrophes (e.g., "O'Brien") or non-Latin characters, creating an inconsistent user experience.
| 'name' => ['required', 'string', 'max:255', 'regex:/^[a-zA-Z0-9\s]+$/'], | |
| 'name' => ['required', 'string', 'max:255', 'regex:/^[a-zA-Z0-9\s\'\p{Arabic}]+$/iu'], |
| @@ -76,9 +76,28 @@ | |||
| } | |||
|
|
|||
| if (request()->hasFile('image')) { | |||
|
|
|||
| $uploadedFile = current(request()->file('image')); | |||
| $allowedExtensions = ['jpg', 'jpeg', 'png', 'webp', 'svg']; | |||
|
|
|||
| if (! in_array(strtolower($uploadedFile->getClientOriginalExtension()), $allowedExtensions)) { | |||
| return back()->withErrors(['image' => 'Invalid file extension']); | |||
| } | |||
|
|
|||
| $allowedMimeTypes = [ | |||
| 'image/jpeg', | |||
| 'image/png', | |||
| 'image/webp', | |||
| 'image/svg+xml' | |||
| ]; | |||
|
|
|||
| if (! in_array($uploadedFile->getMimeType(), $allowedMimeTypes)) { | |||
| return back()->withErrors(['image' => 'Invalid file type']); | |||
| } | |||
|
|
|||
| $data['image'] = $this->fileStorer->store( | |||
| path: 'admins'.DIRECTORY_SEPARATOR.$user->id, | |||
| file: current(request()->file('image')) | |||
| file: $uploadedFile | |||
There was a problem hiding this comment.
The changes to AccountController.php are not mentioned in the PR description, which states that the code paths are only ExportController.php and ImportController.php. This creates a discrepancy between the PR description and the actual changes. While the security improvements in AccountController are valuable, they appear to be addressing a different vulnerability (file upload validation and name field injection) rather than the SSTI vulnerability described in the PR.
|
|
||
| $this->validate(request(), [ | ||
| 'code' => 'required|unique:job_instances,code', | ||
| 'code' => ['required', 'unique:job_instances,code', 'regex:/^[a-zA-Z0-9_-]+$/'], |
There was a problem hiding this comment.
The validation regex allows hyphens in the code field, but the existing Code validation rule (packages/Webkul/Core/src/Rules/Code.php) used throughout the codebase only allows alphanumeric characters and underscores: /^[a-zA-Z0-9_]+$/. This creates an inconsistency where Export/Import codes can contain hyphens, but other codes in the system (attributes, categories, channels, locales, etc.) cannot. This could lead to confusion and potential issues if code values are expected to be interchangeable or used in similar contexts.
Issue Reference
Security Fix – Server Side Template Injection (SSTI) in Export Code Field
Fixes #260
Description
This PR fixes a Server-Side Template Injection (SSTI) vulnerability identified in the Export → Code input field.
Previously, it was possible to inject a malicious SSTI payload into the Code field. Upon saving, the payload was interpreted and executed by the template engine, confirming the existence of SSTI.
Root Cause
Fix Applied
Code path :
packages/Webkul/Admin/src/Http/Controllers/Settings/DataTransfer/ExportController.php
packages/Webkul/Admin/src/Http/Controllers/Settings/DataTransfer/ImportController.php
This prevents execution of malicious template expressions and mitigates potential Remote Code Execution (RCE) risks.
How To Test This?
Expected Result: