Compare commits

..

2 commits

2 changed files with 23 additions and 11 deletions

View file

@ -98,6 +98,8 @@ if (str_ends_with($ctx->requestPath, 'feed.xml')) {
// Render full content for each item // Render full content for each item
foreach ($items as &$item) { foreach ($items as &$item) {
$item['content'] = ''; $item['content'] = '';
$itemMetadata = loadMetadata($item['dirPath']);
getPluginManager()->loadPagePlugins($itemMetadata);
$contentFiles = findAllContentFiles($item['dirPath']); $contentFiles = findAllContentFiles($item['dirPath']);
foreach ($contentFiles as $file) { foreach ($contentFiles as $file) {
$item['content'] .= renderContentFile($file, $ctx); $item['content'] .= renderContentFile($file, $ctx);

View file

@ -1,29 +1,39 @@
<?php <?php
// test
// Serve static files from /app directory // Serve static files from /app directory
$requestUri = $_SERVER['REQUEST_URI']; $requestUri = $_SERVER['REQUEST_URI'];
$file = preg_replace('#^/app/#', '', parse_url($requestUri, PHP_URL_PATH)); $file = preg_replace('#^/app/#', '', parse_url($requestUri, PHP_URL_PATH));
$file = str_replace(['../', '..\\'], '', $file); // Prevent directory traversal
// Map request paths to actual file paths // Map request paths to allowed base directories
$basePath = __DIR__ . '/'; $customBasePath = dirname(__DIR__) . '/custom/';
$customBasePath = dirname(__DIR__) . '/'; $appBasePath = __DIR__ . '/default/';
if (str_starts_with($file, 'styles/')) { if (str_starts_with($file, 'styles/')) {
$filePath = $customBasePath . 'custom/' . $file; $allowedBase = realpath($customBasePath . 'styles');
$filePath = $customBasePath . $file;
} elseif (str_starts_with($file, 'fonts/')) { } elseif (str_starts_with($file, 'fonts/')) {
$filePath = $customBasePath . 'custom/' . $file; $allowedBase = realpath($customBasePath . 'fonts');
$filePath = $customBasePath . $file;
} elseif (str_starts_with($file, 'assets/')) { } elseif (str_starts_with($file, 'assets/')) {
$filePath = $customBasePath . 'custom/' . $file; $allowedBase = realpath($customBasePath . 'assets');
$filePath = $customBasePath . $file;
} elseif (str_starts_with($file, 'default-styles/')) { } elseif (str_starts_with($file, 'default-styles/')) {
$filePath = $basePath . 'default/' . substr($file, 15); // Remove 'default-styles/' prefix $allowedBase = realpath($appBasePath . 'styles');
$filePath = $appBasePath . 'styles/' . substr($file, 15);
} else { } else {
http_response_code(404); http_response_code(404);
exit; exit;
} }
// Check if file exists and is readable // Resolve real path and verify it's within the allowed directory
if (!file_exists($filePath) || !is_readable($filePath)) { $realPath = realpath($filePath);
if ($realPath === false || $allowedBase === false || !str_starts_with($realPath, $allowedBase . '/')) {
http_response_code(404);
exit;
}
$filePath = $realPath;
// Check if file is readable
if (!is_readable($filePath)) {
http_response_code(404); http_response_code(404);
exit; exit;
} }