From 3924c934943811d3668a64b0f914b94da52cc489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=82=B6=E3=82=AB=E3=83=AA=E3=82=A2=E3=82=B9=E3=83=BB?= =?UTF-8?q?=E3=82=A6=E3=82=A3=E3=83=AA=E3=82=A2=E3=83=A0=E3=83=BB=E3=83=9D?= =?UTF-8?q?=E3=83=BC=E3=82=B8=E3=83=BC?= <26689019-pancakes1234@users.noreply.gitlab.com> Date: Thu, 29 May 2025 00:34:32 +0900 Subject: [PATCH] Edit index.php --- API/index.php | 320 ++++++++++++++++++++++++++++---------------------- 1 file changed, 179 insertions(+), 141 deletions(-) diff --git a/API/index.php b/API/index.php index 706d4ce..e45c86f 100644 --- a/API/index.php +++ b/API/index.php @@ -1,21 +1,50 @@ true, + 'secure' => true, // Ensure HTTPS is used in production + 'samesite' => 'Strict' +]); session_start(); -// === Login & Authentication === -// Only proceed if the current session is authenticated. -// If not, show a login form. -if (!isset($_SESSION['logged_in'])) { - if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['username'], $_POST['password'])) { - $user_env = getenv('user'); // environment variable "user" - $pass_env = getenv('pass'); // environment variable "pass" - if ($_POST['username'] === $user_env && $_POST['password'] === $pass_env) { - $_SESSION['logged_in'] = true; - header("Location: index.php"); - exit; +// --- CSRF Utility Functions --- +function getCsrfToken() { + if (empty($_SESSION['csrf_token'])) { + $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); + } + return $_SESSION['csrf_token']; +} + +function validateCsrfToken($token) { + return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token); +} + +// --- Login and Authentication --- +if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) { + if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['username'], $_POST['password'], $_POST['csrf_token'])) { + if (!validateCsrfToken($_POST['csrf_token'])) { + $error = "Invalid CSRF token."; } else { - $error = "Invalid credentials."; + $envUser = getenv('user'); + $envPass = getenv('pass'); + // Using hash_equals for timing attack prevention + if (hash_equals($_POST['username'], $envUser) && hash_equals($_POST['password'], $envPass)) { + $_SESSION['logged_in'] = true; + session_regenerate_id(true); + header("Location: " . $_SERVER['PHP_SELF']); + exit; + } else { + $error = "Invalid credentials."; + } } } + $loginToken = getCsrfToken(); ?> @@ -64,8 +93,9 @@ if (!isset($_SESSION['logged_in'])) {

Login

- {$error}

"; ?> -
+ " . htmlspecialchars($error) . "

"; } ?> + + @@ -76,65 +106,76 @@ if (!isset($_SESSION['logged_in'])) { &1'; + return trim(shell_exec($cmd)); + } + return "Directory not found."; } -$output = ""; // To hold any output from actions +function handleUpdateAction() { + // Only allow updates using a POST request with a valid CSRF token. + if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['csrf_token']) || !validateCsrfToken($_POST['csrf_token'])) { + return "Unauthorized update request."; + } + $botDir = '/home/server/wdiscordbotserver'; + $result = ""; + if (is_dir($botDir)) { + $rmCmd = 'rm -rf ' . escapeshellarg($botDir) . ' 2>&1'; + $result .= shell_exec($rmCmd); + } + $cloneCmd = 'git clone https://gitlab.com/pancakes1234/wdiscordbotserver.git ' . escapeshellarg($botDir) . ' 2>&1'; + $result .= shell_exec($cloneCmd); + return $result; +} -// Handle the different actions. -switch ($action) { - case "version": - // Gets the current commit from /home/server/wdiscordbotserver. - $botDir = '/home/server/wdiscordbotserver'; - if (is_dir($botDir)) { - $cmd = 'cd ' . escapeshellarg($botDir) . ' && git rev-parse HEAD 2>&1'; - $output = shell_exec($cmd); +function handleDataAction() { + $baseDir = realpath('/home/server'); + $file = $_GET['file'] ?? null; + $response = ""; + if ($file) { + $realFile = realpath($file); + if ($realFile === false || strpos($realFile, $baseDir) !== 0) { + $response = "Invalid file."; } else { - $output = "Directory not found."; - } - break; - - case "update": - // Removes the folder and clones the repository anew. - $botDir = '/home/server/wdiscordbotserver'; - if (is_dir($botDir)) { - $rmCmd = 'rm -rf ' . escapeshellarg($botDir) . ' 2>&1'; - $output .= shell_exec($rmCmd); - } - $cloneCmd = 'git clone https://gitlab.com/pancakes1234/wdiscordbotserver.git ' . escapeshellarg($botDir) . ' 2>&1'; - $output .= shell_exec($cloneCmd); - break; - - case "data": - // If editing a file, process its content. - if (isset($_GET['file'])) { - $file = $_GET['file']; - $baseDir = realpath('/home/server'); - $realFile = realpath($file); - if ($realFile === false || strpos($realFile, $baseDir) !== 0) { - $output = "Invalid file."; - } else { - if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['content'])) { - file_put_contents($realFile, $_POST['content']); - $output = "File updated successfully."; + if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['content'], $_POST['csrf_token'])) { + if (!validateCsrfToken($_POST['csrf_token'])) { + $response = "Invalid CSRF token."; + } else { + if (file_put_contents($realFile, $_POST['content']) !== false) { + $response = "File updated successfully."; + } else { + $response = "Failed to update file."; + } } } } - break; + } + return $response; +} - // Other actions (such as terminal) will be handled in the UI below. +// --- Process Request Actions --- +$action = $_GET['action'] ?? ($_POST['action'] ?? ""); +switch ($action) { + case "version": + $output = handleVersionAction(); + break; + case "update": + $output = handleUpdateAction(); + break; + case "data": + $output = handleDataAction(); + break; + // Additional action cases (e.g., "terminal") can be handled below. default: - // No action or unrecognized action. break; } ?> @@ -143,7 +184,6 @@ switch ($action) { Discord Bot Admin API + +

Discord Bot Admin API

- + + + + +
- +
- Files in {$baseDir}"; - echo "
    "; - $iterator = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($baseDir, RecursiveDirectoryIterator::SKIP_DOTS) - ); - foreach ($iterator as $fileInfo) { - $filePath = $fileInfo->getPathname(); - echo "
  • " . htmlspecialchars($filePath) . "
  • "; + +

    Files in

    +
      + getPathname(); + echo "
    • " . htmlspecialchars($filePath) . "
    • "; + } + } catch (Exception $e) { + echo "
    • Error reading files: " . htmlspecialchars($e->getMessage()) . "
    • "; } - echo "
    "; - } else { + ?> +
+ Invalid file.

"; - } else { - echo "

Editing: " . htmlspecialchars($realFile) . "

"; - echo "
"; - echo "
"; - echo ""; - echo ""; - echo "
"; - } - } - } - // === Terminal Section === - elseif ($action === "terminal") : - // This section provides two terminal options: - // 1. Wetty Terminal via an iframe (assumes Wetty is running on port 3000) - // 2. A direct integration of xterm.js (which connects via WebSocket to a Node.js pty server on port 3001) - ?> + if ($realFile === false || strpos($realFile, $baseDir) !== 0): ?> +

Invalid file.

+ +

Editing:

+
+ +
+ + +
+

Wetty Terminal

- +
- - - - - +