Большинство незащищенных веб-серверов Tomcat уязвимы, кто виноват?
Большинство Java JVM подвергаются очень серьезному отказу в обслуживании (все JVM Oracle / Sun до 1.6.0_24 [который еще не вышел на момент написания этой статьи) и который не получил исправление, вышедшее вчера, для пример).
http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
Следующие:
curl -H 'Accept-Language: en-us;q=2.2250738585072012e-308' http://example.org
падает много веб-серверов Tomcat на планете.
Мой вопрос прост: кто виноват?
По-видимому getLocale()
вызывает (очень плохо) прослушивается Double.parseDouble(...)
и затем вы можете тривиально выполнить отказ в обслуживании на Tomcat.
Является ли ошибочная реализация Double.parseDouble(...)
действительно виноват?
Мне кажется, что реальная проблема заключается в том, что спецификации HTTP используют числа с плавающей точкой для чего-то, что на самом деле не очень похоже на научные вычисления для меня. Использование числа с плавающей точкой для такой вещи кажется более чем странным: легко доказать, что реализация на разных языках даст разные результаты.
Так кто виноват?
Ужасно хромая реализация Java (ошибка известна с 10 лет) Double.parseDouble(...)
?
Спецификации HTTP? (помните, что PHP перенес точно такую же ошибку).
Я могу понять, что вы обвиняете язык, если это происходит с одним языком... Но когда две удаленные атаки типа "отказ в обслуживании" происходят с двумя разными языками из-за того, что спецификации HTTP диктуют разбор числа с плавающей запятой для чего-то, что не является научный расчет должен позвонить в колокол.
Числа с плавающей точкой должны использоваться только для научных вычислений. Если у вас нет чисел с плавающей точкой и эпсилон, вы делаете это неправильно.
3 ответа
На самом деле, rfc 2616 (спецификация HTTP/1.1) говорит:
Приложения HTTP/1.1 НЕ ДОЛЖНЫ генерировать более трех цифр после десятичной точки. Пользовательская конфигурация этих значений также ДОЛЖНА быть ограничена таким образом.
qvalue = ( "0" [ "." 0*3DIGIT ] ) | ( "1" [ "." 0*3("0") ] )
"Значения качества" - это неправильное название, поскольку эти значения просто представляют относительное ухудшение желаемого качества.
Обратите внимание, что это ограничивает количество цифр и не допускает экспоненту. Я думаю, что любая реализация будет в рамках спецификации, чтобы игнорировать ввод, который имеет более 3 дробных цифр, и полностью игнорировать все, что имеет значение экспоненты. Тот факт, что Tomcat не делает этого, не является проблемой спецификации HTTP.
Это не либо / или. Как и в случае многих проблем с безопасностью, это результат их вины. Если бы кто-то сделал свою работу достаточно хорошо, проблема никогда бы не возникла.
Это проблема метода разбора чисел в библиотеке времени выполнения Java, а не в Tomcat - он просто использует указанный метод.
Редактировать: Причина, по которой q является дробью, заключается в том, что она позволяет использовать значение между двумя существующими значениями, что может быть необходимо при предоставлении значения после того, как начальные присвоения произошли.