@PathVariable 包含反斜杠引号返回 400 错误请求

问题描述 投票:0回答:4

如果您使用 Spring Boot (2.5.3) 运行这个简单的 RestController:

@RestController
public class SampleRestController {

    @GetMapping("/search/{criteria}")
    public String hello(@PathVariable(name = "criteria") String criteria) {
        return "Hello: " + criteria;
    }

}

并尝试在浏览器中打开此链接:

 http://localhost:8080/search/%22%5C%22bug%5C%22%22 

然后您将收到“400 Bad Request”,由嵌入式 Tomcat 返回。

我不明白,这是 Tomcat 中的错误吗?这不是一个有效的网址吗?

编辑:根据一些回复:我一步步浏览了 Tomcat 9.0.50 源代码,看到了有关 ALLOW_BACKSLASH 的行。 true 或 false 值对我来说都没有好处,因为使用 true 时,它会用

\
替换
/
,使用 false 时,它会返回 400 Bad Request。 我需要的是允许反斜杠而不用斜杠替换它。

我的问题实际上是这是否是 Tomcat 中的一个错误,因为对我来说该 URL 似乎是有效的。从技术上讲,我并没有在 URL 中放入

\
,而是放入了 % 编码的反斜杠。如果不允许用户在 URL 中发送任何字符,那么 % 编码的目的是什么?

spring-mvc tomcat
4个回答
2
投票

请参阅上面 Piotr P. Karwasz 的评论以获得更好的解释。

Spring Boot(2.5.3)对应的tomcat版本是9.0.50。 通过查看CoyoteAdaptor

源码和Tomcat系统参数文档,url检查是通过系统属性ALLOW_BACKSLASH
通过标志
org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH
配置的,默认值为
false

... protected static final boolean ALLOW_BACKSLASH = Boolean.parseBoolean(System.getProperty("org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH", "false")); ...
要允许在 URL 中使用反斜杠,我们可以在运行应用程序时添加以下内容。

-Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true
此属性在 

tomcat 10.0.0-M4 后被替换。

删除 org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH 系统属性,替换为连接器上的allowBackslash 属性。 (雷姆)


1
投票
虽然

samabcde的回答为您的问题提供了解决方案,但让我回答您更一般的问题:

如果设置

org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true

,您的系统就会暴露于上述漏洞,并且所有 
%5C
 序列将在 
/
servletPath
 
pathInfo
 属性中显示为 
ServletRequest
。由于 
requestURI
 属性包含未解码的 URI 路径(参见 
这个问题),您的示例将起作用。


1
投票
是的,这似乎是一个无效的 URL,您还会在 Spring Boot 参考 RFC 7230 和 RFC 3986 规范时收到错误。 但是您可以使用一些查询参数来避免此错误,例如:

@GetMapping("/search") public String hello(@RequestParam(name = "criteria", required = false) String criteria) { return "Hello: " + criteria; }
并称其为:

http://localhost:8080/search?criteria=%22%5C%22bug%5C%22%22
    

0
投票
似乎 tomcat 在到达调度程序 servlet 之前阻止了这些请求。

使用Spring boot 3.2.4版本10.x.x。假设路径变量中包含 %2F 或 %5C 并收到 400 Bad request。 我已经尝试过上述方法,但不知何故它对我不起作用。感谢这篇

帖子但这对我有用,你可以尝试一下

@Bean public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() { return factory -> factory.addConnectorCustomizers(connector -> { connector.setAllowBackslash(true); connector.setEncodedSolidusHandling( EncodedSolidusHandling.DECODE.getValue()); }); }
    
© www.soinside.com 2019 - 2024. All rights reserved.