From 08cc7f673c377bf88897743e340097e93f1e95f4 Mon Sep 17 00:00:00 2001 From: ftimme <ft@falkotimme.com> Date: Wed, 16 Jan 2013 09:30:05 -0500 Subject: [PATCH] - Changed regex for redirect path (Web sites, subdomains, vhost subdomains, alias domains) and web folder (vhost subdomains) so that ".." is not allowed (in order to prevent path traversals). - nginx: don't allow folders for proxy redirects (subdomains and alias domains); URL is required. - nginx: modified rewriting. --- server/plugins-available/nginx_plugin.inc.php | 151 +++++++++++++++++++++++++++---------------------- 1 files changed, 83 insertions(+), 68 deletions(-) diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php index 4234f94..1c37a5a 100644 --- a/server/plugins-available/nginx_plugin.inc.php +++ b/server/plugins-available/nginx_plugin.inc.php @@ -982,6 +982,7 @@ // Rewrite rules $own_rewrite_rules = array(); $rewrite_rules = array(); + $local_rewrite_rules = array(); if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { if(substr($data['new']['redirect_path'],-1) != '/') $data['new']['redirect_path'] .= '/'; if(substr($data['new']['redirect_path'],0,8) == '[scheme]'){ @@ -1011,6 +1012,7 @@ switch($data['new']['subdomain']) { case 'www': + $exclude_own_hostname = ''; if(substr($data['new']['redirect_path'],0,1) == '/'){ // relative path if($data['new']['redirect_type'] == 'proxy'){ $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; @@ -1033,6 +1035,7 @@ break; } else { $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'],1).(substr($tmp_redirect_path_parts['path'],1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; } } else { // external URL @@ -1041,7 +1044,8 @@ $vhost_data['use_proxy'] = 'y'; $rewrite_subdir = $tmp_redirect_path_parts['path']; if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; } } unset($tmp_redirect_path); @@ -1052,11 +1056,13 @@ 'rewrite_target' => $data['new']['redirect_path'], 'rewrite_exclude' => $rewrite_exclude, 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, 'proxy_directives' => $final_proxy_directives, 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); break; case '*': + $exclude_own_hostname = ''; if(substr($data['new']['redirect_path'],0,1) == '/'){ // relative path if($data['new']['redirect_type'] == 'proxy'){ $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; @@ -1081,6 +1087,7 @@ break; } else { $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'],1).(substr($tmp_redirect_path_parts['path'],1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; } } else { // external URL @@ -1089,7 +1096,8 @@ $vhost_data['use_proxy'] = 'y'; $rewrite_subdir = $tmp_redirect_path_parts['path']; if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; } } unset($tmp_redirect_path); @@ -1100,12 +1108,14 @@ 'rewrite_target' => $data['new']['redirect_path'], 'rewrite_exclude' => $rewrite_exclude, 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, 'proxy_directives' => $final_proxy_directives, 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); break; default: if(substr($data['new']['redirect_path'],0,1) == '/'){ // relative path + $exclude_own_hostname = ''; if($data['new']['redirect_type'] == 'proxy'){ $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'],0,-1); @@ -1127,6 +1137,7 @@ break; } else { $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'],1).(substr($tmp_redirect_path_parts['path'],1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; } } else { // external URL @@ -1135,7 +1146,8 @@ $vhost_data['use_proxy'] = 'y'; $rewrite_subdir = $tmp_redirect_path_parts['path']; if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; } } unset($tmp_redirect_path); @@ -1146,6 +1158,7 @@ 'rewrite_target' => $data['new']['redirect_path'], 'rewrite_exclude' => $rewrite_exclude, 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, 'proxy_directives' => $final_proxy_directives, 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); @@ -1202,7 +1215,7 @@ $final_proxy_directives = false; } - if($alias['redirect_type'] == '' || $alias['redirect_path'] == '') { + if($alias['redirect_type'] == '' || $alias['redirect_path'] == '' || substr($alias['redirect_path'],0,1) == '/') { switch($alias['subdomain']) { case 'www': $server_alias[] = 'www.'.$alias['domain'].' '.$alias['domain'].' '; @@ -1225,8 +1238,44 @@ } } - // Rewriting - if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') { + // Local Rewriting (inside vhost server {} container) + if($alias['redirect_type'] != '' && substr($alias['redirect_path'],0,1) == '/' && $alias['redirect_type'] != 'proxy') { // proxy makes no sense with local path + if(substr($alias['redirect_path'],-1) != '/') $alias['redirect_path'] .= '/'; + $rewrite_exclude = '(?!/\b('.substr($alias['redirect_path'],1,-1).(substr($alias['redirect_path'],1,-1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + switch($alias['subdomain']) { + case 'www': + // example.com + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + + // www.example.com + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => 'www.'.$alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + break; + case '*': + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => '^('.str_replace('.', '\.', $alias['domain']).'|.+\.'.str_replace('.', '\.', $alias['domain']).')$', + 'local_redirect_operator' => '~*', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + break; + default: + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + } + } + + // External Rewriting (extra server {} containers) + if($alias['redirect_type'] != '' && $alias['redirect_path'] != '' && substr($alias['redirect_path'],0,1) != '/') { if(substr($alias['redirect_path'],-1) != '/') $alias['redirect_path'] .= '/'; if(substr($alias['redirect_path'],0,8) == '[scheme]'){ if($alias['redirect_type'] != 'proxy'){ @@ -1238,21 +1287,15 @@ switch($alias['subdomain']) { case 'www': - if(substr($alias['redirect_path'],0,1) == '/'){ // relative path - if($alias['redirect_type'] == 'proxy'){ - $rewrite_subdir = substr($alias['redirect_path'],1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); - } - $alias['redirect_path'] = ($alias['redirect_type'] == 'proxy'? 'http' : '$scheme').'://'.($vhost_data['seo_redirect_enabled'] ? $vhost_data['seo_redirect_target_domain'] : $data['new']['domain']).$alias['redirect_path']; - } else { - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); - } + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; } + if($alias['redirect_type'] != 'proxy'){ if(substr($alias['redirect_path'],-1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'],0,-1); } @@ -1272,26 +1315,7 @@ 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - - - if(substr($alias['redirect_path'],0,1) == '/'){ // relative path - if($alias['redirect_type'] == 'proxy'){ - $rewrite_subdir = substr($alias['redirect_path'],1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); - } - $alias['redirect_path'] = ($alias['redirect_type'] == 'proxy'? 'http' : '$scheme').'://'.($vhost_data['seo_redirect_enabled'] ? $vhost_data['seo_redirect_target_domain'] : $data['new']['domain']).$alias['redirect_path']; - } else { - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); - } - } - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'],-1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'],0,-1); - } + // Add SEO redirects for alias domains $alias_seo_redirects2 = array(); if($alias['seo_redirect'] != ''){ @@ -1310,21 +1334,15 @@ 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); break; case '*': - if(substr($alias['redirect_path'],0,1) == '/'){ // relative path - if($alias['redirect_type'] == 'proxy'){ - $rewrite_subdir = substr($alias['redirect_path'],1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); - } - $alias['redirect_path'] = ($alias['redirect_type'] == 'proxy'? 'http' : '$scheme').'://'.($vhost_data['seo_redirect_enabled'] ? $vhost_data['seo_redirect_target_domain'] : $data['new']['domain']).$alias['redirect_path']; - } else { - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); - } + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; } + if($alias['redirect_type'] != 'proxy'){ if(substr($alias['redirect_path'],-1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'],0,-1); } @@ -1346,21 +1364,15 @@ 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); break; default: - if(substr($alias['redirect_path'],0,1) == '/'){ // relative path - if($alias['redirect_type'] == 'proxy'){ - $rewrite_subdir = substr($alias['redirect_path'],1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); - } - $alias['redirect_path'] = ($alias['redirect_type'] == 'proxy'? 'http' : '$scheme').'://'.($vhost_data['seo_redirect_enabled'] ? $vhost_data['seo_redirect_target_domain'] : $data['new']['domain']).$alias['redirect_path']; - } else { - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) == '/') $rewrite_subdir = substr($rewrite_subdir,0,-1); - } + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; } + if($alias['redirect_type'] != 'proxy'){ if(substr($alias['redirect_path'],-1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'],0,-1); } @@ -1412,6 +1424,9 @@ if(count($own_rewrite_rules) > 0) { $tpl->setLoop('own_redirects',$own_rewrite_rules); } + if(count($local_rewrite_rules) > 0) { + $tpl->setLoop('local_redirects',$local_rewrite_rules); + } if(count($alias_seo_redirects) > 0) { $tpl->setLoop('alias_seo_redirects',$alias_seo_redirects); } -- Gitblit v1.9.1