<?php
/**
 * Global File Upload Security Validator
 * Auto-validates ALL file uploads in your application
 * 
 * Place this file at: /journals/common/file_upload_security.php
 * Include it ONCE in your main config file
 * 
 * NO CODE CHANGES NEEDED IN OTHER FILES!
 */

class FileUploadSecurity {
    
    // Blocked extensions (security threat - code files)
    private static $blockedExtensions = [
        'php', 'php3', 'php4', 'php5', 'phtml', 'pht',
        'js', 'jsx',
        'html', 'htm', 'xhtml',
        'css', 'scss', 'sass', 'less',
        'py', 'pyc', 'pyo',
        'sh', 'bash', 'zsh',
        'bat', 'cmd', 'com',
        'exe', 'dll', 'so', 'dylib',
        'jar', 'war', 'ear',
        'sql', 'db', 'sqlite',
        'xml', 'xsl', 'xslt',
        'json', 'yml', 'yaml',
        'asp', 'aspx', 'jsp', 'jspx',
        'cgi', 'pl', 'pm',
        'rb', 'rake',
        'go', 'swift',
        'vbs', 'vb',
        'ps1', 'psm1',
        'htaccess', 'htpasswd',
        'config', 'conf', 'ini',
        'env',
        'key', 'pem', 'cer', 'crt',
        'class', 'java',
        'c', 'cpp', 'h', 'hpp',
        'cs', 'vb', 'fs'
    ];
    
    // Allowed MIME types for documents
    private static $allowedMimeTypes = [
        'application/pdf',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/rtf',
        'text/rtf',
        'application/vnd.ms-excel',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'text/csv',
        'image/jpeg',
        'image/jpg',
        'image/png',
        'image/gif',
        'image/webp',
        'image/bmp',
        'text/plain'
    ];
    
    /**
     * Initialize auto-validation
     * Call this once in your config file
     */
    public static function init() {
        // Auto-validate when files are accessed
        if (!empty($_FILES)) {
            self::validateAllUploads();
        }
    }
    
    /**
     * Validate all uploaded files automatically
     */
    private static function validateAllUploads() {
        foreach ($_FILES as $fieldName => $file) {
            // Skip if no file uploaded or error
            if (!isset($file['tmp_name']) || $file['error'] === UPLOAD_ERR_NO_FILE) {
                continue;
            }
            
            if ($file['error'] !== UPLOAD_ERR_OK) {
                continue; // Let application handle upload errors
            }
            
            // Validate the file
            $result = self::validateFile($file);
            
            if (!$result['success']) {
                // Block the upload and stop execution
                self::blockUpload($result['message'], $fieldName);
            }
        }
    }
    
    /**
     * Validate a single file
     */
    private static function validateFile($file) {
        $fileName = $file['name'];
        $fileTmpPath = $file['tmp_name'];
        $fileExtension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
        
        // SECURITY CHECK 1: Block dangerous extensions
        if (in_array($fileExtension, self::$blockedExtensions)) {
            return [
                'success' => false,
                'message' => '🚫 Security Alert: Code/Script files (.' . $fileExtension . ') are not allowed for security reasons.'
            ];
        }
        
        // SECURITY CHECK 2: Verify MIME type
        if (function_exists('finfo_open')) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mimeType = finfo_file($finfo, $fileTmpPath);
            finfo_close($finfo);
            
            if (!in_array($mimeType, self::$allowedMimeTypes)) {
                return [
                    'success' => false,
                    'message' => '🚫 Invalid file type detected. Only documents, images, and spreadsheets are allowed.'
                ];
            }
        }
        
        // SECURITY CHECK 3: Scan for executable content
        $content = file_get_contents($fileTmpPath, false, null, 0, 2048);
        
        // Check for PHP code
        if (stripos($content, '<?php') !== false || stripos($content, '<?=') !== false) {
            return [
                'success' => false,
                'message' => '🚫 Security Alert: File contains PHP code and cannot be uploaded.'
            ];
        }
        
        // Check for script tags
        if (stripos($content, '<script') !== false) {
            return [
                'success' => false,
                'message' => '🚫 Security Alert: File contains script tags and cannot be uploaded.'
            ];
        }
        
        // Check for binary executable signatures
        $signatures = [
            'MZ', // Windows EXE
            "\x7FELF", // Linux ELF
            "\xCA\xFE\xBA\xBE", // Java Class
            "\xFE\xED\xFA" // Mach-O
        ];
        
        foreach ($signatures as $sig) {
            if (strpos($content, $sig) === 0) {
                return [
                    'success' => false,
                    'message' => '🚫 Security Alert: Executable files are not allowed.'
                ];
            }
        }
        
        // File passed all security checks
        return ['success' => true];
    }
    
    /**
     * Block upload and show error
     */
    private static function blockUpload($message, $fieldName) {
        // Log the security incident
        error_log("SECURITY: Blocked file upload - Field: $fieldName - Reason: $message - IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
        
        // Check if it's an AJAX request
        if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && 
            strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
            // Return JSON response for AJAX
            header('Content-Type: application/json');
            echo json_encode([
                'success' => false,
                'message' => $message
            ]);
            exit();
        } else {
            // Show error page for regular form submission
            http_response_code(403);
            ?>
            <!DOCTYPE html>
            <html>
            <head>
                <title>Upload Blocked - Security</title>
                <style>
                    body {
                        font-family: Arial, sans-serif;
                        background: #f5f5f5;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        height: 100vh;
                        margin: 0;
                    }
                    .error-box {
                        background: white;
                        padding: 40px;
                        border-radius: 10px;
                        box-shadow: 0 4px 6px rgba(0,0,0,0.1);
                        max-width: 500px;
                        text-align: center;
                    }
                    .error-icon {
                        font-size: 60px;
                        color: #e74c3c;
                        margin-bottom: 20px;
                    }
                    h1 {
                        color: #e74c3c;
                        margin-bottom: 10px;
                    }
                    p {
                        color: #666;
                        line-height: 1.6;
                    }
                    .back-button {
                        display: inline-block;
                        margin-top: 20px;
                        padding: 12px 30px;
                        background: #3498db;
                        color: white;
                        text-decoration: none;
                        border-radius: 5px;
                        transition: background 0.3s;
                    }
                    .back-button:hover {
                        background: #2980b9;
                    }
                </style>
            </head>
            <body>
                <div class="error-box">
                    <div class="error-icon">🛡️</div>
                    <h1>Upload Blocked</h1>
                    <p><?php echo htmlspecialchars($message); ?></p>
                    <p style="font-size: 14px; margin-top: 20px; color: #999;">
                        For your security, only safe file types are allowed.<br>
                        Allowed: PDF, DOC, DOCX, XLS, XLSX, Images (JPG, PNG, GIF)
                    </p>
                    <a href="javascript:history.back()" class="back-button">Go Back</a>
                </div>
            </body>
            </html>
            <?php
            exit();
        }
    }
    
    /**
     * Manual validation function (optional - for specific checks)
     */
    public static function validate($file) {
        return self::validateFile($file);
    }
}

// Auto-initialize when file is included
FileUploadSecurity::init();