urlencoded正斜杠破坏URL


70

关于系统

我的专案中有这种格式的网址:

http://project_name/browse_by_exam/type/tutor_search/keyword/class/new_search/1/search_exam/0/search_subject/0

关键字/类别对表示使用“类别”关键字进行搜索。

我有一个通用的index.php文件,该文件针对项目中的每个模块执行。只有重写规则才能从URL中删除index.php:-

RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]

我在准备搜索URL时使用urlencode(),在阅读搜索URL时使用urldecode()。

问题

仅正斜杠字符破坏了URL,导致404页面未找到错误。例如,如果我搜索one/two的网址是

http://project_name/browse_by_exam/type/tutor_search/keyword/one%2Ftwo/new_search/1/search_exam/0/search_subject/0/page_sort/

我该如何解决?我需要将index.php隐藏在URL中。否则,如果不需要,正斜杠将没有问题,我可以使用以下URL:-

http://project_name/index.php?browse_by_exam/type/tutor_search/keyword/one
%2Ftwo/new_search/1/search_exam/0/search_subject/0

1
我觉得最好有这样的URL:-http://project_name/browse_by_exam?type/tutor_search/keyword/class %2Fnew/new_search/1/search_exam/0/search_subject/0 这样,我就摆脱了&param1 = value1&param2 = value2约定引起的可读性难题,而且我还可以允许正斜杠(现在在查询字符串部分使用?)我会避免AllowEncodedSlashes,因为Bobince说Also some tools or spiders might get confused by it. Although %2F to mean / in a path part is correct as per the standard, most of the web avoids it. url .htaccess url-routing
Sandeepan Nath 2010年

1
如果以这种方式使用?param1 = value1&param2 = value%2Fvalue,则可以使用%2F,但如果使用/ param1 = value1 / param2 = value%2Fvalue,则会抛出错误。
Ahmad

Answers:


145

%2F出于安全原因,Apache拒绝在路径部分中使用的所有URL :由于环境变量会自动进行URL解码(这很愚蠢,但长期以来一直存在)%2F/因此脚本通常无法(即,无需重写)区分两者之间的区别。PATH_INFOCGI规范的一部分,因此无可奈何)。

您可以使用AllowEncodedSlashes指令关闭此功能,但请注意,其他Web服务器仍将禁止使用此功能(没有选择将其关闭),并且其他字符也可能是忌讳的(例如%5C),%00尤其始终是被Apache和IIS阻止。因此,如果您的应用程序依赖于%2F在路径部分中包含字符或其他字符,则将限制您的兼容性/部署选项。

我在准备搜索URL时正在使用urlencode()

您应该使用rawurlencode(),而不是urlencode()转义路径部分。urlencode()被错误命名,它实际上是用于application/x-www-form-urlencoded查询字符串或POST请求正文中的数据,而不用于URL的其他部分。

区别在于+并不意味着路径部分中有空间。rawurlencode()会正确地产生%20,这将对表单编码的数据和URL的其他部分都起作用。


4
啊,这就是为什么不使用斜线的原因。完善的诊断和治疗。
Pekka 2010年

1
+1我尝试在他的另一个问题中解释其中的一些问题,但是您所做的事情比我能做到的更加连贯。
Tim Stone

6
嗨,Bobince,rawurlencode()也将正斜杠转换%2F为仍然破坏我的URL的斜杠。我实际上不了解如何rawurlencode()解决我的问题。
Sandeepan Nath 2010年

2
并非如此,这是+vs.的附带问题%20。解决方法是AllowEncodedSlashes,尽管依靠可以减少部署的可能性(即,您无法将其部署在IIS上,并且其他用户(如果有)将无法部署,如果他们使用的是无法访问的共享托管)到httpd.conf)。还有一些工具或蜘蛛可能会对此感到困惑。尽管%2F按照标准表示/路径部分是正确的,但大多数网络都避免使用它。
bobince 2010年

1
是的,查询字符串中必须允许任何编码字节序列。尽管根据URL RFC,任何编码的字节在路径组件中在技术上都是有效的,但由于传统上将路径部分用作文件名,因此服务器在使用其中的某些组件时会遇到麻烦。除此之外%00%2F%5C,IIS也会给你用的是不是合法的UTF-8序列路径非ASCII字节序列的麻烦。
bobince 2010年

