Table of Contents
一、什么是SQL注入
二、Java项目防止SQL注入方式
1、PreparedStatement防止SQL注入
2、mybatis中#{}防止SQL注入
3、对请求参数的敏感词汇进行过滤
4、nginx反向代理防止SQL注入
Home Java javaTutorial How to prevent SQL injection in Java projects

How to prevent SQL injection in Java projects

May 27, 2023 pm 07:25 PM
java sql

    一、什么是SQL注入

    SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

    SQL案列

    String sql = "delete from table1 where id = " + "id";
    Copy after login

    这个id从请求参数中获取,若参数被拼接为:

    1001 or 1 = 1

    最执行语句变为:

    String sql = "delete from table1 where id = 1001 or 1 = 1";
    Copy after login

    此时,数据库的数据都会被清空掉,后果非常严重

    二、Java项目防止SQL注入方式

    这里总结4种:

    • PreparedStatement防止SQL注入

    • mybatis中#{}防止SQL注入

    • 对请求参数的敏感词汇进行过滤

    • nginx反向代理防止SQL注入

    1、PreparedStatement防止SQL注入

    PreparedStatement具有预编译功能,以上述SQL为例

    使用PreparedStatement预编译后的SQL为:

    delete from table1 where id= ?
    Copy after login

    此时SQL语句结构已固定,无论"?"被替换为任何参数,SQL语句只认为where后面只有一个条件,当再传入 1001 or 1 = 1时,语句会报错,从而达到防止SQL注入效果

    2、mybatis中#{}防止SQL注入

    mybatis中#{}表达式防止SQL注入与PreparedStatement类似,都是对SQL语句进行预编译处理

    注意:

    #{} :参数占位符

    ${} :拼接替换符,不能防止SQL注入,一般用于

    • 传入数据库对象(如:数据库名称、表名)

    • order by 后的条件

    3、对请求参数的敏感词汇进行过滤

    这里是springboot的写法,如下:

    import org.springframework.context.annotation.Configuration;
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    import java.util.Enumeration;
     
    /**
     * @Auther: 睡竹
     * @Date: 2023/03/07
     * @Description: sql防注入过滤器
     */
    @WebFilter(urlPatterns = "/*",filterName = "sqlFilter")
    @Configuration
    public class SqlFilter implements Filter {
     
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {}
     
        /**
         * @description sql注入过滤
         */
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            ServletRequest request = servletRequest;
            ServletResponse response = servletResponse;
            // 获得所有请求参数名
            Enumeration<String> names = request.getParameterNames();
            String sql = "";
            while (names.hasMoreElements()){
                // 得到参数名
                String name = names.nextElement().toString();
                // 得到参数对应值
                String[] values = request.getParameterValues(name);
                for (int i = 0; i < values.length; i++) {
                    sql += values[i];
                }
            }
            if (sqlValidate(sql)) {
                //TODO 这里直接抛异常处理,前后端交互项目中,请把错误信息按前后端"数据返回的VO"对象进行封装
                throw new IOException("您发送请求中的参数中含有非法字符");
            } else {
                filterChain.doFilter(request,response);
            }
        }
     
        /**
         * @description 匹配效验
         */
        protected static boolean sqlValidate(String str){
            // 统一转为小写
            String s = str.toLowerCase();
            // 过滤掉的sql关键字,特殊字符前面需要加\\进行转义
            String badStr =
                    "select|update|and|or|delete|insert|truncate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|table|"+
                            "char|declare|sitename|xp_cmdshell|like|from|grant|use|group_concat|column_name|" +
                            "information_schema.columns|table_schema|union|where|order|by|" +
                            "&#39;\\*|\\;|\\-|\\--|\\+|\\,|\\//|\\/|\\%|\\#";
            //使用正则表达式进行匹配
            boolean matches = s.matches(badStr);
            return matches;
        }
     
        @Override
        public void destroy() {}
    }
    Copy after login

    4、nginx反向代理防止SQL注入

    越来越多网站使用nginx进行反向代理,该层我们也可以进行防止SQL注入配置。

    将下面的Nginx配置文件代码放入到server块中,然后重启Nginx即可

     if ($request_method !~* GET|POST) { return 444; }
     #使用444错误代码可以更加减轻服务器负载压力。
     #防止SQL注入
     if ($query_string ~* (\$|&#39;|--|[+|(%20)]union[+|(%20)]|[+|(%20)]insert[+|(%20)]|[+|(%20)]drop[+|(%20)]|[+|(%20)]truncate[+|(%20)]|[+|(%20)]update[+|(%20)]|[+|(%20)]from[+|(%20)]|[+|(%20)]grant[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]where[+|(%20)]|[+|(%20)]select[+|(%20)]|[+|(%20)]and[+|(%20)]|[+|(%20)]or[+|(%20)]|[+|(%20)]count[+|(%20)]|[+|(%20)]exec[+|(%20)]|[+|(%20)]chr[+|(%20)]|[+|(%20)]mid[+|(%20)]|[+|(%20)]like[+|(%20)]|[+|(%20)]iframe[+|(%20)]|[\<|%3c]script[\>|%3e]|javascript|alert|webscan|dbappsecurity|style|confirm\(|innerhtml|innertext)(.*)$) { return 555; }
     if ($uri ~* (/~).*) { return 501; }
     if ($uri ~* (\\x.)) { return 501; }
     #防止SQL注入 
     if ($query_string ~* "[;&#39;<>].*") { return 509; }
     if ($request_uri ~ " ") { return 509; }
     if ($request_uri ~ (\/\.+)) { return 509; }
     if ($request_uri ~ (\.+\/)) { return 509; }
     #if ($uri ~* (insert|select|delete|update|count|master|truncate|declare|exec|\*|\&#39;)(.*)$ ) { return 503; }
     #防止SQL注入
     if ($request_uri ~* "(cost\()|(concat\()") { return 504; }
     if ($request_uri ~* "[+|(%20)]union[+|(%20)]") { return 504; }
     if ($request_uri ~* "[+|(%20)]and[+|(%20)]") { return 504; }
     if ($request_uri ~* "[+|(%20)]select[+|(%20)]") { return 504; }
     if ($request_uri ~* "[+|(%20)]or[+|(%20)]") { return 504; }
     if ($request_uri ~* "[+|(%20)]delete[+|(%20)]") { return 504; }
     if ($request_uri ~* "[+|(%20)]update[+|(%20)]") { return 504; }
     if ($request_uri ~* "[+|(%20)]insert[+|(%20)]") { return 504; }
     if ($query_string ~ "(<|%3C).*script.*(>|%3E)") { return 505; }
     if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") { return 505; }
     if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") { return 505; }
     if ($query_string ~ "proc/self/environ") { return 505; }
     if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") { return 505; }
     if ($query_string ~ "base64_(en|de)code\(.*\)") { return 505; }
     if ($query_string ~ "[a-zA-Z0-9_]=http://") { return 506; }
     if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") { return 506; }
     if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") { return 506; }
     if ($query_string ~ "b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)b") { return 507; }
     if ($query_string ~ "b(erections|hoodia|huronriveracres|impotence|levitra|libido)b") {return 507; }
     if ($query_string ~ "b(ambien|bluespill|cialis|cocaine|ejaculation|erectile)b") { return 507; }
     if ($query_string ~ "b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)b") { return 507; }
     #这里大家根据自己情况添加删减上述判断参数,cURL、wget这类的屏蔽有点儿极端了,但要“宁可错杀一千,不可放过一个”。
     if ($http_user_agent ~* YisouSpider|ApacheBench|WebBench|Jmeter|JoeDog|Havij|GetRight|TurnitinBot|GrabNet|masscan|mail2000|github|wget|curl|Java|python) { return 508; }
     #同上,大家根据自己站点实际情况来添加删减下面的屏蔽拦截参数。
     if ($http_user_agent ~* "Go-Ahead-Got-It") { return 508; }
     if ($http_user_agent ~* "GetWeb!") { return 508; }
     if ($http_user_agent ~* "Go!Zilla") { return 508; }
     if ($http_user_agent ~* "Download Demon") { return 508; }
     if ($http_user_agent ~* "Indy Library") { return 508; }
     if ($http_user_agent ~* "libwww-perl") { return 508; }
     if ($http_user_agent ~* "Nmap Scripting Engine") { return 508; }
     if ($http_user_agent ~* "~17ce.com") { return 508; }
     if ($http_user_agent ~* "WebBench*") { return 508; }
     if ($http_user_agent ~* "spider") { return 508; } #这个会影响国内某些搜索引擎爬虫,比如:搜狗
     #拦截各恶意请求的UA,可以通过分析站点日志文件或者waf日志作为参考配置。
     if ($http_referer ~* 17ce.com) { return 509; }
     #拦截17ce.com站点测速节点的请求,所以明月一直都说这些测速网站的数据仅供参考不能当真的。
     if ($http_referer ~* WebBench*") { return 509; }
     #拦截WebBench或者类似压力测试工具,其他工具只需要更换名称即可。
    Copy after login

    The above is the detailed content of How to prevent SQL injection in Java projects. For more information, please follow other related articles on the PHP Chinese website!

    Statement of this Website
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

    Hot AI Tools

    Undresser.AI Undress

    Undresser.AI Undress

    AI-powered app for creating realistic nude photos

    AI Clothes Remover

    AI Clothes Remover

    Online AI tool for removing clothes from photos.

    Undress AI Tool

    Undress AI Tool

    Undress images for free

    Clothoff.io

    Clothoff.io

    AI clothes remover

    AI Hentai Generator

    AI Hentai Generator

    Generate AI Hentai for free.

    Hot Article

    R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
    4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Best Graphic Settings
    4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. How to Fix Audio if You Can't Hear Anyone
    1 months ago By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Chat Commands and How to Use Them
    1 months ago By 尊渡假赌尊渡假赌尊渡假赌

    Hot Tools

    Notepad++7.3.1

    Notepad++7.3.1

    Easy-to-use and free code editor

    SublimeText3 Chinese version

    SublimeText3 Chinese version

    Chinese version, very easy to use

    Zend Studio 13.0.1

    Zend Studio 13.0.1

    Powerful PHP integrated development environment

    Dreamweaver CS6

    Dreamweaver CS6

    Visual web development tools

    SublimeText3 Mac version

    SublimeText3 Mac version

    God-level code editing software (SublimeText3)

    Java Spring Interview Questions Java Spring Interview Questions Aug 30, 2024 pm 04:29 PM

    In this article, we have kept the most asked Java Spring Interview Questions with their detailed answers. So that you can crack the interview.

    Break or return from Java 8 stream forEach? Break or return from Java 8 stream forEach? Feb 07, 2025 pm 12:09 PM

    Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

    Java Program to Find the Volume of Capsule Java Program to Find the Volume of Capsule Feb 07, 2025 am 11:37 AM

    Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

    How to Run Your First Spring Boot Application in Spring Tool Suite? How to Run Your First Spring Boot Application in Spring Tool Suite? Feb 07, 2025 pm 12:11 PM

    Spring Boot simplifies the creation of robust, scalable, and production-ready Java applications, revolutionizing Java development. Its "convention over configuration" approach, inherent to the Spring ecosystem, minimizes manual setup, allo

    Create the Future: Java Programming for Absolute Beginners Create the Future: Java Programming for Absolute Beginners Oct 13, 2024 pm 01:32 PM

    Java is a popular programming language that can be learned by both beginners and experienced developers. This tutorial starts with basic concepts and progresses through advanced topics. After installing the Java Development Kit, you can practice programming by creating a simple "Hello, World!" program. After you understand the code, use the command prompt to compile and run the program, and "Hello, World!" will be output on the console. Learning Java starts your programming journey, and as your mastery deepens, you can create more complex applications.

    Java Made Simple: A Beginner's Guide to Programming Power Java Made Simple: A Beginner's Guide to Programming Power Oct 11, 2024 pm 06:30 PM

    Java Made Simple: A Beginner's Guide to Programming Power Introduction Java is a powerful programming language used in everything from mobile applications to enterprise-level systems. For beginners, Java's syntax is simple and easy to understand, making it an ideal choice for learning programming. Basic Syntax Java uses a class-based object-oriented programming paradigm. Classes are templates that organize related data and behavior together. Here is a simple Java class example: publicclassPerson{privateStringname;privateintage;

    Java Program to insert an element at the Bottom of a Stack Java Program to insert an element at the Bottom of a Stack Feb 07, 2025 am 11:59 AM

    A stack is a data structure that follows the LIFO (Last In, First Out) principle. In other words, The last element we add to a stack is the first one to be removed. When we add (or push) elements to a stack, they are placed on top; i.e. above all the

    Comparing Two ArrayList In Java Comparing Two ArrayList In Java Feb 07, 2025 pm 12:03 PM

    This guide explores several Java methods for comparing two ArrayLists. Successful comparison requires both lists to have the same size and contain identical elements. Methods for Comparing ArrayLists in Java Several approaches exist for comparing Ar

    See all articles