This commit is contained in:
Mateusz Gruszczyński committed 2026-10-09 14:07:41 +02:00
1 parent dd8c195600
commit 3e33982cd3
20 files changed
+287 -52

No files matched your search

+39
View File
@@ -106,6 +106,38 @@ async fn serve_inner(
{
return builtin_error_response(StatusCode::FORBIDDEN, &method);
}
// An existing PHP script followed by PATH_INFO is a valid virtual PHP
// request, even though the full URL is not a filesystem path. Dispatch it
// before try_files can rewrite /static.php/skins/... to /index.php (as in
// Roundcube 1.7), while still applying the original path's rewrites and
// access controls above.
if let Ok(components) = path_components(&rewritten_path) {
if let Some((script_path, path_info)) = resolve_php_path_info(service, &components).await {
let script_components = path_components(&script_path).unwrap_or_default();
if hardening_denied_path(service, &script_path)
|| script_components.iter().any(|component| htaccess::protected_component(service.htaccess.as_ref(), component))
|| htaccess::denied(service.htaccess.as_ref(), &script_path)
{
return builtin_error_response(StatusCode::FORBIDDEN, &method);
}
if let Some(php) = php_for_path(service, &PathBuf::from(&script_path)) {
return php_response(
service,
php,
method,
headers,
uri,
script_path,
Some(path_info),
rewritten_query,
body,
context,
)
.await;
}
}
}
let (effective_path, effective_query) = match resolve_try_files(
service,
&rewritten_path,
@@ -140,6 +172,13 @@ async fn serve_inner(
if matches!(error.kind(), io::ErrorKind::NotFound | io::ErrorKind::NotADirectory) =>
{
if let Some((script_path, path_info)) = resolve_php_path_info(service, &components).await {
let script_components = path_components(&script_path).unwrap_or_default();
if hardening_denied_path(service, &script_path)
|| script_components.iter().any(|component| htaccess::protected_component(service.htaccess.as_ref(), component))
|| htaccess::denied(service.htaccess.as_ref(), &script_path)
{
return builtin_error_response(StatusCode::FORBIDDEN, &method);
}
let public_path = PathBuf::from(&script_path);
if let Some(php) = php_for_path(service, &public_path) {
return php_response(