[Java] جافا - سلسلة الهروب لمنع حقن SQL


Answers

الطريقة الوحيدة لمنع حقن SQL هي مع SQL معلمات. ببساطة ، ليس من الممكن إنشاء فلتر أكثر ذكاءً من الأشخاص الذين يقومون باختراق SQL لقمة العيش.

لذلك استخدم المعلمات لجميع المدخلات والتحديثات وأين العبارات. Dynamic SQL هو ببساطة باب مفتوح للمتسللين ، ويتضمن ذلك SQL الديناميكية في الإجراءات المخزنة. Parameterize، parameterize، parameterize.

Question

أحاول أن أضع بعض الحقن المضادة للمضادات الحيوية في مكان جافا وأنا أجد أنه من الصعب جدا العمل مع وظيفة السلسلة "replaceAll". في النهاية ، أحتاج إلى وظيفة تقوم بتحويل أي \n موجود ، أي " to \" ، أي ' to \' ، وأي \n إلى \\n بحيث يتم حظر السلسلة بواسطة MySQL SQL.

لقد قمت برفع بعض الكود الذي كنت أعمل به مع كل هذه \\\\\\\\\\\ التي تجعل عيني تذهب للمكسرات. إذا كان أي شخص يحصل على مثال على هذا ، فأنا أقدر ذلك كثيرًا.




في حال كنت تتعامل مع نظام قديم ، أو لديك العديد من الأماكن للتحويل إلى PreparedStatement في وقت قليل جدًا - أي إذا كان هناك عائق لاستخدام أفضل الممارسات المقترحة من قبل إجابات أخرى ، يمكنك تجربة AntiSQLFilter




باستخدام تعبير عادي لإزالة النص الذي قد يتسبب في إدخال إدخال SQL مثل عبارة SQL ، يتم إرسالها إلى قاعدة البيانات عبر Statement بدلاً من PreparedStatement .

واحدة من أسهل الطرق لمنع حقن SQL في المقام الأول هو استخدام PreparedStatement ، والذي يقبل البيانات ليحل محلها في عبارة SQL باستخدام العناصر النائبة ، والتي لا تعتمد على سلسلة concatenations لإنشاء جملة SQL لإرسالها إلى قاعدة البيانات.

لمزيد من المعلومات ، فإن استخدام البيانات الجاهزة من برامج Java التعليمية قد يكون مكانًا جيدًا للبدء.




(هذا في إجابته على تعليق OP تحت السؤال الأصلي ؛ أوافق تمامًا على أن PreparedStatement هي أداة لهذه الوظيفة ، وليس regexes.)

عندما تقول \n ، هل تقصد التسلسل \ n أو حرف تغذية فعلية؟ إذا كانت \ n ، n المهمة واضحة جدًا:

s = s.replaceAll("['\"\\\\]", "\\\\$0");

لمطابقة خط مائل عكسي واحد في الإدخال ، يمكنك وضع أربعة منها في سلسلة regex. لوضع خط مائل عكسي واحد في الإخراج ، يمكنك وضع أربعة منها في سلسلة الاستبدال. هذا هو افتراض أنك تقوم بإنشاء regexes والاستبدالات في شكل القيم الحرفية سلسلة جافا. إذا قمت بإنشاء أي طريقة أخرى (على سبيل المثال ، من خلال قراءتها من ملف) ، فلن تضطر إلى القيام بكل ذلك الهرب المزدوج.

إذا كان لديك حرف تغذية في الإدخال وتريد استبداله بتسلسل هروب ، فيمكنك إجراء تمرير ثاني عبر الإدخال باستخدام هذا:

s = s.replaceAll("\n", "\\\\n");

أو ربما كنت تريد اثنين من خطوط مائلة عكسية (لست واضحا جدا على ذلك):

s = s.replaceAll("\n", "\\\\\\\\n");



بعد البحث عن اختبار الكثير من الحل لمنع sqlmap من حقن SQL ، في حالة النظام القديم الذي لا يمكن تطبيق الإحصائيات المعدّة في كل مكان.

java-security-cross-site-scripting-xss-and-sql-injection topic WAS THE SOLUTION

حاولت حل ريتشارد s ولكن لم يعمل في حالتي. أنا استخدم مرشح

الهدف من هذا المرشح هو إرفاق الطلب في غلاف خاص به MyHttpRequestWrapper والذي يحول:

معلمات HTTP ذات الأحرف الخاصة (<،> ، '، ...) إلى رموز HTML عبر org.springframework.web.util.HtmlUtils.html أسلوب Escape (…). ملاحظة: يوجد classe مشابه في Apache Commons: org.apache.commons.lang.StringEscapeUtils.escapeHtml (…) أحرف إدخال SQL ('، “،…) عبر clache Commons classe org.apache.commons.lang.StringEscapeUtils. escapeSql (...)

<filter>
<filter-name>RequestWrappingFilter</filter-name>
<filter-class>com.huo.filter.RequestWrappingFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>RequestWrappingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>




package com.huo.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletReponse;
import javax.servlet.http.HttpServletRequest;

public class RequestWrappingFilter implements Filter{

    public void doFilter(ServletRequest req, ServletReponse res, FilterChain chain) throws IOException, ServletException{
        chain.doFilter(new MyHttpRequestWrapper(req), res);
    }

    public void init(FilterConfig config) throws ServletException{
    }

    public void destroy() throws ServletException{
    }
}




package com.huo.filter;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.lang.StringEscapeUtils;

public class MyHttpRequestWrapper extends HttpServletRequestWrapper{
    private Map<String, String[]> escapedParametersValuesMap = new HashMap<String, String[]>();

    public MyHttpRequestWrapper(HttpServletRequest req){
        super(req);
    }

    @Override
    public String getParameter(String name){
        String[] escapedParameterValues = escapedParametersValuesMap.get(name);
        String escapedParameterValue = null; 
        if(escapedParameterValues!=null){
            escapedParameterValue = escapedParameterValues[0];
        }else{
            String parameterValue = super.getParameter(name);

            // HTML transformation characters
            escapedParameterValue = org.springframework.web.util.HtmlUtils.htmlEscape(parameterValue);

            // SQL injection characters
            escapedParameterValue = StringEscapeUtils.escapeSql(escapedParameterValue);

            escapedParametersValuesMap.put(name, new String[]{escapedParameterValue});
        }//end-else

        return escapedParameterValue;
    }

    @Override
    public String[] getParameterValues(String name){
        String[] escapedParameterValues = escapedParametersValuesMap.get(name);
        if(escapedParameterValues==null){
            String[] parametersValues = super.getParameterValues(name);
            escapedParameterValue = new String[parametersValues.length];

            // 
            for(int i=0; i<parametersValues.length; i++){
                String parameterValue = parametersValues[i];
                String escapedParameterValue = parameterValue;

                // HTML transformation characters
                escapedParameterValue = org.springframework.web.util.HtmlUtils.htmlEscape(parameterValue);

                // SQL injection characters
                escapedParameterValue = StringEscapeUtils.escapeSql(escapedParameterValue);

                escapedParameterValues[i] = escapedParameterValue;
            }//end-for

            escapedParametersValuesMap.put(name, escapedParameterValues);
        }//end-else

        return escapedParameterValues;
    }
}





Links