2010-09-02 3 views
2

Я кодирую инструмент, который при любом URL-адресе периодически выводит его вывод. Проблема заключается в том, что вывод может быть не простой и легкой HTML-страницей (как ожидается, в большинстве случаев), а некоторым тяжелым потоком данных (т. Е. Прямо из/dev/urandom, возможной атаки DoS).Ограничение потока ввода Java: защита от DoS-атак

Я использую java.net.URL + java.net.URLConnection, устанавливая время соединения и время ожидания до 30 секунд. В настоящее время ввод считывается java.io.BufferedReader, используя readLine().

Возможные решения:

  1. Используйте java.io.BufferedReader.read() байт за байтом, считая их и закрытия соединения после предел был достигнут. Проблема заключается в том, что злоумышленник может передавать один байт каждые 29 секунд, так что тайм-аут чтения/соединения почти никогда не будет происходить (204800B * 29сек = 68 дней)
  2. Ограничить выполнение резьбы до 1-5 минут и использовать java.io.BufferedReader.readLine(). Любые проблемы здесь?

Я чувствую, что пытаюсь изобретать велосипед, и решение очень прямолинейно, просто мне не приходит в голову.

Заранее спасибо.

ответ

1

Вы можете encapsulatebhhis написав себе FilterInputStream, что навязывает то, что вы хотите, чтобы усилить и поместить его в нижней части стека, вокруг выходного соединения потока

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

+0

Написал LimitedInputStream, расширяющий FilterInputStream с помощью методов overriden read(), которые возвращают -1 (конец поддельного входного потока), когда предел достигнут. Благодаря! – ljank

0

Здесь, как представляется, существует несколько способов отказа в обслуживании.

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

Работа с противником (или ошибкой), поддерживающая сразу несколько соединений. Вероятно, вы хотите, чтобы неблокирующий ввод-вывод читал все сообщение, а затем продолжал нормально.