Вопрос по sql, java, mysql – Java-эквивалент для PHP mysql_real_escape_string ()

14

Существует ли Java-эквивалент для PHP mysql_real_escape_string ()?

Это делается для того, чтобы избежать попыток внедрения SQL перед передачей их в Statement.execute ().

Я знаю, что вместо этого могу использовать PreparedStatement, но предположим, что это одноразовые операторы, поэтому их подготовка приведет книзкая производительность, Я уже изменил код для использования PreparedStatement, но, учитывая структуру существующего кода, функция escape () сделает изменения кода намного проще для просмотра и сопровождения; Я предпочитаю легко поддерживать код, если нет веских причин для дополнительной сложности. Кроме того, PreparedStatements по-разному обрабатываются базой данных, поэтому это может подвергнуть нас ошибкам в базе данных, с которыми мы не сталкивались ранее, что требует дополнительного тестирования перед выпуском в эксплуатацию.

Apache StringEscapeUtils escapeSQL () только избегает одинарных кавычек.

Постскриптум: В окружающей среде, которую я унаследовал, есть много тонкостей, которых я намеренно избегал в своем вопросе.

Два момента для рассмотрения:

1) Подготовленные операторы не являются панацеей и не обеспечивают 100% защиту от SQL-инъекций. Некоторые драйверы баз данных создают параметризованные запросы, используя небезопасную конкатенацию строк, а не предварительно компилируя запрос в двоичную форму. Кроме того, если ваш SQL основан на хранимых процедурах, вы должны убедиться, что хранимые процедуры сами не создают запросы небезопасными способами.

2) Наиболее подготовленная реализация оператора связывает оператор с подключением к базе данных, на котором был создан оператор. Если вы используете пул соединений с базой данных, вы должны быть осторожны с
использовать ссылку на подготовленное заявление только с той связью, по которой оно было подготовлено. Некоторые механизмы объединения реализуют это прозрачно. В противном случае вы также можете объединить подготовленные операторы или (самое простое, но более затратное) создать новый подготовленный оператор для каждого запроса.

низкая производительность может быть более привлекательной, чем риск для безопасности. штраф за безопасность может быть слишком высоким. Подготовьте свои заявления в коде инициализации приложения, и штраф может не быть заметным (конечно, зависит от приложения). Cheekysoft
Учитывая способ, которым существующий код (который я не писал), да, его было бы легче поддерживать. Kieran Tully
Вы предпочитаете простой в обслуживании код, и все же вы предпочитаете использовать экранирование строк вручную, а не PrearedStatement? skaffman

Ваш Ответ

6   ответов
2

ет решить вашу проблему!

Error: User Rate Limit Exceeded
3

подготовленные / параметризованные операторы.

Например,Подготовленное заявление Вы пытаетесь избежать по какой-то причине. Если вы делаете одноразовые заявления, время для их подготовки должно быть незначительным («одноразовый» и «критичный к производительности» - противоречие, ИМХО). Если вы делаете что-то в цикле, подготовленные операторы даже приводят к увеличению производительности.

5

что PreparedStatements медленнее. Попробуйте, измерите, а затем судите.

PreparedStatements долженalways быть использованы в предпочтении к утверждению, в значительной степени без исключения,especially когда вы пытаетесь избежать атак с использованием SQL-инъекций.

6

который достигает того, что вы ищете. Первоначально в Внет Публикация вики.

https://web.archive.org/web/20131202082741/http://wiki.vnetpublishing.com/Java_Mysql_Real_Escape_String

/**
  * Mysql Utilities
  *        
  * @author Ralph Ritoch <[email protected]>
  * @copyright Ralph Ritoch 2011 ALL RIGHTS RESERVED
  * @link http://www.vnetpublishing.com
  *
  */

 package vnet.java.util;

 public class MySQLUtils {

     /**
      * Escape string to protected against SQL Injection
      *
      * You must add a single quote ' around the result of this function for data,
      * or a backtick ` around table and row identifiers. 
      * If this function returns null than the result should be changed
      * to "NULL" without any quote or backtick.
      *
      * @param link
      * @param str
      * @return
      * @throws Exception 
      */

     public static String mysql_real_escape_string(java.sql.Connection link, String str) 
           throws Exception
     {
         if (str == null) {
             return null;
         }

         if (str.replaceAll("[[email protected]#$%^&*()-=+~.;:,\\Q[\\E\\Q]\\E<>{}\\/? ]","").length() < 1) {
             return str;
         }

         String clean_string = str;
         clean_string = clean_string.replaceAll("\\\\", "\\\\\\\\");
         clean_string = clean_string.replaceAll("\\n","\\\\n");
         clean_string = clean_string.replaceAll("\\r", "\\\\r");
         clean_string = clean_string.replaceAll("\\t", "\\\\t");
         clean_string = clean_string.replaceAll("\\00", "\\\\0");
         clean_string = clean_string.replaceAll("'", "\\\\'");
         clean_string = clean_string.replaceAll("\\\"", "\\\\\"");

         if (clean_string.replaceAll("[[email protected]#$%^&*()-=+~.;:,\\Q[\\E\\Q]\\E<>{}\\/?\\\\\"' ]"
           ,"").length() < 1) 
         {
             return clean_string;
         }

         java.sql.Statement stmt = link.createStatement();
         String qry = "SELECT QUOTE('"+clean_string+"')";

         stmt.executeQuery(qry);
         java.sql.ResultSet resultSet = stmt.getResultSet();
         resultSet.first();
         String r = resultSet.getString(1);
         return r.substring(1,r.length() - 1);       
     }

     /**
      * Escape data to protected against SQL Injection
      *
      * @param link
      * @param str
      * @return
      * @throws Exception 
      */

     public static String quote(java.sql.Connection link, String str)
           throws Exception
     {
         if (str == null) {
             return "NULL";
         }
         return "'"+mysql_real_escape_string(link,str)+"'";
     }

     /**
      * Escape identifier to protected against SQL Injection
      *
      * @param link
      * @param str
      * @return
      * @throws Exception 
      */

     public static String nameQuote(java.sql.Connection link, String str)
           throws Exception
     {
         if (str == null) {
             return "NULL";
         }
         return "`"+mysql_real_escape_string(link,str)+"`";
     }

 }
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0

в Java нет стандартного способа обработки mysql_real_escape_string () из PHP Я сделал цепочку метода replaceAll для обработки каждого аспекта, который может понадобиться, чтобы избежать каких-либо исключений. Вот мой пример кода:

public void saveExtractedText(String group,String content) { try { content = content.replaceAll("\\", "\\\\") .replaceAll("\n","\\n") .replaceAll("\r", "\\r") .replaceAll("\t", "\\t") .replaceAll("\00", "\\0") .replaceAll("'", "\\'") .replaceAll("\\"", "\\\"");

        state.execute("insert into extractiontext(extractedtext,extractedgroup) values('"+content+"','"+group+"')");
    } catch (Exception e) {
        e.printStackTrace();

    }

12

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

Безопасность, которую вы получаете, должна быть гораздо выше, чем проблема с производительностью, которую вы еще не видели. По моему мнению, это четкая ситуация "не оптимизировать преждевременно".

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

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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Kieran Tully

Похожие вопросы