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

@PathVariable containing backslash quote returns 400 Bad Request

如果你 运行 这个简单的 RestController with Spring Boot (2.5.3):

@RestController
public class SampleRestController {

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

}

并尝试在您的浏览器中打开此 link:

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

然后你会得到“400 Bad Request”,由嵌入式Tomcat返回。

我不明白,这是 Tomcat 中的错误吗?这不是有效的 URL 吗?

编辑:根据一些回复:我逐步浏览了 Tomcat 9.0.50 源代码并看到了关于 ALLOW_BACKSLASH。 true 或 false 的值对我来说都不好,因为 true 它将 \ 替换为 / 并且 false 它将 returns 400 Bad Request 替换。 我需要的是允许反斜杠而不用斜杠替换它。

我的问题是这是否真的是 Tomcat 中的错误,因为对我来说 URL 似乎是有效的。从技术上讲,我并没有将 \ 放入 URL,而是放置了一个 % 编码的反斜杠。如果不允许用户发送 URL 中的任何字符,% 编码的目的是什么?

是的,它似乎是一个无效的 URL,您还通过 Spring 引导参考 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 

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

tomcat版本对应SpringBoot(2.5.3)为9.0.50。 通过检查 source code of CoyoteAdaptor and Tomcat System parameter documentation,url 检查由标志 ALLOW_BACKSLASH 通过系统 属性 org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH 配置,默认值为 false。 =19=]

...
    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之后。

Remove org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH system property, replaced by the allowBackslash attribute on the Connector. (remm)

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

  • 您的 URL 完全有效,尽管 RFC 3986, section 7.3 出于安全原因允许施加一些限制,
  • 这些限制不是 Tomcat 错误,因为它们是作为对 CVE-2007-0450 的回答而引入的。在 Tomcat 6.0.10 之前,序列 /%2F%5C 用于将请求 URI 拆分为组件。如果 Tomcat 位于仅转发应用程序的代理后面(假设 /app),您可以使用 /app/%5C../manager/html 访问 Tomcat 管理器。

如果您设置 org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true,您的系统将面临上述漏洞,所有 %5C 序列将在 servletPathpathInfo 中显示为 / ServletRequest 个属性。由于 requestURI 属性 包含未解码的 URI 路径(参见 this question),您的示例将起作用。