X Tutup
Skip to content

Fix/server side template injection#260

Open
ranjanbagisto322 wants to merge 3 commits intounopim:masterfrom
ranjanbagisto322:fix/Server-Side-Template-Injection
Open

Fix/server side template injection#260
ranjanbagisto322 wants to merge 3 commits intounopim:masterfrom
ranjanbagisto322:fix/Server-Side-Template-Injection

Conversation

@ranjanbagisto322
Copy link

@ranjanbagisto322 ranjanbagisto322 commented Feb 20, 2026

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

  • User input from the Export Code field was being processed/rendered without proper validation.
  • Dynamic template evaluation allowed execution of injected expressions.
  • Lack of strict input sanitization before rendering.

Fix Applied

Code path :

packages/Webkul/Admin/src/Http/Controllers/Settings/DataTransfer/ExportController.php
packages/Webkul/Admin/src/Http/Controllers/Settings/DataTransfer/ImportController.php

  • Implemented strict input validation for the Export Code field.
  • Prevented dynamic template compilation using untrusted input.
  • Sanitized user input before rendering.
  • Restricted execution of arbitrary template expressions.
  • Ensured only expected/static values are processed.
    This prevents execution of malicious template expressions and mitigates potential Remote Code Execution (RCE) risks.

How To Test This?

  • Go to Export section.
  • In the Code input field, enter an SSTI payload ({{7*7}}).
  • Click Save.

Expected Result:

  • The payload should NOT execute.
  • The system should either reject the input or store it as plain text.
  • No template expression should be evaluated.
  • Normal export functionality should continue to work properly.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_-]+$/'],
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.

$this->validate(request(), [
'code' => 'required|unique:job_instances,code',
'code' => ['required', 'unique:job_instances,code', 'regex:/^[a-zA-Z0-9_-]+$/'],
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +97
$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']);
}

Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
$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']);
}

Copilot uses AI. Check for mistakes.
'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',
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.

$this->validate(request(), [
'name' => 'required',
'name' => ['required', 'string', 'max:255', 'regex:/^[a-zA-Z0-9\s]+$/'],
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
'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'],

Copilot uses AI. Check for mistakes.
Comment on lines 42 to +100
@@ -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
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.

$this->validate(request(), [
'code' => 'required|unique:job_instances,code',
'code' => ['required', 'unique:job_instances,code', 'regex:/^[a-zA-Z0-9_-]+$/'],
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

X Tutup