This commit is contained in:
zuevav
2026-04-30 15:14:09 +03:00
parent 08fe53fa5c
commit e5a88665cd
25 changed files with 13697 additions and 0 deletions
+579
View File
@@ -0,0 +1,579 @@
<?php
/**
* Diagnostic file - DELETE after debugging!
*/
// Show all errors
error_reporting(E_ALL);
ini_set('display_errors', 1);
// ============ QUICK FIX ACTIONS ============
$fixResults = array();
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['fix_action'])) {
$action = $_POST['fix_action'];
switch ($action) {
case 'create_htaccess':
$htaccessContent = '# VH Posting System - Apache Configuration (reg.ru compatible)
# Prevent directory listing
Options -Indexes
# Deny access to sensitive files
<FilesMatch "(config\.php|auth_config\.php|\.example\.php)$">
Order Allow,Deny
Deny from all
</FilesMatch>
# Block direct access to class files
RewriteEngine On
RewriteRule ^classes/ - [F,L]
# Security headers (if mod_headers available)
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
</IfModule>';
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 = '<?php
return [
\'flickr\' => [
\'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 ============
?>
<!DOCTYPE html>
<html>
<head>
<title>VH Posting System - Diagnostics</title>
<style>
body { font-family: Arial, sans-serif; max-width: 900px; margin: 20px auto; padding: 0 20px; }
h1 { color: #333; border-bottom: 2px solid #2196F3; padding-bottom: 10px; }
h2 { color: #555; margin-top: 30px; }
h3 { color: #666; margin-top: 20px; }
code { background: #f5f5f5; padding: 2px 6px; border-radius: 3px; }
pre { background: #f5f5f5; padding: 10px; overflow-x: auto; }
.fix-box { background: #e3f2fd; border: 1px solid #2196F3; border-radius: 8px; padding: 20px; margin: 20px 0; }
.fix-box h2 { margin-top: 0; color: #1976D2; }
.btn { display: inline-block; padding: 10px 20px; margin: 5px; border: none; border-radius: 5px; cursor: pointer; font-size: 14px; }
.btn-primary { background: #2196F3; color: white; }
.btn-warning { background: #FF9800; color: white; }
.btn-danger { background: #f44336; color: white; }
.btn-success { background: #4CAF50; color: white; }
.btn:hover { opacity: 0.9; }
.result { padding: 10px 15px; margin: 5px 0; border-radius: 5px; }
.result-success { background: #e8f5e9; color: #2e7d32; border: 1px solid #4CAF50; }
.result-error { background: #ffebee; color: #c62828; border: 1px solid #f44336; }
.result-info { background: #fff3e0; color: #e65100; border: 1px solid #FF9800; }
</style>
</head>
<body>
<h1>VH Posting System - Diagnostics</h1>
<?php
// Show fix results
if (!empty($fixResults)) {
echo '<div class="fix-box">';
echo '<h2>Fix Results</h2>';
foreach ($fixResults as $result) {
echo '<div class="result result-' . $result[0] . '">' . htmlspecialchars($result[1]) . '</div>';
}
echo '</div>';
}
?>
<!-- Quick Fix Panel -->
<div class="fix-box">
<h2>Quick Fix Panel</h2>
<p>Click buttons to automatically fix common issues:</p>
<form method="POST" style="display: inline;">
<input type="hidden" name="fix_action" value="create_htaccess">
<button type="submit" class="btn btn-primary" onclick="return confirm('Create/overwrite .htaccess?')">Create .htaccess</button>
</form>
<form method="POST" style="display: inline;">
<input type="hidden" name="fix_action" value="create_config">
<button type="submit" class="btn btn-primary" onclick="return confirm('Create config.php from example?')">Create config.php</button>
</form>
<form method="POST" style="display: inline;">
<input type="hidden" name="fix_action" value="fix_permissions">
<button type="submit" class="btn btn-warning">Fix All Permissions</button>
</form>
<form method="POST" style="display: inline;">
<input type="hidden" name="fix_action" value="fix_auth_config_perms">
<button type="submit" class="btn btn-warning">Secure auth_config.php</button>
</form>
<br><br>
<form method="POST" style="display: inline;">
<input type="hidden" name="fix_action" value="reset_user">
<button type="submit" class="btn btn-danger" onclick="return confirm('DELETE all users and start fresh?')">Reset Users</button>
</form>
<form method="POST" style="display: inline;">
<input type="hidden" name="fix_action" value="delete_debug">
<button type="submit" class="btn btn-success" onclick="return confirm('Delete debug.php and go to main site?')">Delete debug.php & Go to Site</button>
</form>
</div>
<?php
// PHP Version
echo "<h2>1. PHP Version</h2>";
echo "<p>PHP Version: <strong>" . phpversion() . "</strong></p>";
if (version_compare(PHP_VERSION, '7.2.0', '<')) {
echo "<p style='color:red'>WARNING: PHP 7.2+ required!</p>";
} else {
echo "<p style='color:green'>OK: PHP version is compatible</p>";
}
// Required extensions
echo "<h2>2. Required Extensions</h2>";
$extensions = array('curl', 'json', 'mbstring', 'session');
foreach ($extensions as $ext) {
if (extension_loaded($ext)) {
echo "<p style='color:green'>OK: {$ext}</p>";
} else {
echo "<p style='color:red'>MISSING: {$ext}</p>";
}
}
// BCMath (for base58 decoding)
echo "<p>";
if (function_exists('bcmul')) {
echo "<span style='color:green'>OK: bcmath</span>";
} else {
echo "<span style='color:orange'>WARNING: bcmath not available (short URLs won't work)</span>";
}
echo "</p>";
// Password algorithms
echo "<h2>3. Password Hashing</h2>";
if (defined('PASSWORD_ARGON2ID')) {
echo "<p style='color:green'>OK: Argon2ID available</p>";
} else {
echo "<p style='color:orange'>INFO: Argon2ID not available, using bcrypt (OK)</p>";
}
// Config file
echo "<h2>4. Configuration</h2>";
if (file_exists(__DIR__ . '/config.php')) {
echo "<p style='color:green'>OK: config.php exists</p>";
try {
$config = require __DIR__ . '/config.php';
echo "<p style='color:green'>OK: config.php is valid PHP</p>";
if (!empty($config['flickr']['api_key'])) {
echo "<p style='color:green'>OK: Flickr API key set</p>";
} else {
echo "<p style='color:orange'>INFO: Flickr API key not set</p>";
}
if (!empty($config['telegram']['bot_token'])) {
echo "<p style='color:green'>OK: Telegram bot token set</p>";
} else {
echo "<p style='color:orange'>INFO: Telegram bot token not set</p>";
}
} catch (Throwable $e) {
echo "<p style='color:red'>ERROR in config.php: " . htmlspecialchars($e->getMessage()) . "</p>";
}
} else {
echo "<p style='color:red'>MISSING: config.php — <strong>use Quick Fix above!</strong></p>";
}
// Writable directories
echo "<h2>5. File Permissions</h2>";
if (is_writable(__DIR__)) {
echo "<p style='color:green'>OK: Root directory is writable</p>";
} else {
echo "<p style='color:red'>ERROR: Root directory is not writable (needed for auth_config.php)</p>";
}
// Test class loading
echo "<h2>6. Class Loading Test</h2>";
$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 "<p style='color:green'>OK: {$class}</p>";
} else {
echo "<p style='color:red'>ERROR: {$class} - file loaded but class not found</p>";
}
} catch (Throwable $e) {
echo "<p style='color:red'>ERROR loading {$class}: " . htmlspecialchars($e->getMessage()) . "</p>";
echo "<pre>" . htmlspecialchars($e->getTraceAsString()) . "</pre>";
}
} else {
echo "<p style='color:red'>MISSING: {$file}</p>";
}
}
// Test Auth instantiation
echo "<h2>7. Auth System Test</h2>";
try {
$auth = new Auth();
echo "<p style='color:green'>OK: Auth class instantiated</p>";
if ($auth->hasUsers()) {
echo "<p style='color:green'>OK: Users exist, login page should work</p>";
} else {
echo "<p style='color:orange'>INFO: No users yet, setup.php should appear</p>";
}
} catch (Throwable $e) {
echo "<p style='color:red'>ERROR: " . htmlspecialchars($e->getMessage()) . "</p>";
echo "<pre>" . htmlspecialchars($e->getTraceAsString()) . "</pre>";
}
// Security checks
echo "<h2>8. Security Checks</h2>";
// 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 "<p style='color:green'>OK: HTTPS enabled</p>";
} else {
echo "<p style='color:orange'>WARNING: HTTPS not detected (recommended for production)</p>";
}
// .htaccess exists
if (file_exists(__DIR__ . '/.htaccess')) {
echo "<p style='color:green'>OK: .htaccess exists</p>";
} else {
echo "<p style='color:red'>WARNING: .htaccess missing — <strong>use Quick Fix above!</strong></p>";
}
// ========== LEAK DETECTION ==========
echo "<h3>Leak Detection (API Keys & Credentials)</h3>";
// 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 "<p style='color:green'>OK: {$file} is protected (HTTP {$httpCode})</p>";
} 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 "<p style='color:red'><strong>CRITICAL LEAK:</strong> {$file} is ACCESSIBLE and contains sensitive data! ({$desc})</p>";
$leaksFound++;
} else {
echo "<p style='color:orange'>WARNING: {$file} is accessible (HTTP 200) - {$desc}</p>";
}
} else {
echo "<p style='color:orange'>INFO: {$file} returned HTTP {$httpCode}</p>";
}
}
// Check for common info disclosure files
echo "<h3>Information Disclosure Check</h3>";
$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 "<p style='color:orange'>WARNING: {$file} exists - consider removing ({$desc})</p>";
}
}
// Check if secrets are exposed in JS files
echo "<h3>Secret Exposure in Public Files</h3>";
$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 "<p style='color:red'><strong>DANGER:</strong> {$file} may contain: " . implode(', ', $foundSecrets) . "</p>";
$leaksFound++;
} else {
echo "<p style='color:green'>OK: {$file} - no secrets found</p>";
}
}
}
// 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 "<p style='color:red'><strong>DANGER:</strong> config.php contains output statements!</p>";
$leaksFound++;
} else {
echo "<p style='color:green'>OK: config.php has no output statements</p>";
}
// Check if config returns array (proper format)
if (strpos($configContent, 'return') !== false) {
echo "<p style='color:green'>OK: config.php uses return statement (good)</p>";
} else {
echo "<p style='color:orange'>WARNING: config.php may not return array properly</p>";
}
}
// Summary
if ($leaksFound > 0) {
echo "<div style='background:#ffebee;border:2px solid #f44336;padding:15px;margin:15px 0;border-radius:5px;'>";
echo "<strong style='color:#c62828;'>SECURITY ALERT: {$leaksFound} potential leak(s) detected!</strong>";
echo "<p>Use Quick Fix buttons above or manually fix the issues.</p>";
echo "</div>";
} else {
echo "<p style='color:green'><strong>No critical leaks detected.</strong></p>";
}
// File permissions
echo "<h3>File Permissions</h3>";
$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 "<p style='color:orange'>WARNING: {$file} is world-readable ({$perms}), recommended: {$recommended}</p>";
} else {
echo "<p style='color:green'>OK: {$file} permissions: {$perms}</p>";
}
}
}
// PHP security settings
echo "<h3>PHP Security Settings</h3>";
echo "<p style='color:#666'><em>These are hosting settings - may not be changeable on shared hosting</em></p>";
$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 "<p style='color:green'>OK: {$setting} = {$valueStr} ({$info['desc']})</p>";
} else {
echo "<p style='color:orange'>INFO: {$setting} = {$valueStr}, recommended: {$info['recommended']} ({$info['desc']})</p>";
}
}
// Cryptographic Functions
echo "<h3>Cryptographic Functions</h3>";
if (function_exists('random_bytes')) {
try {
$test = random_bytes(32);
echo "<p style='color:green'>OK: random_bytes() works</p>";
} catch (Exception $e) {
echo "<p style='color:red'>ERROR: random_bytes() failed</p>";
}
} else {
echo "<p style='color:orange'>WARNING: random_bytes() not available</p>";
}
if (function_exists('openssl_random_pseudo_bytes')) {
echo "<p style='color:green'>OK: openssl_random_pseudo_bytes() available</p>";
} else {
echo "<p style='color:orange'>WARNING: openssl_random_pseudo_bytes() not available</p>";
}
if (function_exists('password_hash')) {
echo "<p style='color:green'>OK: password_hash() available</p>";
} else {
echo "<p style='color:red'>ERROR: password_hash() not available!</p>";
}
// Server info (be careful not to expose too much)
echo "<h2>9. Server Info</h2>";
echo "<p>Server software: <code>" . htmlspecialchars(isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'Unknown') . "</code></p>";
echo "<p>Document root: <code>" . htmlspecialchars(isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : 'Unknown') . "</code></p>";
echo "<p>Script path: <code>" . htmlspecialchars(__DIR__) . "</code></p>";
echo "<hr>";
echo "<p><strong>If all green:</strong> Use <strong>'Delete debug.php & Go to Site'</strong> button above</p>";
echo "<p><strong>If errors:</strong> Use Quick Fix buttons, then refresh this page</p>";
echo "<p style='color:red'><strong>IMPORTANT: Delete this file after debugging!</strong></p>";
?>
</body>
</html>