#spring-boot #escaping #decode #percentage
#весенняя загрузка #экранирование #декодировать #процент
Вопрос:
информация о версии:
Версия сервера: Apache Tomcat / 9.0.17
Сервер построен: 13 марта 2019 15:55:27 UTC
Номер сервера: 9.0.17.0
Название ОС: Windows 8.1
Версия ОС: 6.3
Архитектура: amd64
Версия JVM: 1.8.0_40-b25
spring-boot-2.1.4
spring-core-5.1.6
У меня есть HTML-страница, подобная этой: localhost/example/37%.html
(извините, я не могу запустить URL с http //, потому что страница редактирования автоматически изменит его на ссылку и добавит 25 после %)
когда я обращаюсь к этому URL, я получаю сообщение об ошибке: HTTP Status 400.
Так и должно быть, потому что % — это escape-символ.
поэтому я изменил URL на: localhost/example/37%.html .
на этот раз я получил новую ошибку:
Страница с ошибкой белой метки
В этом приложении нет явного сопоставления для / error, поэтому вы рассматриваете это как запасной вариант.
Чт, 03 сентября, 09:25:13 CST 2020
Произошла непредвиденная ошибка (тип = Внутренняя ошибка сервера, статус = 500).
URLDecoder: недопустимые шестнадцатеричные символы в шаблоне escape (%) — Для входной строки: «.h»
Я проверил консоль tomcat, она выводит сообщение об ошибке:
2020-09-03 09:25:12 [http-nio-8080-exec-3] ERROR
o.s.b.w.s.support.ErrorPageFilter - Forwarding to error page from request [/37%.html] due to exception [URLDecoder: Illegal hex characters in escape (%) pattern - For input string: ".h"]
java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape(%) pattern - For input string: ".h"
at java.net.URLDecoder.decode(URLDecoder.java:194)
at org.springframework.web.servlet.resource.PathResourceResolver.isInvalidEncodedPath(PathResourceResolver.java:285)
at org.springframework.web.servlet.resource.PathResourceResolver.isResourceUnderLocation(PathResourceResolver.java:254)
Похоже, что tomcat (или браузер) декодировал % до %, но springboot все еще декодирует % снова (PathResourceResolver.java )
Я не знаю, является ли это ошибкой или это правильный способ, которым springboot не разрешает % в URL
Ответ №1:
Я нашел кое-что интересное.
теперь у меня есть две веб-страницы, одна с именем 37%.html , другое имя 37%.html
Следуйте логике springboot, чтобы он дважды декодировал %, я получил доступ к этому URL:
localhost/example/37%25.html
и это покажет мне 37%.html , НО, это показывает мне 37%.html .
итак, сколько раз или как springboot декодировал %???
затем я нашел два файла класса в springboot:
ResourceHttpRequestHandler.java
PathResourceResolver.java
у всех них есть функция с именем: isInvalidEncodedPath()
код здесь:
ResourceHttpRequestHandler.isInvalidEncodedPath(путь)
private boolean isInvalidEncodedPath(String path) {
if(path.contains("%")) {
try {
String decodedPath = URLDecoder.decode(path, "UTF-8");
if(this.isInvalidPath(decodedPath)) {
return true;
}
decodedPath = this.processPath(decodedPath);
if(this.isInvalidPath(decodedPath)) {
return true;
}
} catch (UnsupportedEncodingException | IllegalArgumentException var3) {
;
}
}
return false;
}
PathResourceResolver.isInvalidEncodedPath(resourcePath)
private boolean isInvalidEncodedPath(String resourcePath) {
if(resourcePath.contains("%")) {
try {
String decodedPath = URLDecoder.decode(resourcePath, "UTF-8");
if(decodedPath.contains("../") || decodedPath.contains("..\")) {
this.logger.warn("Resolved resource path contains encoded "../" or "..\": " resourcePath);
return true;
}
} catch (UnsupportedEncodingException var3) {
;
}
}
return false;
}
видите что-то другое?? они оба выполняют URLDecoder.decode(resourcePath, «UTF-8»), но перехватывают разные исключения.
при доступе к URL springboot вызовет функцию в этом порядке:
1 ResourceHttpRequestHandler.isInvalidEncodedPath(путь)
2 PathResourceResolver.isInvalidEncodedPath(resourcePath)
поэтому, когда нажимается /37%.html в ResourceHttpRequestHandler.isInvalidEncodedPath(путь), он получает /37%.html , потому что tomcat (или браузер) декодирует % до %. затем URLDecoder.decode(«/37%.html «, «UTF-8»), вызывает исключение IllegalArgumentException, перехватывается, но ничего не делает, возвращает false . В PathResourceResolver.isInvalidEncodedPath(resourcePath),URLDecoder.decode(«/37%.html «, «UTF-8»), вызывает исключение IllegalArgumentException, не отслеживается, генерирует исключение.
при нажатии /37%25.html в ResourceHttpRequestHandler.isInvalidEncodedPath(путь), он получает /37%.html , URLDecoder.decode(«/37%.html «, «UTF-8»), никаких проблем. В PathResourceResolver.isInvalidEncodedPath(resourcePath),URLDecoder.decode(«/37%.html «, «UTF-8»), также без проблем. затем отобразите 37%.html
Если вы просто наберете /37%.html вы получите ошибку 400, недопустимый URI: isHexDigit.
итак, к сожалению, URL, который имеет % char, не может быть доступен правильно.
Комментарии:
1. О, другой интересный. Если вы используете jrebel для отладки в IDEA, и вы не увидите ошибку.каждая страница хороша! потому что PathResourceResolver. isInvalidEncodedPath(resourcePath) вызываться не будет. Я не знаю ПОЧЕМУ …. (версия jrebel 2018.1.6)