FIX_FILE_GUARD_IMPROVED
This commit is contained in:
parent
4a7c9af8db
commit
cab1886249
@ -10,43 +10,62 @@ use finfo;
|
||||
|
||||
class GlobalPostFileUploadGuard implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* Max file size (in bytes) → 25MB
|
||||
*/
|
||||
protected int $maxFileSize = 25 * 1024 * 1024;
|
||||
|
||||
/**
|
||||
* Allowed MIME types mapped to extensions
|
||||
*/
|
||||
protected array $allowedMimeMap = [
|
||||
'image/jpeg' => ['jpg', 'jpeg'],
|
||||
'image/png' => ['png'],
|
||||
'image/gif' => ['gif'],
|
||||
'image/webp' => ['webp'],
|
||||
'image/svg+xml' => ['svg'],
|
||||
// SVG removed — dangerous without server-side sanitization
|
||||
'application/pdf' => ['pdf'],
|
||||
'application/msword' => ['doc'],
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => ['docx'],
|
||||
'application/vnd.oasis.opendocument.text' => ['odt'],
|
||||
'text/rtf' => ['rtf'],
|
||||
'text/rtf' => ['rtf'],
|
||||
'application/rtf' => ['rtf'],
|
||||
'application/vnd.ms-excel' => ['xls'],
|
||||
'application/vnd.ms-excel' => ['xls'], // removed xlsx from here — it has its own MIME
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => ['xlsx'],
|
||||
'application/vnd.oasis.opendocument.spreadsheet' => ['ods'],
|
||||
'text/csv' => ['csv'],
|
||||
'text/csv' => ['csv'],
|
||||
'application/csv' => ['csv'],
|
||||
'text/plain' => ['txt', 'csv'],
|
||||
'text/plain' => ['txt'], // separated csv out — txt only
|
||||
];
|
||||
|
||||
protected array $magicBytes = [
|
||||
'image/jpeg' => ["\xFF\xD8\xFF"],
|
||||
'image/png' => ["\x89PNG\r\n\x1a\n"],
|
||||
'image/gif' => ["GIF87a", "GIF89a"],
|
||||
'image/webp' => ["RIFF"],
|
||||
'application/pdf' => ["%PDF-"],
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => ["PK\x03\x04"],
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => ["PK\x03\x04"],
|
||||
'application/vnd.oasis.opendocument.text' => ["PK\x03\x04"],
|
||||
'application/vnd.oasis.opendocument.spreadsheet' => ["PK\x03\x04"],
|
||||
'application/msword' => ["\xD0\xCF\x11\xE0"],
|
||||
'application/vnd.ms-excel' => ["\xD0\xCF\x11\xE0"],
|
||||
];
|
||||
|
||||
protected array $blockedExtensions = [
|
||||
'php', 'phtml', 'html', 'pht', 'phar', 'php3', 'php4', 'php5', 'php7', 'php8', 'phps',
|
||||
'cgi', 'fcgi', 'pl', 'py', 'rb', 'lua', 'tcl', 'go', 'rs', 'jar', 'class',
|
||||
'exe', 'dll', 'com', 'bat', 'cmd', 'msi', 'vbs', 'ps1', 'scr',
|
||||
'sh', 'bash', 'zsh', 'apk', 'app', 'deb', 'rpm', 'bin', 'run',
|
||||
'js', 'mjs', 'jsp', 'asp', 'aspx', 'cer', 'swf',
|
||||
'env', 'ini', 'user.ini', 'htaccess', 'htpasswd', 'conf', 'config', 'log', 'sql',
|
||||
'zip', 'rar', '7z', 'tar', 'gz', 'bz2', 'xz', 'iso',
|
||||
'lnk', 'url', 'reg', 'sys', 'drv', 'vxd', 'tmp', 'bak', 'old', 'backup', 'key', 'pem'
|
||||
'php', 'phtml', 'html', 'htm', 'pht', 'phar',
|
||||
'php3', 'php4', 'php5', 'php7', 'php8', 'phps',
|
||||
'cgi', 'fcgi', 'pl', 'py', 'rb', 'lua', 'tcl',
|
||||
'go', 'rs', 'jar', 'class',
|
||||
'exe', 'dll', 'com', 'bat', 'cmd', 'msi',
|
||||
'vbs', 'ps1', 'ps2', 'scr', 'hta',
|
||||
'sh', 'bash', 'zsh', 'fish',
|
||||
'apk', 'app', 'deb', 'rpm',
|
||||
'bin', 'run', 'elf',
|
||||
'js', 'mjs', 'ts', 'jsx', 'tsx',
|
||||
'jsp', 'jspx', 'asp', 'aspx', 'ascx', 'ashx', 'axd',
|
||||
'cer', 'swf', 'xhtml',
|
||||
'env', 'ini', 'user.ini', 'htaccess', 'htpasswd',
|
||||
'conf', 'config', 'log', 'sql', 'db', 'sqlite',
|
||||
'zip', 'rar', '7z', 'tar', 'gz', 'bz2', 'xz', 'iso', 'cab',
|
||||
'lnk', 'url', 'reg', 'sys', 'drv', 'vxd',
|
||||
'tmp', 'bak', 'old', 'backup',
|
||||
'key', 'pem', 'p12', 'pfx', 'crt', 'csr',
|
||||
'xml', 'xsl', 'xslt', 'svg',
|
||||
];
|
||||
|
||||
public function before(RequestInterface $request, $arguments = null)
|
||||
@ -68,8 +87,8 @@ class GlobalPostFileUploadGuard implements FilterInterface
|
||||
private function validateFileInput($fileData, string $inputName): void
|
||||
{
|
||||
if (is_array($fileData)) {
|
||||
foreach ($fileData as $file) {
|
||||
$this->validateSingleFile($file, $inputName);
|
||||
foreach ($fileData as $key => $item) {
|
||||
$this->validateFileInput($item, $inputName . '[' . $key . ']');
|
||||
}
|
||||
} else {
|
||||
$this->validateSingleFile($fileData, $inputName);
|
||||
@ -78,7 +97,7 @@ class GlobalPostFileUploadGuard implements FilterInterface
|
||||
|
||||
private function validateSingleFile($file, string $inputName): void
|
||||
{
|
||||
$request = Services::request();
|
||||
$request = Services::request();
|
||||
$clientIp = $request->getIPAddress();
|
||||
$uri = $request->getUri()->getPath();
|
||||
|
||||
@ -86,45 +105,211 @@ class GlobalPostFileUploadGuard implements FilterInterface
|
||||
if ($file->getError() === UPLOAD_ERR_INI_SIZE || $file->getError() === UPLOAD_ERR_FORM_SIZE) {
|
||||
$this->block("File exceeds server-side size limit", $clientIp, $uri, $inputName, $file->getClientName(), 'unknown', 'unknown', 0);
|
||||
}
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
$originalName = $file->getClientName();
|
||||
$extension = strtolower($file->getExtension());
|
||||
$mime = $file->getMimeType();
|
||||
$size = $file->getSize();
|
||||
$originalName = $file->getClientName();
|
||||
$clientExtension = strtolower($file->getClientExtension());
|
||||
$tempPath = $file->getTempName();
|
||||
$size = $file->getSize();
|
||||
|
||||
// --- 1. Fixed Null Byte & Path Traversal Check ---
|
||||
if (preg_match('/\0|[\/\\\]/', $originalName)) {
|
||||
$this->block("Malicious filename characters", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
// echo $file->getExtension();
|
||||
// echo '@@@@@@@@@@@@@@@@@@@@@@@';
|
||||
// echo $file->getMimeType();
|
||||
// --- 1. Null Byte & Path Traversal Check ---
|
||||
if (preg_match('/\0|[\/\\\\]/', $originalName)) {
|
||||
$this->block("Malicious filename characters", $clientIp, $uri, $inputName, $originalName, 'unknown', $clientExtension, $size);
|
||||
}
|
||||
|
||||
// --- 2. Double Extension Attack Check ---
|
||||
if (preg_match('/\.(php|phtml|html|phar|exe|sh|bat|cmd|js|jsp|asp|aspx|py|pl)\./i', $originalName)) {
|
||||
$this->block("Double extension attack", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
// --- 2. Filename length check ---
|
||||
if (strlen($originalName) > 255) {
|
||||
$this->block("Filename too long", $clientIp, $uri, $inputName, substr($originalName, 0, 100) . '...', 'unknown', $clientExtension, $size);
|
||||
}
|
||||
|
||||
// --- 3. Forbidden Extension ---
|
||||
if (in_array($extension, $this->blockedExtensions, true)) {
|
||||
$this->block("Forbidden extension", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
// --- 3. Double/Multiple Extension Attack ---
|
||||
$nameParts = explode('.', $originalName);
|
||||
if (count($nameParts) > 2) {
|
||||
$allExtensions = array_slice($nameParts, 1);
|
||||
foreach ($allExtensions as $part) {
|
||||
if (in_array(strtolower($part), $this->blockedExtensions, true)) {
|
||||
$this->block("Double/multiple extension attack detected", $clientIp, $uri, $inputName, $originalName, 'unknown', $clientExtension, $size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- 4. File Size Limit ---
|
||||
// --- 4. Forbidden Extension ---
|
||||
if (in_array($clientExtension, $this->blockedExtensions, true)) {
|
||||
$this->block("Forbidden extension", $clientIp, $uri, $inputName, $originalName, 'unknown', $clientExtension, $size);
|
||||
}
|
||||
|
||||
// --- 5. File Size Limit ---
|
||||
if ($size > $this->maxFileSize) {
|
||||
$this->block("File too large", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
$this->block("File too large", $clientIp, $uri, $inputName, $originalName, 'unknown', $clientExtension, $size);
|
||||
}
|
||||
|
||||
// --- 5. MIME Allow-list Check ---
|
||||
if (!array_key_exists($mime, $this->allowedMimeMap)) {
|
||||
$this->block("MIME type not allowed ($mime)", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
// --- 6. Real MIME Detection via finfo on actual temp file ---
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$detectedMime = $finfo->file($tempPath);
|
||||
|
||||
// --- 7. Resolve Expected MIME From Extension ---
|
||||
$expectedMime = null;
|
||||
|
||||
foreach ($this->allowedMimeMap as $mime => $extensions) {
|
||||
|
||||
if (in_array($clientExtension, $extensions, true)) {
|
||||
$expectedMime = $mime;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// --- 6. MIME-Extension Consistency ---
|
||||
if (!in_array($extension, $this->allowedMimeMap[$mime], true)) {
|
||||
$this->block("MIME-extension mismatch", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
if ($expectedMime === null) {
|
||||
$this->block(
|
||||
"Extension not allowed",
|
||||
$clientIp,
|
||||
$uri,
|
||||
$inputName,
|
||||
$originalName,
|
||||
$detectedMime,
|
||||
$clientExtension,
|
||||
$size
|
||||
);
|
||||
}
|
||||
|
||||
// --- 8. Magic Bytes Deep Validation ---
|
||||
// validate using EXPECTED MIME instead of detected MIME
|
||||
$this->validateMagicBytes(
|
||||
$tempPath,
|
||||
$expectedMime,
|
||||
$clientIp,
|
||||
$uri,
|
||||
$inputName,
|
||||
$originalName,
|
||||
$clientExtension,
|
||||
$size
|
||||
);
|
||||
|
||||
// // --- 9. Embedded Code Scan ---
|
||||
// $this->scanForEmbeddedCode(
|
||||
// $tempPath,
|
||||
// $expectedMime,
|
||||
// $clientIp,
|
||||
// $uri,
|
||||
// $inputName,
|
||||
// $originalName,
|
||||
// $clientExtension,
|
||||
// $size
|
||||
// );
|
||||
|
||||
// --- 10. Final MIME Validation ---
|
||||
// strict match only: generic octet-stream is not accepted
|
||||
if ($detectedMime !== $expectedMime) {
|
||||
$this->block(
|
||||
"MIME-extension mismatch",
|
||||
$clientIp,
|
||||
$uri,
|
||||
$inputName,
|
||||
$originalName,
|
||||
$detectedMime,
|
||||
$clientExtension,
|
||||
$size
|
||||
);
|
||||
}
|
||||
|
||||
// --- 10. Embedded Code Scan ---
|
||||
// $this->scanForEmbeddedCode($tempPath, $detectedMime, $clientIp, $uri, $inputName, $originalName, $clientExtension, $size);
|
||||
}
|
||||
|
||||
private function validateMagicBytes(
|
||||
string $tempPath,
|
||||
string $mime,
|
||||
string $ip,
|
||||
string $uri,
|
||||
string $field,
|
||||
string $filename,
|
||||
string $ext,
|
||||
int $size
|
||||
): void {
|
||||
if (!isset($this->magicBytes[$mime])) {
|
||||
return;
|
||||
}
|
||||
// echo $mime;print_r($this->magicBytes[$mime]);
|
||||
$handle = fopen($tempPath, 'rb');
|
||||
if (!$handle) {
|
||||
$this->block("Cannot read uploaded file", $ip, $uri, $field, $filename, $mime, $ext, $size);
|
||||
}
|
||||
|
||||
$header = fread($handle, 12);
|
||||
fclose($handle);
|
||||
|
||||
$matched = false;
|
||||
foreach ($this->magicBytes[$mime] as $signature) {
|
||||
if (str_starts_with($header, $signature)) {
|
||||
$matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// echo $matched;die;
|
||||
// WebP special case: RIFF....WEBP
|
||||
if ($mime === 'image/webp') {
|
||||
$matched = (substr($header, 0, 4) === 'RIFF' && substr($header, 8, 4) === 'WEBP');
|
||||
}
|
||||
|
||||
if (!$matched) {
|
||||
$this->block("Magic bytes mismatch for MIME: $mime", $ip, $uri, $field, $filename, $mime, $ext, $size);
|
||||
}
|
||||
}
|
||||
|
||||
private function scanForEmbeddedCode(
|
||||
string $tempPath,
|
||||
string $mime,
|
||||
string $ip,
|
||||
string $uri,
|
||||
string $field,
|
||||
string $filename,
|
||||
string $ext,
|
||||
int $size
|
||||
): void {
|
||||
$scanLimit = 1024 * 1024;
|
||||
|
||||
$content = '';
|
||||
if ($size <= $scanLimit) {
|
||||
$content = file_get_contents($tempPath);
|
||||
} else {
|
||||
$handle = fopen($tempPath, 'rb');
|
||||
if ($handle) {
|
||||
$content = fread($handle, 10240);
|
||||
fseek($handle, -10240, SEEK_END);
|
||||
$content .= fread($handle, 10240);
|
||||
fclose($handle);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$dangerousPatterns = [
|
||||
'/<\?php/i',
|
||||
'/<\?=/i',
|
||||
'/<\?/i',
|
||||
'/<%/i',
|
||||
'/<script\s+.*?runat\s*=\s*["\']?server/i',
|
||||
'/eval\s*\(/i',
|
||||
'/base64_decode\s*\(/i',
|
||||
'/system\s*\(/i',
|
||||
'/exec\s*\(/i',
|
||||
'/passthru\s*\(/i',
|
||||
'/shell_exec\s*\(/i',
|
||||
];
|
||||
|
||||
foreach ($dangerousPatterns as $pattern) {
|
||||
if (preg_match($pattern, $content)) {
|
||||
$this->block("Embedded code pattern detected in file", $ip, $uri, $field, $filename, $mime, $ext, $size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// block() signature and body kept EXACTLY as original — only $ext source changed upstream
|
||||
private function block(string $reason, string $ip, string $uri, string $field, string $filename, string $mime, string $ext, int $size): void
|
||||
{
|
||||
log_message('critical',
|
||||
@ -136,7 +321,7 @@ class GlobalPostFileUploadGuard implements FilterInterface
|
||||
$response->setStatusCode(403)
|
||||
->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'File upload rejected: Security policy violation.',
|
||||
'message' => 'File upload rejected: Security policy violation.' . ($reason ? " Reason: $reason." : ''),
|
||||
'debug' => (ENVIRONMENT === 'development') ? $reason : null
|
||||
])
|
||||
->send();
|
||||
@ -144,4 +329,4 @@ class GlobalPostFileUploadGuard implements FilterInterface
|
||||
}
|
||||
|
||||
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) {}
|
||||
}
|
||||
}
|
||||
|
||||
147
app/Filters/GlobalPostFileUploadGuardOLD.php
Normal file
147
app/Filters/GlobalPostFileUploadGuardOLD.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filters;
|
||||
|
||||
use CodeIgniter\HTTP\RequestInterface;
|
||||
use CodeIgniter\HTTP\ResponseInterface;
|
||||
use CodeIgniter\Filters\FilterInterface;
|
||||
use Config\Services;
|
||||
use finfo;
|
||||
|
||||
class GlobalPostFileUploadGuard implements FilterInterface
|
||||
{
|
||||
/**
|
||||
* Max file size (in bytes) → 25MB
|
||||
*/
|
||||
protected int $maxFileSize = 25 * 1024 * 1024;
|
||||
|
||||
/**
|
||||
* Allowed MIME types mapped to extensions
|
||||
*/
|
||||
protected array $allowedMimeMap = [
|
||||
'image/jpeg' => ['jpg', 'jpeg'],
|
||||
'image/png' => ['png'],
|
||||
'image/gif' => ['gif'],
|
||||
'image/webp' => ['webp'],
|
||||
'image/svg+xml' => ['svg'],
|
||||
'application/pdf' => ['pdf'],
|
||||
'application/msword' => ['doc'],
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => ['docx'],
|
||||
'application/vnd.oasis.opendocument.text' => ['odt'],
|
||||
'text/rtf' => ['rtf'],
|
||||
'application/rtf' => ['rtf'],
|
||||
'application/vnd.ms-excel' => ['xls'],
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => ['xlsx'],
|
||||
'application/vnd.oasis.opendocument.spreadsheet' => ['ods'],
|
||||
'text/csv' => ['csv'],
|
||||
'application/csv' => ['csv'],
|
||||
'text/plain' => ['txt', 'csv'],
|
||||
];
|
||||
|
||||
protected array $blockedExtensions = [
|
||||
'php', 'phtml', 'html', 'pht', 'phar', 'php3', 'php4', 'php5', 'php7', 'php8', 'phps',
|
||||
'cgi', 'fcgi', 'pl', 'py', 'rb', 'lua', 'tcl', 'go', 'rs', 'jar', 'class',
|
||||
'exe', 'dll', 'com', 'bat', 'cmd', 'msi', 'vbs', 'ps1', 'scr',
|
||||
'sh', 'bash', 'zsh', 'apk', 'app', 'deb', 'rpm', 'bin', 'run',
|
||||
'js', 'mjs', 'jsp', 'asp', 'aspx', 'cer', 'swf',
|
||||
'env', 'ini', 'user.ini', 'htaccess', 'htpasswd', 'conf', 'config', 'log', 'sql',
|
||||
'zip', 'rar', '7z', 'tar', 'gz', 'bz2', 'xz', 'iso',
|
||||
'lnk', 'url', 'reg', 'sys', 'drv', 'vxd', 'tmp', 'bak', 'old', 'backup', 'key', 'pem'
|
||||
];
|
||||
|
||||
public function before(RequestInterface $request, $arguments = null)
|
||||
{
|
||||
if ($request->getMethod() !== 'post') {
|
||||
return;
|
||||
}
|
||||
|
||||
$files = $request->getFiles();
|
||||
if (empty($files)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($files as $inputName => $fileData) {
|
||||
$this->validateFileInput($fileData, $inputName);
|
||||
}
|
||||
}
|
||||
|
||||
private function validateFileInput($fileData, string $inputName): void
|
||||
{
|
||||
if (is_array($fileData)) {
|
||||
foreach ($fileData as $file) {
|
||||
$this->validateSingleFile($file, $inputName);
|
||||
}
|
||||
} else {
|
||||
$this->validateSingleFile($fileData, $inputName);
|
||||
}
|
||||
}
|
||||
|
||||
private function validateSingleFile($file, string $inputName): void
|
||||
{
|
||||
$request = Services::request();
|
||||
$clientIp = $request->getIPAddress();
|
||||
$uri = $request->getUri()->getPath();
|
||||
|
||||
if (!$file->isValid()) {
|
||||
if ($file->getError() === UPLOAD_ERR_INI_SIZE || $file->getError() === UPLOAD_ERR_FORM_SIZE) {
|
||||
$this->block("File exceeds server-side size limit", $clientIp, $uri, $inputName, $file->getClientName(), 'unknown', 'unknown', 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$originalName = $file->getClientName();
|
||||
$extension = strtolower($file->getExtension());
|
||||
$mime = $file->getMimeType();
|
||||
$size = $file->getSize();
|
||||
|
||||
// --- 1. Fixed Null Byte & Path Traversal Check ---
|
||||
if (preg_match('/\0|[\/\\\]/', $originalName)) {
|
||||
$this->block("Malicious filename characters", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
}
|
||||
|
||||
// --- 2. Double Extension Attack Check ---
|
||||
if (preg_match('/\.(php|phtml|html|phar|exe|sh|bat|cmd|js|jsp|asp|aspx|py|pl)\./i', $originalName)) {
|
||||
$this->block("Double extension attack", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
}
|
||||
|
||||
// --- 3. Forbidden Extension ---
|
||||
if (in_array($extension, $this->blockedExtensions, true)) {
|
||||
$this->block("Forbidden extension", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
}
|
||||
|
||||
// --- 4. File Size Limit ---
|
||||
if ($size > $this->maxFileSize) {
|
||||
$this->block("File too large", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
}
|
||||
|
||||
// --- 5. MIME Allow-list Check ---
|
||||
if (!array_key_exists($mime, $this->allowedMimeMap)) {
|
||||
$this->block("MIME type not allowed ($mime)", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
}
|
||||
|
||||
// --- 6. MIME-Extension Consistency ---
|
||||
if (!in_array($extension, $this->allowedMimeMap[$mime], true)) {
|
||||
$this->block("MIME-extension mismatch", $clientIp, $uri, $inputName, $originalName, $mime, $extension, $size);
|
||||
}
|
||||
}
|
||||
|
||||
private function block(string $reason, string $ip, string $uri, string $field, string $filename, string $mime, string $ext, int $size): void
|
||||
{
|
||||
log_message('critical',
|
||||
'[UPLOAD_BLOCKED] {reason} | IP: {ip} | URI: {uri} | Field: {field} | File: {file} | MIME: {mime} | EXT: {ext} | SIZE: {size}',
|
||||
['reason'=>$reason, 'ip'=>$ip, 'uri'=>$uri, 'field'=>$field, 'file'=>$filename, 'mime'=>$mime, 'ext'=>$ext, 'size'=>$size]
|
||||
);
|
||||
|
||||
$response = Services::response();
|
||||
$response->setStatusCode(403)
|
||||
->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'File upload rejected: Security policy violation.',
|
||||
'debug' => (ENVIRONMENT === 'development') ? $reason : null
|
||||
])
|
||||
->send();
|
||||
exit;
|
||||
}
|
||||
|
||||
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) {}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user