Files
wevads-platform/scripts/wevads-shield.php
2026-02-26 04:53:11 +01:00

163 lines
5.3 KiB
PHP
Executable File

<?php
/**
* WEVADS Arsenal — Security Shield v1.0
* Auto-prepended on every request (via arsenal-auth.php)
* - SQL injection filter
* - XSS sanitization
* - Rate limiting
* - CORS lockdown
* - Centralized DB config
*/
// === DB CONFIG (single source of truth) ===
define('WEVADS_DB_HOST', 'localhost');
define('WEVADS_DB_NAME', 'adx_system');
define('WEVADS_DB_USER', 'admin');
define('WEVADS_DB_PASS', 'admin123');
define('WEVADS_DB_DSN', 'pgsql:host='.WEVADS_DB_HOST.';dbname='.WEVADS_DB_NAME);
// === CORS LOCKDOWN ===
$allowed_origins = [
'http://89.167.40.150:5890',
'http://89.167.40.150:5821',
'http://127.0.0.1:5890',
'http://127.0.0.1:5821',
];
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if ($origin && !in_array($origin, $allowed_origins)) {
// Strip any existing wildcard CORS
header_remove('Access-Control-Allow-Origin');
}
// === TRUSTED IP + EXEC WHITELIST ===
$_waf_page = basename($_SERVER['SCRIPT_FILENAME'] ?? '');
$_waf_trusted_ips = ['151.80.235.110','127.0.0.1','::1','89.167.40.150'];
$_waf_skip_pages = ['claude-exec.php','claude-exec2.php','bx.php','sentinel-brain.php'];
if (in_array(($_SERVER['REMOTE_ADDR'] ?? ''), $_waf_trusted_ips)) goto waf_done;
if (in_array($_waf_page, $_waf_skip_pages)) goto waf_done;
$_waf_ext = pathinfo($_waf_page, PATHINFO_EXTENSION);
if (in_array($_waf_ext, ['js','css','png','jpg','jpeg','gif','svg','ico','woff','woff2'])) goto waf_done;
// === SQL INJECTION DETECTION ===
function wevads_detect_sqli($input) {
if (!is_string($input) || strlen($input) < 3) return false;
$patterns = [
'/(\bunion\b.*\bselect\b)/i',
'/(\bselect\b.*\bfrom\b.*\bwhere\b)/i',
'/(\bdrop\b\s+\btable\b)/i',
'/(\bdelete\b\s+\bfrom\b)/i',
'/(\binsert\b\s+\binto\b)/i',
'/(\bupdate\b.*\bset\b)/i',
'/(\'|\");\s*(drop|delete|update|insert|alter|create)/i',
'/(--\s|#|\/\*)/i', // SQL comments
'/(\bor\b\s+\b1\s*=\s*1)/i',
'/(\band\b\s+\b1\s*=\s*1)/i',
'/(\bwaitfor\b\s+\bdelay\b)/i',
'/(\bbenchmark\b\s*\()/i',
'/(;|\||`)\s*(cat|ls|rm|wget|curl|nc|bash|sh|python)/i', // Command injection
];
foreach ($patterns as $p) {
if (preg_match($p, $input)) return true;
}
return false;
}
// === XSS SANITIZATION ===
function wevads_clean($val) {
if (is_array($val)) return array_map('wevads_clean', $val);
if (!is_string($val)) return $val;
return htmlspecialchars(strip_tags(trim($val)), ENT_QUOTES, 'UTF-8');
}
// === SCAN ALL INPUT ===
$blocked = false;
$block_reason = '';
foreach (['GET','POST','REQUEST'] as $method) {
$data = ${"_$method"} ?? [];
foreach ($data as $key => $val) {
$values = is_array($val) ? $val : [$val];
foreach ($values as $v) {
if (is_string($v) && wevads_detect_sqli($v)) {
$blocked = true;
$block_reason = "SQLi detected in {$method}[{$key}]";
break 3;
}
}
}
}
// === LOG + BLOCK ===
if ($blocked) {
$log = date('Y-m-d H:i:s') . ' | ' . ($_SERVER['REMOTE_ADDR'] ?? '?') . ' | '
. ($_SERVER['REQUEST_URI'] ?? '?') . ' | ' . $block_reason . "\n";
@file_put_contents('/opt/wevads/logs/waf-blocks.log', $log, FILE_APPEND | LOCK_EX);
header('HTTP/1.1 403 Forbidden');
header('Content-Type: application/json');
echo json_encode(['error' => 'Request blocked by WAF', 'code' => 'WAF_001']);
exit;
}
// === RATE LIMITING (per IP, 200 req/min) ===
$rate_ip = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
if ($rate_ip !== '127.0.0.1' && $rate_ip !== '::1') {
$rate_file = '/tmp/waf_rate_' . md5($rate_ip);
$rate_data = file_exists($rate_file) ? json_decode(file_get_contents($rate_file), true) : ['c'=>0,'t'=>time()];
if (time() - $rate_data['t'] > 60) {
$rate_data = ['c'=>1,'t'=>time()];
} else {
$rate_data['c']++;
}
file_put_contents($rate_file, json_encode($rate_data));
if ($rate_data['c'] > 200) {
header('HTTP/1.1 429 Too Many Requests');
header('Retry-After: 60');
echo json_encode(['error'=>'Rate limit exceeded']);
exit;
}
}
waf_done:
// === SECURITY HEADERS ===
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: SAMEORIGIN');
header('X-XSS-Protection: 1; mode=block');
header('Referrer-Policy: strict-origin-when-cross-origin');
// === SAFE DB HELPER ===
function wevads_db() {
static $pdo = null;
if (!$pdo) {
$pdo = new PDO(WEVADS_DB_DSN, WEVADS_DB_USER, WEVADS_DB_PASS, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // Force real prepared statements
]);
$pdo->exec('SET search_path TO admin, public');
}
return $pdo;
}
function wevads_pg() {
static $pg = null;
if (!$pg) {
$pg = pg_connect("host=".WEVADS_DB_HOST." dbname=".WEVADS_DB_NAME." user=".WEVADS_DB_USER." password=".WEVADS_DB_PASS);
}
return $pg;
}
// Safe query wrapper — always parameterized
function wevads_query($sql, $params = []) {
$db = wevads_db();
$stmt = $db->prepare($sql);
$stmt->execute($params);
return $stmt;
}
// === DISABLE ERROR DISPLAY ===
ini_set('display_errors', 0);
error_reporting(E_ALL);
ini_set('log_errors', 1);
ini_set('error_log', '/opt/wevads/logs/php-errors.log');