From 894392065c07433ec7e72230f7ab4a79b7153887 Mon Sep 17 00:00:00 2001 From: Myron Blair Date: Fri, 22 May 2026 13:05:18 +0000 Subject: [PATCH] Security: remove test/debug/install files from production --- .htaccess.bak | 117 ------------------------- fix_broadcast.php | 28 ------ install.php | 206 --------------------------------------------- phpcheck.php | 25 ------ ref_test.php | 26 ------ referral_setup.php | 96 --------------------- test.php | 6 -- test_login.php | 18 ---- test_mail.php | 91 -------------------- 9 files changed, 613 deletions(-) delete mode 100644 .htaccess.bak delete mode 100644 fix_broadcast.php delete mode 100644 install.php delete mode 100644 phpcheck.php delete mode 100644 ref_test.php delete mode 100644 referral_setup.php delete mode 100644 test.php delete mode 100644 test_login.php delete mode 100644 test_mail.php diff --git a/.htaccess.bak b/.htaccess.bak deleted file mode 100644 index 1424f36..0000000 --- a/.htaccess.bak +++ /dev/null @@ -1,117 +0,0 @@ -# ══════════════════════════════════════════════════════════ -# TomTomGames Security Configuration -# ══════════════════════════════════════════════════════════ - -Options -Indexes -Includes -ServerSignature Off - -# ── Block all sensitive file types ─────────────────────── - - Order allow,deny - Deny from all - - -# ── Block direct access to sensitive PHP files ─────────── - - Order allow,deny - Deny from all - - -# ── Block access to includes and vendor folders ────────── - - RewriteEngine On - RewriteRule ^includes/ - [F,L] - RewriteRule ^vendor/ - [F,L] - RewriteRule ^mail_queue/ - [F,L] - RewriteRule ^\.git/ - [F,L] - - -# ── Block common attack vectors ────────────────────────── - - RewriteEngine On - - # Block SQL injection attempts in query strings - RewriteCond %{QUERY_STRING} (union|select|insert|drop|delete|update|cast|exec|declare|char|convert|truncate).*= [NC,OR] - RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR] - RewriteCond %{QUERY_STRING} \.\./\.\. [NC,OR] - RewriteCond %{QUERY_STRING} (javascript|vbscript|expression|applet|meta|xml|blink|link|iframe|input|embed|script|object|marquee) [NC] - RewriteRule .* - [F,L] - - # Block base64 encoded attacks - RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [NC,OR] - RewriteCond %{QUERY_STRING} base64_(en|de)code[^(]*\([^)]*\) [NC] - RewriteRule .* - [F,L] - - # Block common exploit scanners and bad bots - RewriteCond %{HTTP_USER_AGENT} (nikto|sqlmap|havij|nessus|masscan|zgrab|python-requests/2\.6|libwww-perl|wget|curl\/7\.[0-4]) [NC] - RewriteRule .* - [F,L] - - -# ── Block access to WordPress paths (scanners look for these) ── - - RewriteRule ^wp-admin - [F,L] - RewriteRule ^wp-login - [F,L] - RewriteRule ^xmlrpc - [F,L] - RewriteRule ^\.env - [F,L] - RewriteRule ^composer\. - [F,L] - - -# ── Security Headers ────────────────────────────────────── - - # Prevent MIME type sniffing - Header always set X-Content-Type-Options "nosniff" - - # Prevent clickjacking - Header always set X-Frame-Options "DENY" - - # XSS protection - Header always set X-XSS-Protection "1; mode=block" - - # Referrer policy - Header always set Referrer-Policy "strict-origin-when-cross-origin" - - # Permissions policy — disable dangerous browser features - Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), magnetometer=(), gyroscope=()" - - # Content Security Policy — restrict where resources can load from - Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://web.squarecdn.com https://sandbox.web.squarecdn.com https://js.squareup.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https: wss:; frame-src 'none'" - - # Strict Transport Security — force HTTPS for 1 year - Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" - - # Remove server info headers - Header unset Server - Header unset X-Powered-By - - -# ── Canonical HTTPS + non-www redirect ─────────────────── - - RewriteEngine On - RewriteCond %{HTTPS} off - RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] - RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] - RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L] - - -# ── Block PHP execution in uploads folder (if it exists) ─ - - RewriteRule ^uploads/.*\.php$ - [F,L] - - -# ── Gzip compression ────────────────────────────────────── - - AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/json image/svg+xml - - -# ── Browser caching ─────────────────────────────────────── - - ExpiresActive On - ExpiresByType text/html "access plus 1 hour" - ExpiresByType text/css "access plus 1 month" - ExpiresByType application/javascript "access plus 1 month" - ExpiresByType image/svg+xml "access plus 1 month" - ExpiresByType image/png "access plus 1 month" - ExpiresByType image/jpeg "access plus 1 month" - ExpiresByType image/webp "access plus 1 month" - ExpiresByType application/json "access plus 1 day" - diff --git a/fix_broadcast.php b/fix_broadcast.php deleted file mode 100644 index b8b66f1..0000000 --- a/fix_broadcast.php +++ /dev/null @@ -1,28 +0,0 @@ -query(\$sql);\n echo json_encode(['success'=>true,'broadcasts'=>\$stmt->fetchAll()]);\n } catch(Exception \$e) {\n echo json_encode(['success'=>false,'error'=>\$e->getMessage()]);\n }\n break;"; - -$c = substr($c, 0, $idx) . $new . substr($c, $end); -file_put_contents($f, $c); - -// Verify it works -require_once '/home/tomtomgames.com/includes/config.php'; -require_once '/home/tomtomgames.com/includes/db.php'; - -try { - $stmt = db()->query("SELECT COUNT(*) FROM broadcasts"); - echo "OK - broadcasts in DB: " . $stmt->fetchColumn() . "\n"; - $stmt2 = db()->query("SELECT b.id, b.subject, b.sent_at, u.username AS sender_name FROM broadcasts b JOIN users u ON b.admin_id=u.id ORDER BY b.sent_at DESC LIMIT 5"); - $rows = $stmt2->fetchAll(); - echo "Query works - rows: " . count($rows) . "\n"; - foreach($rows as $r) echo " #{$r['id']}: {$r['subject']} by {$r['sender_name']}\n"; -} catch(Exception $e) { - echo "ERROR: " . $e->getMessage() . "\n"; -} -echo "DONE - delete this file\n"; diff --git a/install.php b/install.php deleted file mode 100644 index d7f1275..0000000 --- a/install.php +++ /dev/null @@ -1,206 +0,0 @@ -Access denied. Add ?key=TomGames2024Admin to URL.'); - -require_once __DIR__ . '/../includes/config.php'; - -$log = []; -function ok($msg) { global $log; $log[] = ['t'=>'ok', 'm'=>$msg]; } -function err($msg) { global $log; $log[] = ['t'=>'err', 'm'=>$msg]; } -function warn($msg) { global $log; $log[] = ['t'=>'warn','m'=>$msg]; } -function info($msg) { global $log; $log[] = ['t'=>'info','m'=>$msg]; } - -try { - $pdo = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=utf8mb4", DB_USER, DB_PASS, - [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); - ok('Connected to '.DB_NAME.' as '.DB_USER.''); -} catch (Exception $e) { - die('
CONNECTION FAILED: '.htmlspecialchars($e->getMessage()).'
'); -} - -// Helper: check if column exists -function colExists(PDO $pdo, string $table, string $col): bool { - $r = $pdo->query("SHOW COLUMNS FROM `$table` LIKE '$col'")->fetch(); - return (bool)$r; -} - -// ── CREATE TABLES ─────────────────────────────────────────── -$tables = [ -'users' => "CREATE TABLE IF NOT EXISTS users ( - id INT AUTO_INCREMENT PRIMARY KEY, - username VARCHAR(50) UNIQUE NOT NULL, - password VARCHAR(255) NOT NULL, - alias VARCHAR(100) NOT NULL, - email VARCHAR(150) UNIQUE, - email_verified TINYINT(1) DEFAULT 0, - tokens DECIMAL(10,2) DEFAULT 0, - is_admin TINYINT(1) DEFAULT 0, - status ENUM('active','suspended') DEFAULT 'active', - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - last_login DATETIME -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", - -'pending_registrations' => "CREATE TABLE IF NOT EXISTS pending_registrations ( - id INT AUTO_INCREMENT PRIMARY KEY, - username VARCHAR(50) NOT NULL, - password VARCHAR(255) NOT NULL, - alias VARCHAR(100) NOT NULL, - email VARCHAR(150) NOT NULL, - token VARCHAR(64) UNIQUE NOT NULL, - expires_at DATETIME NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", - -'token_purchases' => "CREATE TABLE IF NOT EXISTS token_purchases ( - id INT AUTO_INCREMENT PRIMARY KEY, - user_id INT NOT NULL, - tokens INT NOT NULL, - amount_cents INT NOT NULL, - payment_method VARCHAR(20) DEFAULT 'card', - square_payment_id VARCHAR(255), - platform_id VARCHAR(50), - game_alias VARCHAR(100), - player_name VARCHAR(100), - billing_name VARCHAR(160), - billing_address VARCHAR(200), - billing_city VARCHAR(80), - billing_state VARCHAR(2), - billing_zip VARCHAR(10), - billing_email VARCHAR(150), - is_custom TINYINT(1) DEFAULT 0, - failure_reason TEXT, - card_brand VARCHAR(30), - card_last4 VARCHAR(4), - receipt_url VARCHAR(512), - status ENUM('pending','completed','failed') DEFAULT 'pending', - admin_note TEXT, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", - -'cashout_requests' => "CREATE TABLE IF NOT EXISTS cashout_requests ( - id INT AUTO_INCREMENT PRIMARY KEY, - user_id INT NOT NULL, - platform_id VARCHAR(50) NOT NULL, - alias VARCHAR(100) NOT NULL, - tokens DECIMAL(10,2) NOT NULL, - status ENUM('pending','approved','rejected') DEFAULT 'pending', - admin_note TEXT, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - resolved_at DATETIME, - FOREIGN KEY (user_id) REFERENCES users(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", - -'saved_billing' => "CREATE TABLE IF NOT EXISTS saved_billing ( - id INT AUTO_INCREMENT PRIMARY KEY, - user_id INT UNIQUE NOT NULL, - first_name VARCHAR(80), - last_name VARCHAR(80), - email VARCHAR(150), - address VARCHAR(200), - city VARCHAR(80), - state VARCHAR(2), - zip VARCHAR(10), - card_brand VARCHAR(30), - card_last4 VARCHAR(4), - card_exp_month VARCHAR(2), - card_exp_year VARCHAR(4), - sq_card_id VARCHAR(255), - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", - -'chat_messages' => "CREATE TABLE IF NOT EXISTS chat_messages ( - id INT AUTO_INCREMENT PRIMARY KEY, - user_id INT NOT NULL, - sender ENUM('user','admin') NOT NULL, - message TEXT NOT NULL, - is_read TINYINT(1) DEFAULT 0, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users(id) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", -]; - -foreach ($tables as $name => $sql) { - try { $pdo->exec($sql); ok("Table $name ✓"); } - catch (Exception $e) { err("Table $name: ".htmlspecialchars($e->getMessage())); } -} - -// ── ADD MISSING COLUMNS (compatible with MySQL 5.6/5.7/8) ── -// Check existence first, then ALTER — works on all MySQL versions -$addCols = [ - // [table, column, definition, after] - ['token_purchases', 'billing_name', "VARCHAR(160)", 'player_name'], - ['token_purchases', 'billing_address', "VARCHAR(200)", 'billing_name'], - ['token_purchases', 'billing_city', "VARCHAR(80)", 'billing_address'], - ['token_purchases', 'billing_state', "VARCHAR(2)", 'billing_city'], - ['token_purchases', 'billing_zip', "VARCHAR(10)", 'billing_state'], - ['token_purchases', 'billing_email', "VARCHAR(150)", 'billing_zip'], - ['token_purchases', 'is_custom', "TINYINT(1) DEFAULT 0", 'billing_email'], - ['token_purchases', 'failure_reason', "TEXT", 'is_custom'], - ['token_purchases', 'card_brand', "VARCHAR(30)", 'failure_reason'], - ['token_purchases', 'card_last4', "VARCHAR(4)", 'card_brand'], - ['token_purchases', 'receipt_url', "VARCHAR(512)", 'card_last4'], - ['token_purchases', 'admin_note', "TEXT", 'status'], - ['users', 'email_verified', "TINYINT(1) DEFAULT 0", 'email'], -]; - -foreach ($addCols as [$tbl, $col, $def, $after]) { - if (colExists($pdo, $tbl, $col)) { - ok("Column $tbl.$col already exists ✓"); - } else { - try { - $pdo->exec("ALTER TABLE `$tbl` ADD COLUMN `$col` $def AFTER `$after`"); - ok("Column $tbl.$col added ✓"); - } catch (Exception $e) { - err("Column $tbl.$col: ".htmlspecialchars($e->getMessage())); - } - } -} - -// ── FIX ADMIN email_verified ──────────────────────────────── -try { - $n = $pdo->exec("UPDATE users SET email_verified=1 WHERE is_admin=1"); - ok("Admin accounts email_verified set to 1 ($n updated)"); -} catch (Exception $e) { warn("Admin fix: ".htmlspecialchars($e->getMessage())); } - -// ── SUMMARY ───────────────────────────────────────────────── -$tables_now = $pdo->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN); -info("All tables: ".implode(', ', $tables_now).""); - -try { - $total = $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn(); - $admins = $pdo->query("SELECT COUNT(*) FROM users WHERE is_admin=1")->fetchColumn(); - info("Users: $total total, $admins admin(s)"); -} catch (Exception $e) {} -?> - -TomTomGames DB Install - -

