Advertisement
mayankjoin3

Claude security

May 4th, 2025
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 15.91 KB | None | 0 0
  1. <?php
  2. // Prevent direct access
  3. if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) {
  4.     http_response_code(403);
  5.     exit("Forbidden");
  6. }
  7.  
  8. // Define application constants
  9. define('APP_ROOT', realpath(dirname(__FILE__)));
  10. define('LOG_DIR', APP_ROOT . '/logs');
  11.  
  12. // Create log directory if it doesn't exist
  13. if (!is_dir(LOG_DIR)) {
  14.     mkdir(LOG_DIR, 0750, true);
  15. }
  16.  
  17. // Security Headers
  18. header('X-Frame-Options: SAMEORIGIN');
  19. header('X-XSS-Protection: 1; mode=block');
  20. header('X-Content-Type-Options: nosniff');
  21. header("Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'; connect-src 'self'; frame-src 'none'; object-src 'none';");
  22. header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
  23. header('Referrer-Policy: same-origin');
  24. header('Permissions-Policy: geolocation=(), microphone=(), camera=()');
  25. header_remove("X-Powered-By");
  26. header_remove("Server");
  27.  
  28. // Error handling
  29. error_reporting(0); // Set to E_ALL for development
  30. ini_set('display_errors', 0);
  31. ini_set('log_errors', 1);
  32. ini_set('error_log', LOG_DIR . '/security.log');
  33.  
  34. // Check if HTTPS is in use
  35. if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
  36.     // For production - redirect to HTTPS (uncomment in production)
  37.     // header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
  38.     // exit();
  39.    
  40.     // Log that the site was accessed without HTTPS
  41.     error_log('Site accessed without HTTPS: ' . $_SERVER['REQUEST_URI']);
  42. }
  43.  
  44. // Set PHP security configuration
  45. ini_set('allow_url_include', 0);
  46. ini_set('allow_url_fopen', 0);
  47. ini_set('expose_php', 0);
  48. ini_set('max_execution_time', 30);
  49. ini_set('memory_limit', '128M');
  50. ini_set('file_uploads', 1);
  51. ini_set('upload_max_filesize', '10M');
  52. ini_set('max_file_uploads', 5);
  53. ini_set('post_max_size', '20M');
  54.  
  55. // Secure sessions
  56. ini_set('session.cookie_httponly', 1);
  57. ini_set('session.cookie_secure', isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on');
  58. ini_set('session.use_only_cookies', 1);
  59. ini_set('session.cookie_samesite', 'Lax');
  60. ini_set('session.gc_maxlifetime', 3600); // Session expires after 1 hour
  61. ini_set('session.use_strict_mode', 1);
  62. ini_set('session.sid_length', 48); // Longer session IDs
  63. ini_set('session.sid_bits_per_character', 6); // More entropy per character
  64.  
  65. // Set session name with non-default value
  66. session_name('APP_SESSION');
  67.  
  68. // Start the session
  69. session_start();
  70.  
  71. // Session fixation & binding - enhanced version
  72. $sessionTimeout = 3600; // 1 hour
  73. if (!isset($_SESSION['initiated'])) {
  74.     session_regenerate_id(true);
  75.     $_SESSION['initiated'] = true;
  76.     $_SESSION['created'] = time();
  77.     $_SESSION['last_activity'] = time();
  78.     $_SESSION['user_agent'] = hash('sha256', $_SERVER['HTTP_USER_AGENT']);
  79.     $_SESSION['ip'] = hash('sha256', $_SERVER['REMOTE_ADDR']);
  80. } else {
  81.     // Check for session timeout
  82.     if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > $sessionTimeout)) {
  83.         // Session timed out
  84.         session_unset();
  85.         session_destroy();
  86.         session_start();
  87.         session_regenerate_id(true);
  88.         error_log("Session timeout after {$sessionTimeout} seconds of inactivity.");
  89.         $_SESSION['auth_error'] = "Your session has expired. Please login again.";
  90.         // Redirect to login page if needed
  91.         // header('Location: /login.php');
  92.         // exit();
  93.     }
  94.    
  95.     // Check for session hijacking
  96.     if ($_SESSION['user_agent'] !== hash('sha256', $_SERVER['HTTP_USER_AGENT']) ||
  97.         $_SESSION['ip'] !== hash('sha256', $_SERVER['REMOTE_ADDR'])) {
  98.         session_unset();
  99.         session_destroy();
  100.         session_start();
  101.         session_regenerate_id(true);
  102.         error_log("Session hijack attempt blocked. IP: {$_SERVER['REMOTE_ADDR']}, User-Agent: {$_SERVER['HTTP_USER_AGENT']}");
  103.         $_SESSION['auth_error'] = "Session authentication error. Please login again.";
  104.         // Redirect to login page if needed
  105.         // header('Location: /login.php');
  106.         exit("Session Error");
  107.     }
  108.    
  109.     // Regenerate session ID periodically (every 30 minutes)
  110.     if (isset($_SESSION['created']) && (time() - $_SESSION['created'] > 1800)) {
  111.         session_regenerate_id(true);
  112.         $_SESSION['created'] = time();
  113.     }
  114.    
  115.     // Update last activity time
  116.     $_SESSION['last_activity'] = time();
  117. }
  118.  
  119. // Rate limiting for certain actions (example for login attempts)
  120. function rateLimit($action, $limit = 5, $timeframe = 300) {
  121.     // Simple rate limiting based on IP and action
  122.     $ip = $_SERVER['REMOTE_ADDR'];
  123.     $timestamp = time();
  124.     $logFile = LOG_DIR . '/rate_limits.json';
  125.    
  126.     // Create or load rate limit data
  127.     if (file_exists($logFile)) {
  128.         $data = json_decode(file_get_contents($logFile), true);
  129.     } else {
  130.         $data = [];
  131.     }
  132.    
  133.     // Clean up old entries
  134.     foreach ($data as $key => $entries) {
  135.         foreach ($entries as $i => $entry) {
  136.             if ($timestamp - $entry > $timeframe) {
  137.                 unset($data[$key][$i]);
  138.             }
  139.         }
  140.         if (empty($data[$key])) {
  141.             unset($data[$key]);
  142.         }
  143.     }
  144.    
  145.     // Check rate limit
  146.     $key = $ip . '_' . $action;
  147.     if (!isset($data[$key])) {
  148.         $data[$key] = [];
  149.     }
  150.    
  151.     if (count($data[$key]) >= $limit) {
  152.         // Rate limit exceeded
  153.         error_log("Rate limit exceeded for {$action} from IP {$ip}");
  154.         http_response_code(429);
  155.         exit('Too many requests. Please try again later.');
  156.     }
  157.    
  158.     // Add current timestamp to the log
  159.     $data[$key][] = $timestamp;
  160.    
  161.     // Save updated data
  162.     file_put_contents($logFile, json_encode($data), LOCK_EX);
  163.    
  164.     return true;
  165. }
  166.  
  167. // Input sanitization - Enhanced version
  168. function clean_input($data) {
  169.     if (is_array($data)) {
  170.         $cleaned = [];
  171.         foreach ($data as $key => $value) {
  172.             $cleaned[$key] = clean_input($value);
  173.         }
  174.         return $cleaned;
  175.     }
  176.     return htmlspecialchars(trim($data), ENT_QUOTES, 'UTF-8');
  177. }
  178.  
  179. // Input validation functions
  180. function validate_email($email) {
  181.     return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
  182. }
  183.  
  184. function validate_int($value, $min = null, $max = null) {
  185.     $options = [];
  186.     if ($min !== null) $options['min_range'] = $min;
  187.     if ($max !== null) $options['max_range'] = $max;
  188.     return filter_var($value, FILTER_VALIDATE_INT, ['options' => $options]) !== false;
  189. }
  190.  
  191. function validate_url($url) {
  192.     return filter_var($url, FILTER_VALIDATE_URL) !== false;
  193. }
  194.  
  195. // Enhanced recursive sanitization of input arrays
  196. function sanitize_inputs(&$array) {
  197.     foreach ($array as $key => &$value) {
  198.         if (is_array($value)) {
  199.             sanitize_inputs($value);
  200.         } else {
  201.             $value = clean_input($value);
  202.         }
  203.     }
  204. }
  205.  
  206. // Apply sanitization to all input sources
  207. sanitize_inputs($_GET);
  208. sanitize_inputs($_POST);
  209. sanitize_inputs($_COOKIE);
  210. // Don't sanitize $_FILES
  211.  
  212. // Safe include with better path handling
  213. function safe_include($file) {
  214.     // Convert to absolute path if relative path provided
  215.     if (!preg_match('/^\//', $file)) {
  216.         $file = APP_ROOT . '/' . $file;
  217.     }
  218.    
  219.     $realpath = realpath($file);
  220.     if ($realpath && strpos($realpath, APP_ROOT) === 0 && file_exists($realpath)) {
  221.         include $realpath;
  222.         return true;
  223.     } else {
  224.         error_log("Blocked unsafe include attempt: $file");
  225.         http_response_code(403);
  226.         exit("Invalid include");
  227.     }
  228. }
  229.  
  230. // CSRF protection - Enhanced version
  231. function generate_csrf_token() {
  232.     if (empty($_SESSION['csrf_token']) || empty($_SESSION['csrf_token_time']) ||
  233.         (time() - $_SESSION['csrf_token_time']) > 3600) {
  234.         $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
  235.         $_SESSION['csrf_token_time'] = time();
  236.     }
  237.     return $_SESSION['csrf_token'];
  238. }
  239.  
  240. function csrf_token_tag() {
  241.     $token = generate_csrf_token();
  242.     return '<input type="hidden" name="csrf_token" value="' . $token . '">';
  243. }
  244.  
  245. function verify_csrf_token($token = null) {
  246.     if ($token === null) {
  247.         // Try to get token from POST or headers
  248.         if (isset($_POST['csrf_token'])) {
  249.             $token = $_POST['csrf_token'];
  250.         } elseif (isset($_SERVER['HTTP_X_CSRF_TOKEN'])) {
  251.             $token = $_SERVER['HTTP_X_CSRF_TOKEN'];
  252.         } else {
  253.             return false;
  254.         }
  255.     }
  256.    
  257.     if (!isset($_SESSION['csrf_token']) || empty($token)) {
  258.         return false;
  259.     }
  260.    
  261.     return hash_equals($_SESSION['csrf_token'], $token);
  262. }
  263.  
  264. // SQL injection prevention helper (when using mysqli)
  265. function escape_sql($conn, $input) {
  266.     if (is_array($input)) {
  267.         $escaped = [];
  268.         foreach ($input as $key => $value) {
  269.             $escaped[$key] = escape_sql($conn, $value);
  270.         }
  271.         return $escaped;
  272.     }
  273.     return mysqli_real_escape_string($conn, $input);
  274. }
  275.  
  276. // Prepared statement wrapper for mysqli
  277. function execute_query($conn, $sql, $params = [], $types = '') {
  278.     if (empty($params)) {
  279.         return $conn->query($sql);
  280.     }
  281.    
  282.     $stmt = $conn->prepare($sql);
  283.     if (!$stmt) {
  284.         error_log("SQL Prepare Error: " . $conn->error . " in query: " . $sql);
  285.         return false;
  286.     }
  287.    
  288.     // If types string not provided, generate it
  289.     if (empty($types)) {
  290.         foreach ($params as $param) {
  291.             if (is_int($param)) {
  292.                 $types .= 'i';
  293.             } elseif (is_float($param)) {
  294.                 $types .= 'd';
  295.             } elseif (is_string($param)) {
  296.                 $types .= 's';
  297.             } else {
  298.                 $types .= 'b';
  299.             }
  300.         }
  301.     }
  302.    
  303.     if (!empty($params)) {
  304.         $stmt->bind_param($types, ...$params);
  305.     }
  306.    
  307.     $stmt->execute();
  308.    
  309.     return $stmt;
  310. }
  311.  
  312. // File upload security
  313. function secure_file_upload($file, $allowedTypes, $maxSize, $uploadDir) {
  314.     // Check if upload directory exists and is writable
  315.     if (!is_dir($uploadDir)) {
  316.         mkdir($uploadDir, 0750, true);
  317.     }
  318.    
  319.     if (!is_writable($uploadDir)) {
  320.         error_log("Upload directory not writable: $uploadDir");
  321.         return ['error' => 'Server configuration error.'];
  322.     }
  323.    
  324.     // Basic error checking
  325.     if (!isset($file['error']) || is_array($file['error'])) {
  326.         return ['error' => 'Invalid file parameters.'];
  327.     }
  328.    
  329.     // Check file upload errors
  330.     switch ($file['error']) {
  331.         case UPLOAD_ERR_OK:
  332.             break;
  333.         case UPLOAD_ERR_INI_SIZE:
  334.         case UPLOAD_ERR_FORM_SIZE:
  335.             return ['error' => 'File too large.'];
  336.         case UPLOAD_ERR_PARTIAL:
  337.             return ['error' => 'File upload was not completed.'];
  338.         case UPLOAD_ERR_NO_FILE:
  339.             return ['error' => 'No file was uploaded.'];
  340.         case UPLOAD_ERR_NO_TMP_DIR:
  341.         case UPLOAD_ERR_CANT_WRITE:
  342.         case UPLOAD_ERR_EXTENSION:
  343.             return ['error' => 'Server file upload error.'];
  344.         default:
  345.             return ['error' => 'Unknown upload error.'];
  346.     }
  347.    
  348.     // Check filesize
  349.     if ($file['size'] > $maxSize) {
  350.         return ['error' => 'File too large.'];
  351.     }
  352.    
  353.     // Check MIME type
  354.     $finfo = new finfo(FILEINFO_MIME_TYPE);
  355.     $fileType = $finfo->file($file['tmp_name']);
  356.    
  357.     if (!in_array($fileType, $allowedTypes)) {
  358.         return ['error' => 'File type not allowed.'];
  359.     }
  360.    
  361.     // Create safe filename
  362.     $filename = basename($file['name']);
  363.     $filename = preg_replace('/[^a-zA-Z0-9_.-]/', '_', $filename);
  364.     $filename = time() . '_' . $filename;
  365.     $uploadFile = $uploadDir . '/' . $filename;
  366.    
  367.     // Check for PHP code in files that shouldn't have it
  368.     if (!in_array($fileType, ['application/x-php', 'text/x-php'])) {
  369.         $fileContent = file_get_contents($file['tmp_name']);
  370.         if (preg_match('/<\?php/i', $fileContent)) {
  371.             return ['error' => 'File contains malicious code.'];
  372.         }
  373.     }
  374.    
  375.     // Move the file
  376.     if (move_uploaded_file($file['tmp_name'], $uploadFile)) {
  377.         // Set proper permissions
  378.         chmod($uploadFile, 0640);
  379.         return [
  380.             'success' => true,
  381.             'filename' => $filename,
  382.             'path' => $uploadFile
  383.         ];
  384.     }
  385.    
  386.     return ['error' => 'Failed to save file.'];
  387. }
  388.  
  389. // Password hashing function
  390. function hash_password($password) {
  391.     return password_hash($password, PASSWORD_ARGON2ID, [
  392.         'memory_cost' => 65536, // 64MB
  393.         'time_cost' => 4,       // 4 iterations
  394.         'threads' => 2          // 2 threads
  395.     ]);
  396. }
  397.  
  398. // Password verification
  399. function verify_password($password, $hash) {
  400.     return password_verify($password, $hash);
  401. }
  402.  
  403. // Request method validation
  404. function require_method($method) {
  405.     if ($_SERVER['REQUEST_METHOD'] !== strtoupper($method)) {
  406.         http_response_code(405);
  407.         header('Allow: ' . strtoupper($method));
  408.         exit('Method Not Allowed');
  409.     }
  410.     return true;
  411. }
  412.  
  413. // Logger function
  414. function security_log($message, $level = 'INFO') {
  415.     $timestamp = date('Y-m-d H:i:s');
  416.     $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'Unknown';
  417.     $user = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : 'Guest';
  418.     $logMessage = "[$timestamp][$level][$ip][$user] $message" . PHP_EOL;
  419.     error_log($logMessage, 3, LOG_DIR . '/security.log');
  420. }
  421.  
  422. // Environment check for additional security in production
  423. function is_production() {
  424.     // This is a simple example - define a more robust method for your environment
  425.     return (!isset($_SERVER['SERVER_NAME']) ||
  426.             !preg_match('/(localhost|127.0.0.1|.local|.test)$/', $_SERVER['SERVER_NAME']));
  427. }
  428.  
  429. // If in production, apply stricter security measures
  430. if (is_production()) {
  431.     // Additional production-only security measures
  432.     ini_set('session.cookie_secure', 1); // Force secure cookies
  433.     ini_set('session.gc_maxlifetime', 1800); // 30 minutes session timeout
  434. }
  435.  
  436. // Simple firewall - block suspicious requests
  437. $blocked_keywords = [
  438.     'eval(', 'UNION+SELECT', 'UNION SELECT', 'concat(', 'group_concat(',
  439.     'LOAD_FILE', 'outfile', 'dumpfile', '<script', 'javascript:',
  440.     'onload=', 'onerror=', 'onclick=', 'onmouseover='
  441. ];
  442.  
  443. foreach ($_GET as $key => $value) {
  444.     foreach ($blocked_keywords as $keyword) {
  445.         if (stripos($value, $keyword) !== false || stripos($key, $keyword) !== false) {
  446.             security_log("Blocked request with suspicious GET parameter: $key=$value", 'WARNING');
  447.             http_response_code(403);
  448.             exit('Access Denied');
  449.         }
  450.     }
  451. }
  452.  
  453. foreach ($_POST as $key => $value) {
  454.     if (is_string($value)) {
  455.         foreach ($blocked_keywords as $keyword) {
  456.             if (stripos($value, $keyword) !== false || stripos($key, $keyword) !== false) {
  457.                 security_log("Blocked request with suspicious POST parameter: $key=$value", 'WARNING');
  458.                 http_response_code(403);
  459.                 exit('Access Denied');
  460.             }
  461.         }
  462.     }
  463. }
  464.  
  465. // Check for common attack vectors in URL
  466. $uri = $_SERVER['REQUEST_URI'];
  467. foreach ($blocked_keywords as $keyword) {
  468.     if (stripos($uri, $keyword) !== false) {
  469.         security_log("Blocked request with suspicious URI: $uri", 'WARNING');
  470.         http_response_code(403);
  471.         exit('Access Denied');
  472.     }
  473. }
  474.  
  475. // Anti-automation - Block requests with no user agent
  476. if (empty($_SERVER['HTTP_USER_AGENT'])) {
  477.     security_log("Blocked request with no user agent", 'WARNING');
  478.     http_response_code(403);
  479.     exit('Access Denied');
  480. }
  481.  
  482. // Register shutdown function for additional logging
  483. register_shutdown_function(function() {
  484.     $error = error_get_last();
  485.     if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
  486.         security_log("Fatal error: {$error['message']} in {$error['file']} on line {$error['line']}", 'ERROR');
  487.     }
  488. });
  489. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement