Order Allow,Deny Deny from all # Block direct access to class files RewriteEngine On RewriteRule ^classes/ - [F,L] # Security headers (if mod_headers available) Header set X-Content-Type-Options "nosniff" Header set X-Frame-Options "SAMEORIGIN" '; if (file_put_contents(__DIR__ . '/.htaccess', $htaccessContent)) { $fixResults[] = array('success', 'Created .htaccess file'); } else { $fixResults[] = array('error', 'Failed to create .htaccess'); } break; case 'create_config': if (file_exists(__DIR__ . '/config.example.php')) { if (copy(__DIR__ . '/config.example.php', __DIR__ . '/config.php')) { @chmod(__DIR__ . '/config.php', 0644); $fixResults[] = array('success', 'Created config.php from example'); } else { $fixResults[] = array('error', 'Failed to copy config.example.php'); } } else { $configContent = ' [ \'api_key\' => \'\', \'api_secret\' => \'\', ], \'flickr_user_id\' => \'\', \'telegram\' => [ \'bot_token\' => \'\', \'channels\' => [], ], \'default_size\' => \'Large\', \'custom_formats\' => [], ];'; if (file_put_contents(__DIR__ . '/config.php', $configContent)) { @chmod(__DIR__ . '/config.php', 0644); $fixResults[] = array('success', 'Created config.php'); } else { $fixResults[] = array('error', 'Failed to create config.php'); } } break; case 'fix_permissions': $files = array( 'config.php' => 0644, 'auth_config.php' => 0600, '.htaccess' => 0644, ); foreach ($files as $file => $perm) { $path = __DIR__ . '/' . $file; if (file_exists($path)) { if (@chmod($path, $perm)) { $fixResults[] = array('success', "Fixed permissions for {$file}"); } else { $fixResults[] = array('error', "Failed to fix permissions for {$file}"); } } } break; case 'fix_auth_config_perms': $path = __DIR__ . '/auth_config.php'; if (file_exists($path)) { if (@chmod($path, 0600)) { $fixResults[] = array('success', 'Fixed auth_config.php permissions to 0600'); } else { $fixResults[] = array('error', 'Failed to fix auth_config.php permissions'); } } else { $fixResults[] = array('info', 'auth_config.php does not exist yet'); } break; case 'delete_debug': // Self-delete if (@unlink(__FILE__)) { header('Location: index.php'); exit; } else { $fixResults[] = array('error', 'Failed to delete debug.php - delete manually!'); } break; case 'reset_user': $path = __DIR__ . '/auth_config.php'; if (file_exists($path)) { if (@unlink($path)) { $fixResults[] = array('success', 'Deleted auth_config.php - go to setup.php to create new user'); } else { $fixResults[] = array('error', 'Failed to delete auth_config.php'); } } else { $fixResults[] = array('info', 'auth_config.php does not exist'); } break; } } // ============ HTML OUTPUT ============ ?> VH Posting System - Diagnostics

VH Posting System - Diagnostics

'; echo '

Fix Results

'; foreach ($fixResults as $result) { echo '
' . htmlspecialchars($result[1]) . '
'; } echo ''; } ?>

Quick Fix Panel

Click buttons to automatically fix common issues:



1. PHP Version"; echo "

PHP Version: " . phpversion() . "

"; if (version_compare(PHP_VERSION, '7.2.0', '<')) { echo "

WARNING: PHP 7.2+ required!

"; } else { echo "

OK: PHP version is compatible

"; } // Required extensions echo "

2. Required Extensions

"; $extensions = array('curl', 'json', 'mbstring', 'session'); foreach ($extensions as $ext) { if (extension_loaded($ext)) { echo "

OK: {$ext}

"; } else { echo "

MISSING: {$ext}

"; } } // BCMath (for base58 decoding) echo "