9

网址编码后,将%2F替换为%252F

的PHP

function custom_http_build_query($query=array()){

    return str_replace('%2F','%252F', http_build_query($query));
}

通过htaccess处理请求

.htaccess

RewriteCond %{REQUEST_URI} ^(.*?)(%252F)(.*?)$ [NC]
RewriteRule . %1/%3 [R=301,L,NE]

资源资源

http://www.leakon.com/archives/865


非常感谢,我的问题是没有NE标志。
EmRa228 '20

4

在Apache中,AllowEncodedSlashes On可以防止使用404立即拒绝该请求。

关于解决此问题的另一种想法。



4

我在url get param中存在斜线相同的问题,在我的情况下,以下php代码有效:

$value = "hello/world"
$value = str_replace('/', '/', $value;?>
$value = urlencode($value);?>
# $value is now hello%26%2347%3Bworld

我先用html实体替换斜杠,然后再进行url编码。


2

在我的托管帐户上,此问题是由为所有帐户自动设置的ModSecurity规则引起的。在我报告此问题后,他们的管理员迅速为我的帐户删除了此规则。


1

使用其他字符并替换斜杠服务器端

例如,Drupal.org使用%21(感叹号字符!)表示url参数中的斜杠。

以下两个链接均有效:

https://api.drupal.org/api/drupal/includes%21common.inc/7

https://api.drupal.org/api/drupal/includes!common.inc/7

如果您担心字符可能与参数中的字符冲突,请使用字符组合。

因此,您的网址应为 http:// project_name / browse_by_exam / type / tutor_search / keyword / one_-!two / new_search / 1 / search_exam / 0 / search_subject / 0

使用js进行更改,然后将其转换回斜杠服务器端。


1

这是我的拙见。!!!! 别 !!!!更改服务器上的设置以使您的参数正常工作。这是一枚定时炸弹,等待您更换服务器的某天发生。

我发现最好的方法就是将参数转换为base 64编码。因此,在我的情况下,我从Angular调用了php服务,并传递了可以包含任何值的参数。

所以我在客户端的打字稿代码看起来像这样:

    private encodeParameter(parm:string){
    if (!parm){
        return null;
    }
    return btoa(parm);
}

并在php中检索参数:

    $item_name = $request->getAttribute('item_name');
    $item_name = base64_decode($item_name); 

0

此问题的标准解决方案是通过使可能包含斜杠的参数成为URL中的最后一个参数来允许斜杠。

对于产品代码URL,您将有...

mysite.com/product/details/PR12345/22

对于搜索词,您将拥有

http://project/search_exam/0/search_subject/0/keyword/Psychology/Management

(这里的关键词是心理学/管理学)

处理第一个“命名”参数,然后将其余参数组合为产品代码或关键字,这不是大量的工作。

一些框架在其路由定义中内置了此功能。

这不适用于涉及两个包含斜杠的参数的用例。


0

对我来说很简单,使用base64_encode

$term = base64_encode($term) 
$url = $youurl.'?term='.$term

在您解码该词之后

$term = base64_decode($['GET']['term'])

这样编码“ /”和“ \”


-1

我对具有正斜杠的URL部分使用javascript encodeURI()函数,应将其视为字符而不是http地址。例如:

"/api/activites/" + encodeURI("?categorie=assemblage&nom=Manipulation/Finition")

参见http://www.w3schools.com/tags/ref_urlencode.asp


问题是在将URI编码为%2F后处理该URI-请参见已接受的答案Apache denies all URLs with %2F in the path part
Jordan Jordan

-1

我通过使用2个这样的自定义函数解决了这个问题:

function slash_replace($query){

    return str_replace('/','_', $query);
}

function slash_unreplace($query){

    return str_replace('_','/', $query);
}

因此,我可以调用以下代码:

rawurlencode(slash_replace($param))

并解码我可以打电话

slash_unreplace(rawurldecode($param);

干杯!


-3

您可以%2F通过以下方式使用它:
?param1=value1&param2=value%2Fvalue

但是如果使用/param1=value1/param2=value%2Fvalue它会抛出错误。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.