Перейти к основному содержимому

Использование символа косой черты в URL-адресах Spring

· 4 мин. чтения

1. Введение

При разработке веб-сервисов нам может понадобиться иметь дело со сложными или неожиданными путями URL, которые могут содержать косые черты . Как следствие, мы можем столкнуться с проблемами с веб-серверами или платформами, которые мы используем.

В частности, Spring может быть немного сложным в этом отношении из-за конфигураций по умолчанию, которые он предоставляет.

В этом руководстве мы покажем некоторые распространенные решения и рекомендации по обработке URL-адресов с косой чертой в Spring . Мы также увидим, почему мы не должны использовать некоторые распространенные хаки для решения этих проблем. Продолжайте читать, чтобы узнать об этом больше!

2. Разберите запрос вручную

В наших веб-сервисах иногда нам нужно сопоставить все запросы по определенному пути с одной и той же конечной точкой. Что еще хуже, мы можем не знать, как будет выглядеть остальная часть пути. Нам также может понадобиться как-то получить этот путь в качестве параметра, чтобы потом использовать его.

Допустим, мы можем получать запросы с любым путем в /mypaths :

http://localhost:8080/mypaths/any/custom/path

И предположим, что мы хотим сохранить все эти разные пути в базе данных, чтобы знать, какие запросы мы получаем.

Первое решение, которое, вероятно, придет нам в голову, — захватить динамическую часть пути в PathVariable :

@GetMapping("mypaths/{anything}")
public String pathVariable(@PathVariable("anything") String anything) {
return anything;
}

К сожалению, вскоре мы обнаруживаем, что это возвращает 404 , если PathVariable содержит косую черту . Символ косой черты является стандартным разделителем пути URI , и все, что идет после него, считается новым уровнем в иерархии путей. Как и ожидалось, Spring следует этому стандарту.

Мы можем легко решить эту проблему, создав запасной вариант для всех запросов по определенному пути, используя подстановочный знак `` ** :

@GetMapping("all/**")
public String allDirectories(HttpServletRequest request) {
return request.getRequestURI()
.split(request.getContextPath() + "/all/")[1];
}

Затем мы должны сами разобрать URI, чтобы получить интересующую нас часть пути.

Это решение очень удобно при работе с URL-подобными параметрами , но, как мы увидим в следующем разделе, его недостаточно для некоторых других случаев.

3. Используйте параметры запроса

В отличие от нашего предыдущего примера, есть и другие случаи, когда мы не просто сопоставляем разные пути, но и получаем любую строку в качестве параметра в URL-адресе.

Давайте представим, что в нашем предыдущем примере мы делаем запрос с параметром пути, который содержит последовательные косые черты :

http://localhost:8080/all/http://myurl.com

Сначала мы могли подумать, что это должно работать, но вскоре мы поняли, что наш контроллер возвращает http:/myurl.com. Это происходит потому, что Spring Security нормализует URL-адреса и заменяет любую двойную косую черту одинарной .

Spring также нормализует другие последовательности в URL-адресах, такие как обход пути. Эти меры предосторожности необходимы для предотвращения обхода вредоносными URL-адресами определенных ограничений безопасности , как описано в официальной документации Spring Security .

В этих случаях настоятельно рекомендуется вместо этого использовать параметры запроса:

@GetMapping("all")
public String queryParameter(@RequestParam("param") String param) {
return param;
}

Таким образом, мы можем получить любой параметр String без этих ограничений безопасности, и наш веб-сервис будет более надежным и безопасным.

4. Избегайте обходных путей

Представленные нами решения могут подразумевать некоторые изменения в дизайне наших отображений. Это может побудить нас использовать некоторые общие обходные пути, чтобы наши исходные конечные точки работали при получении косой черты в URL-адресах.

Наиболее распространенный обходной путь, вероятно, состоит в том, чтобы закодировать косые черты в параметрах пути. Однако в прошлом сообщалось о некоторых уязвимостях в системе безопасности, и большинство веб-серверов и серверов приложений реагировали на них, запрещая закодированные косые черты по умолчанию . Это поведение по-прежнему можно изменить, просто изменив соответствующий параметр, как в Tomcat .

Другие, такие как Apache Server , пошли немного дальше и представили возможность разрешать закодированные косые черты без их декодирования, чтобы они не интерпретировались как разделители пути. В любом случае, это не рекомендуется, и это может привести к потенциальным рискам безопасности.

С другой стороны, веб-фреймворки также принимают некоторые меры предосторожности. Как мы видели ранее, Spring добавляет некоторые механизмы для защиты от менее строгих контейнеров сервлетов . Итак, если мы разрешаем закодированные косые черты на нашем сервере, нам все равно нужно разрешить их в Spring.

Наконец, есть и другие обходные пути, такие как изменение нормализации URI, которую Spring предоставляет по умолчанию. Как и прежде, мы должны быть очень осторожны, если изменим эти значения по умолчанию.

5. Вывод

В этой короткой статье мы показали некоторые решения для работы с косой чертой в URL-адресах в Spring. Мы также представили некоторые проблемы безопасности, которые могут возникнуть, если мы изменим стандартные конфигурации серверов или фреймворков, таких как Spring.

Как правило, параметры запроса обычно являются лучшим решением для работы с косой чертой в URL-адресах.

Как всегда, полный исходный код примеров доступен на GitHub .