"; if (function_exists('bcmul')) { echo "OK: bcmath"; } else { echo "WARNING: bcmath not available (short URLs won't work)"; } echo "

"; // Password algorithms echo "

3. Password Hashing

"; if (defined('PASSWORD_ARGON2ID')) { echo "

OK: Argon2ID available

"; } else { echo "

INFO: Argon2ID not available, using bcrypt (OK)

"; } // Config file echo "

4. Configuration

"; if (file_exists(__DIR__ . '/config.php')) { echo "

OK: config.php exists

"; try { $config = require __DIR__ . '/config.php'; echo "

OK: config.php is valid PHP

"; if (!empty($config['flickr']['api_key'])) { echo "

OK: Flickr API key set

"; } else { echo "

INFO: Flickr API key not set

"; } if (!empty($config['telegram']['bot_token'])) { echo "

OK: Telegram bot token set

"; } else { echo "

INFO: Telegram bot token not set

"; } } catch (Throwable $e) { echo "

ERROR in config.php: " . htmlspecialchars($e->getMessage()) . "

"; } } else { echo "

MISSING: config.php — use Quick Fix above!

"; } // Writable directories echo "

5. File Permissions

"; if (is_writable(__DIR__)) { echo "

OK: Root directory is writable

"; } else { echo "

ERROR: Root directory is not writable (needed for auth_config.php)

"; } // Test class loading echo "

6. Class Loading Test

"; $classes = array('Auth', 'FlickrParser', 'FormatGenerator', 'FlickrAPI', 'TelegramBot'); foreach ($classes as $class) { $file = __DIR__ . '/classes/' . $class . '.php'; if (file_exists($file)) { try { require_once $file; if (class_exists($class)) { echo "

OK: {$class}

"; } else { echo "

ERROR: {$class} - file loaded but class not found

"; } } catch (Throwable $e) { echo "

ERROR loading {$class}: " . htmlspecialchars($e->getMessage()) . "

"; echo "
" . htmlspecialchars($e->getTraceAsString()) . "
"; } } else { echo "

MISSING: {$file}

"; } } // Test Auth instantiation echo "

7. Auth System Test

"; try { $auth = new Auth(); echo "

OK: Auth class instantiated

"; if ($auth->hasUsers()) { echo "

OK: Users exist, login page should work

"; } else { echo "

INFO: No users yet, setup.php should appear

"; } } catch (Throwable $e) { echo "

ERROR: " . htmlspecialchars($e->getMessage()) . "

"; echo "
" . htmlspecialchars($e->getTraceAsString()) . "
"; } // Security checks echo "

8. Security Checks

"; // HTTPS $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') || (!empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443); if ($isHttps) { echo "

OK: HTTPS enabled

"; } else { echo "

WARNING: HTTPS not detected (recommended for production)

"; } // .htaccess exists if (file_exists(__DIR__ . '/.htaccess')) { echo "

OK: .htaccess exists

"; } else { echo "

WARNING: .htaccess missing — use Quick Fix above!

"; } // ========== LEAK DETECTION ========== echo "

Leak Detection (API Keys & Credentials)

"; // Check if sensitive files are accessible via web $baseUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['REQUEST_URI']); $sensitiveFiles = array( 'config.php' => 'API Keys (Flickr, Telegram)', 'auth_config.php' => 'User passwords (hashed)', 'config.example.php' => 'Config template', 'classes/Auth.php' => 'Auth class source', 'classes/FlickrAPI.php' => 'Flickr API class', 'classes/TelegramBot.php' => 'Telegram Bot class', '.env' => 'Environment file', '.git/config' => 'Git config', 'composer.json' => 'Dependencies', 'error_log' => 'Error log', 'debug.log' => 'Debug log', ); $leaksFound = 0; foreach ($sensitiveFiles as $file => $desc) { $testUrl = rtrim($baseUrl, '/') . '/' . $file; $ch = curl_init(); curl_setopt_array($ch, array( CURLOPT_URL => $testUrl, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, CURLOPT_FOLLOWLOCATION => false, CURLOPT_SSL_VERIFYPEER => false, )); $content = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode == 403 || $httpCode == 404 || $httpCode == 500) { echo "

OK: {$file} is protected (HTTP {$httpCode})

"; } elseif ($httpCode == 200) { // Check if content contains sensitive data $hasSensitiveData = false; if (strpos($content, 'api_key') !== false || strpos($content, 'api_secret') !== false || strpos($content, 'bot_token') !== false || strpos($content, 'password_hash') !== false || strpos($content, 'password') !== false) { $hasSensitiveData = true; } if ($hasSensitiveData) { echo "

CRITICAL LEAK: {$file} is ACCESSIBLE and contains sensitive data! ({$desc})

"; $leaksFound++; } else { echo "

WARNING: {$file} is accessible (HTTP 200) - {$desc}

"; } } else { echo "

INFO: {$file} returned HTTP {$httpCode}

"; } } // Check for common info disclosure files echo "

Information Disclosure Check

"; $infoFiles = array( 'phpinfo.php' => 'PHP Info page', 'info.php' => 'PHP Info page', 'test.php' => 'Test file', 'readme.md' => 'Readme file', 'README.md' => 'Readme file', 'CHANGELOG.md' => 'Changelog', '.htpasswd' => 'Password file', 'backup.sql' => 'Database backup', 'dump.sql' => 'Database dump', ); foreach ($infoFiles as $file => $desc) { $path = __DIR__ . '/' . $file; if (file_exists($path)) { echo "

WARNING: {$file} exists - consider removing ({$desc})

"; } } // Check if secrets are exposed in JS files echo "

Secret Exposure in Public Files

"; $publicFiles = array( 'js/app.js', 'css/style.css', ); $secretPatterns = array( '/api[_-]?key\s*[:=]\s*[\'"][^\'"]+[\'"]/i' => 'API Key', '/bot[_-]?token\s*[:=]\s*[\'"][^\'"]+[\'"]/i' => 'Bot Token', '/password\s*[:=]\s*[\'"][^\'"]+[\'"]/i' => 'Password', '/secret\s*[:=]\s*[\'"][^\'"]+[\'"]/i' => 'Secret', ); foreach ($publicFiles as $file) { $path = __DIR__ . '/' . $file; if (file_exists($path)) { $content = file_get_contents($path); $foundSecrets = array(); foreach ($secretPatterns as $pattern => $type) { if (preg_match($pattern, $content)) { $foundSecrets[] = $type; } } if (!empty($foundSecrets)) { echo "

DANGER: {$file} may contain: " . implode(', ', $foundSecrets) . "

"; $leaksFound++; } else { echo "

OK: {$file} - no secrets found

"; } } } // Check config.php for exposed secrets (verify it's not outputting) if (file_exists(__DIR__ . '/config.php')) { $configContent = file_get_contents(__DIR__ . '/config.php'); // Check if config has echo/print statements if (preg_match('/(echo|print|var_dump|print_r)\s*\(/i', $configContent)) { echo "

DANGER: config.php contains output statements!

"; $leaksFound++; } else { echo "

OK: config.php has no output statements

"; } // Check if config returns array (proper format) if (strpos($configContent, 'return') !== false) { echo "

OK: config.php uses return statement (good)

"; } else { echo "

WARNING: config.php may not return array properly

"; } } // Summary if ($leaksFound > 0) { echo "
"; echo "SECURITY ALERT: {$leaksFound} potential leak(s) detected!"; echo "

Use Quick Fix buttons above or manually fix the issues.

"; echo "
"; } else { echo "

No critical leaks detected.

"; } // File permissions echo "

File Permissions

"; $checkPerms = array( 'config.php' => '0600 or 0644', 'auth_config.php' => '0600', '.htaccess' => '0644', ); foreach ($checkPerms as $file => $recommended) { $path = __DIR__ . '/' . $file; if (file_exists($path)) { $perms = substr(sprintf('%o', fileperms($path)), -4); $worldReadable = (fileperms($path) & 0x0004); if ($file === 'auth_config.php' && $worldReadable) { echo "

WARNING: {$file} is world-readable ({$perms}), recommended: {$recommended}

"; } else { echo "

OK: {$file} permissions: {$perms}

"; } } } // PHP security settings echo "

PHP Security Settings

"; echo "

These are hosting settings - may not be changeable on shared hosting

"; $securitySettings = array( 'expose_php' => array('recommended' => '0', 'desc' => 'Hide PHP version'), 'display_errors' => array('recommended' => '0', 'desc' => 'Hide errors in production'), 'allow_url_include' => array('recommended' => '0', 'desc' => 'Prevent remote file inclusion'), 'session.cookie_httponly' => array('recommended' => '1', 'desc' => 'Protect session cookie'), 'session.cookie_secure' => array('recommended' => '1', 'desc' => 'HTTPS-only cookies'), 'session.use_strict_mode' => array('recommended' => '1', 'desc' => 'Strict session mode'), ); foreach ($securitySettings as $setting => $info) { $value = ini_get($setting); $valueStr = ($value === '' || $value === '0' || $value === false) ? '0' : '1'; if ($valueStr === $info['recommended']) { echo "

OK: {$setting} = {$valueStr} ({$info['desc']})

"; } else { echo "

INFO: {$setting} = {$valueStr}, recommended: {$info['recommended']} ({$info['desc']})

"; } } // Cryptographic Functions echo "

Cryptographic Functions

"; if (function_exists('random_bytes')) { try { $test = random_bytes(32); echo "

OK: random_bytes() works

"; } catch (Exception $e) { echo "

ERROR: random_bytes() failed

"; } } else { echo "

WARNING: random_bytes() not available

"; } if (function_exists('openssl_random_pseudo_bytes')) { echo "

OK: openssl_random_pseudo_bytes() available

"; } else { echo "

WARNING: openssl_random_pseudo_bytes() not available

"; } if (function_exists('password_hash')) { echo "

OK: password_hash() available

"; } else { echo "

ERROR: password_hash() not available!

"; } // Server info (be careful not to expose too much) echo "

9. Server Info

"; echo "

Server software: " . htmlspecialchars(isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'Unknown') . "

"; echo "

Document root: " . htmlspecialchars(isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : 'Unknown') . "

"; echo "

Script path: " . htmlspecialchars(__DIR__) . "

"; echo "
"; echo "

If all green: Use 'Delete debug.php & Go to Site' button above

"; echo "

If errors: Use Quick Fix buttons, then refresh this page

"; echo "

IMPORTANT: Delete this file after debugging!

"; ?>