cms/app/Console/Commands/PluginSecurityAudit.php
Funky Waddle 37ed997989 feat(cms): initialize Laravel project structure and core CMS files
- Added standard Laravel directory structure and configuration.

- Included Svelte and Tailwind configuration for the admin interface.

- Added core PHPUnit and testing scripts.
2026-04-13 12:48:06 -05:00

97 lines
3.1 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
class PluginSecurityAudit extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'sw:plugins:audit {--path=../plugins}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Audit plugins for potentially suspicious code.';
/**
* Suspect patterns to search for.
*
* @var array
*/
protected $suspectPatterns = [
'eval\(' => 'Use of eval() is highly dangerous and rarely necessary.',
'base64_decode\(' => 'Obfuscated code often uses base64_decode().',
'system\(' => 'Execution of system commands can be a security risk.',
'exec\(' => 'Execution of system commands can be a security risk.',
'shell_exec\(' => 'Execution of system commands can be a security risk.',
'passthru\(' => 'Execution of system commands can be a security risk.',
'popen\(' => 'Execution of system commands can be a security risk.',
'proc_open\(' => 'Execution of system commands can be a security risk.',
'curl_exec\(' => 'Outgoing network requests should be scrutinized.',
'file_get_contents\(\s*[\'"]http' => 'Fetching remote content can be dangerous.',
'extract\(' => 'extract() can lead to variable hijacking.',
'unserialize\(' => 'Unsafe deserialization can lead to RCE.',
];
/**
* Execute the console command.
*/
public function handle()
{
$pluginsPath = base_path($this->option('path'));
if (!File::isDirectory($pluginsPath)) {
$this->error("Plugins directory not found at: {$pluginsPath}");
return 1;
}
$this->info("Auditing plugins in: {$pluginsPath}");
$files = File::allFiles($pluginsPath);
$totalIssues = 0;
foreach ($files as $file) {
if ($file->getExtension() !== 'php') {
continue;
}
$content = File::get($file->getPathname());
$issues = [];
foreach ($this->suspectPatterns as $pattern => $reason) {
if (preg_match("/{$pattern}/i", $content)) {
$issues[] = [
'pattern' => $pattern,
'reason' => $reason,
];
}
}
if (!empty($issues)) {
$this->warn("\nSuspect code found in: " . $file->getRelativePathname());
foreach ($issues as $issue) {
$this->line(" [!] Pattern: " . $issue['pattern']);
$this->line(" Reason: " . $issue['reason']);
$totalIssues++;
}
}
}
if ($totalIssues === 0) {
$this->info("\nAudit completed. No suspicious patterns found.");
} else {
$this->error("\nAudit completed. Found {$totalIssues} potential issues.");
}
return $totalIssues === 0 ? 0 : 1;
}
}