🎮 TomTomGames — DB Install / Repair

-
Database:
- -
- - -
⚠ Delete install.php after use — it exposes DB structure.
- diff --git a/phpcheck.php b/phpcheck.php deleted file mode 100644 index f97dab1..0000000 --- a/phpcheck.php +++ /dev/null @@ -1,25 +0,0 @@ -&1"); - echo $f . ": " . trim($out) . "\n"; -} - -// Also test DB connection directly -try { - require_once __DIR__ . '/../../includes/config.php'; - require_once __DIR__ . '/../../includes/db.php'; - $v = db()->query("SELECT COUNT(*) FROM users")->fetchColumn(); - echo "\nDB OK — users: $v\n"; - $v2 = db()->query("SELECT version FROM app_version ORDER BY id DESC LIMIT 1")->fetchColumn(); - echo "App version: $v2\n"; -} catch (Throwable $e) { - echo "\nDB ERROR: " . $e->getMessage() . "\n"; - echo "File: " . $e->getFile() . " line " . $e->getLine() . "\n"; -} diff --git a/ref_test.php b/ref_test.php deleted file mode 100644 index 377e9b0..0000000 --- a/ref_test.php +++ /dev/null @@ -1,26 +0,0 @@ -query("SELECT id, username, referral_code FROM users")->fetchAll(); -$out = []; -foreach ($users as $u) { - $out[] = [ - 'id' => $u['id'], - 'username' => $u['username'], - 'referral_code' => $u['referral_code'], - 'referral_url' => 'https://tomtomgames.com/?ref=' . $u['referral_code'], - ]; -} - -// Also check tiers -$tiers = db()->query("SELECT id, name, min_referrals, tokens_per_ref, bonus_tokens, is_active FROM referral_tiers ORDER BY sort_order")->fetchAll(); - -echo json_encode([ - 'users' => $out, - 'tiers' => $tiers, - 'tier_count' => count($tiers), -], JSON_PRETTY_PRINT); diff --git a/referral_setup.php b/referral_setup.php deleted file mode 100644 index b5063b1..0000000 --- a/referral_setup.php +++ /dev/null @@ -1,96 +0,0 @@ -exec("CREATE TABLE IF NOT EXISTS referral_tiers ( - id INT AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(100) NOT NULL, - min_referrals INT NOT NULL DEFAULT 1, - tokens_per_ref DECIMAL(10,2) NOT NULL DEFAULT 10, - bonus_tokens DECIMAL(10,2) NOT NULL DEFAULT 0, - description VARCHAR(300), - is_active TINYINT(1) DEFAULT 1, - sort_order INT DEFAULT 0, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); -echo "referral_tiers table OK\n"; - -// 2. Seed tiers -$count = (int)db()->query("SELECT COUNT(*) FROM referral_tiers")->fetchColumn(); -if ($count == 0) { - $seeds = [ - ['Bronze Referrer', 1, 5, 0, 'Earn 5 tokens for each verified referral', 1, 0], - ['Silver Referrer', 5, 8, 25, 'Earn 8 tokens per referral + 25 bonus at 5 referrals', 1, 1], - ['Gold Referrer', 10, 10, 100, 'Earn 10 tokens per referral + 100 bonus at 10 referrals', 1, 2], - ['Elite Referrer', 25, 15, 250, 'Earn 15 tokens per referral + 250 bonus at 25 referrals', 1, 3], - ]; - $st = db()->prepare("INSERT INTO referral_tiers (name,min_referrals,tokens_per_ref,bonus_tokens,description,is_active,sort_order) VALUES (?,?,?,?,?,?,?)"); - foreach ($seeds as $s) $st->execute($s); - echo "4 tiers seeded\n"; -} else { - echo "Tiers already exist: $count\n"; -} - -// 3. referrals table -db()->exec("CREATE TABLE IF NOT EXISTS referrals ( - id INT AUTO_INCREMENT PRIMARY KEY, - referrer_id INT NOT NULL, - referred_id INT NOT NULL UNIQUE, - tier_id INT, - status ENUM('pending','verified','denied','deleted') DEFAULT 'pending', - tokens_awarded DECIMAL(10,2) DEFAULT 0, - admin_id INT, - admin_note VARCHAR(300), - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - resolved_at DATETIME -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); -echo "referrals table OK\n"; - -// 4. referral_social_shares -db()->exec("CREATE TABLE IF NOT EXISTS referral_social_shares ( - id INT AUTO_INCREMENT PRIMARY KEY, - user_id INT NOT NULL, - platform VARCHAR(50) NOT NULL, - bonus_tokens DECIMAL(10,2) DEFAULT 5, - status ENUM('pending','approved','denied') DEFAULT 'pending', - admin_id INT, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - resolved_at DATETIME -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); -echo "referral_social_shares table OK\n"; - -// 5. Add referral_code to users -$cols = array_column(db()->query("SHOW COLUMNS FROM users")->fetchAll(), 'Field'); -if (!in_array('referral_code', $cols)) { - db()->exec("ALTER TABLE users ADD COLUMN referral_code VARCHAR(20) UNIQUE"); - echo "referral_code column added\n"; -} - -// 6. Add referred_by to users -if (!in_array('referred_by', $cols)) { - db()->exec("ALTER TABLE users ADD COLUMN referred_by INT DEFAULT NULL"); - echo "referred_by column added\n"; -} - -// 7. Add referred_by to pending_registrations -$pcols = array_column(db()->query("SHOW COLUMNS FROM pending_registrations")->fetchAll(), 'Field'); -if (!in_array('referred_by', $pcols)) { - db()->exec("ALTER TABLE pending_registrations ADD COLUMN referred_by INT DEFAULT NULL"); - echo "pending_registrations.referred_by added\n"; -} - -// 8. Generate codes for users missing one -$users = db()->query("SELECT id FROM users WHERE referral_code IS NULL OR referral_code = ''")->fetchAll(); -$upd = db()->prepare("UPDATE users SET referral_code=? WHERE id=?"); -foreach ($users as $u) { - $code = strtoupper(substr(md5($u['id'].uniqid()), 0, 8)); - $upd->execute([$code, $u['id']]); -} -echo count($users) . " users given referral codes\n"; - -// 9. Show sample -$sample = db()->query("SELECT username, referral_code FROM users LIMIT 5")->fetchAll(); -foreach ($sample as $r) echo " " . $r['username'] . ": " . $r['referral_code'] . "\n"; - -echo "\nDONE\n"; diff --git a/test.php b/test.php deleted file mode 100644 index 00f0b67..0000000 --- a/test.php +++ /dev/null @@ -1,6 +0,0 @@ - PHP_VERSION, - 'time' => date('Y-m-d H:i:s'), - 'status' => 'ok' -]); diff --git a/test_login.php b/test_login.php deleted file mode 100644 index 08d99ca..0000000 --- a/test_login.php +++ /dev/null @@ -1,18 +0,0 @@ -$e->getMessage()])); } -ob_end_clean(); -header('Content-Type: application/json'); - -if ($_SERVER['REQUEST_METHOD'] === 'POST') { - $data = json_decode(file_get_contents('php://input'), true); - $result = loginUser($data['username'] ?? '', $data['password'] ?? ''); - if ($result['success']) unset($result['user']['password']); - echo json_encode($result); - exit; -} - -// GET - show users -$users = db()->query("SELECT id,username,alias,is_admin,email_verified,status FROM users")->fetchAll(); -echo json_encode(['users'=>$users,'session_id'=>session_id()]); diff --git a/test_mail.php b/test_mail.php deleted file mode 100644 index daaa45e..0000000 --- a/test_mail.php +++ /dev/null @@ -1,91 +0,0 @@ - - - - -Email Test - - - -

TomTomGames — Email Diagnostics

- -
-Server Info:
-PHP:
-Server:
-Hostname:
-mail() function:
-sendmail_path:
-SMTP: : -
- - -
-Send Result:
-To:
-mail() returned:
-Error:
- -
Check your inbox (and spam folder). If nothing arrives in 5 minutes, the server is not sending outbound mail. - -
mail() returned false — server cannot send email. You need to configure SMTP (PHPMailer) or enable sendmail. - -
- - -
-
- - - -
-
- -

Delete test_mail.php after diagnosis is complete.

- -