Как защититься от исчерпания ресурсов и других уязвимостей?

Нам довелось использовать приложения IBM. awdtools/appscan/

против нашей кодовой базы Java, и он обнаружил около 3000 уязвимостей высокой степени серьезности.

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

И некоторые из них касаются SQL-инъекций, проверки ввода и т. д.

Но мой вопрос был об исчерпании ресурсов (дескриптор файла, место на диске, сокеты и т. д.), и в нем перечислены все экземпляры java.io.BufferedReader.readLine как места для возможных внешних атак.

       InputStream ins=conn.getInputStream();

      String inputLine;

      if (!preserveLinefeeds) {
         BufferedReader in = new BufferedReader(new InputStreamReader(ins));
         while ((inputLine = in.readLine()) != null)
            pr.readThreadResponse+=inputLine;
         in.close();
         ins.close();
      } 

conn — это объект HttpURLConnection.

Как добавить в код меры безопасности, чтобы предотвратить это?


person roymustang86    schedule 13.09.2012    source источник


Ответы (2)


Каждый раз, когда вы открываете поток, убедитесь, что блок finally закрывает поток по завершении.

Если при чтении из потока в вашем коде возникает исключение IOException, поток не будет закрыт, поэтому предупреждение

В Java 7 это легко сделать с помощью конструкции try with resources. В java 6 или более ранних версиях вам нужно реплицировать множество шаблонов, например

InputStream ins = null;
try {
  ins = conn.getInputStream();
  ...
} finally {
  IOUtils.closeQuietly(ins);
}

Использование класса IOUtils из Apache Commons

Вы можете написать свой собственный closeQuietly, если не хотите добавлять зависимость

person Stephen Connolly    schedule 13.09.2012

Если AppScan указывает на уязвимость типа «отказ в обслуживании», связанную с readLine, это, вероятно, связано не с каким-либо беспокойством по поводу невозможности закрыть поток (каким бы важным это ни было), а скорее из-за неограниченного характера readLine. Поскольку readLine продолжает считывать ввод до тех пор, пока не будет прочитана новая строка или CR-LF, если источник ввода не является доверенным, вы потенциально можете получить чрезмерно большой объем данных без ожидаемого CR-LF, что приведет к нехватке памяти.

Чтобы решить эту проблему, вы можете либо обеспечить (с помощью механизмов вне вашего приложения), что размер ввода ограничен чем-то безопасным и разумным (хотя AppScan, Fortify и другие инструменты будут продолжать жаловаться на readLine), или, что еще лучше, вы можете заменить свой readLines с ограниченной процедурой чтения, которая устанавливает абсолютный максимум количества символов, которые будут считаны в буфер.

person Mark Gee    schedule 16.11.2012