Большинство незащищенных веб-серверов 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 является дробью, заключается в том, что она позволяет использовать значение между двумя существующими значениями, что может быть необходимо при предоставлении значения после того, как начальные присвоения произошли.

Другие вопросы по тегам