Information Security 9 min read

Understanding SQL Injection and Prevention Techniques in Java Projects

SQL injection is a critical web security flaw where unsanitized user input can alter database queries, and this article explains its mechanics, demonstrates vulnerable Java code, and outlines four prevention methods—PreparedStatement, MyBatis #{}, request parameter filtering, and Nginx reverse‑proxy rules—complete with code examples.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding SQL Injection and Prevention Techniques in Java Projects

What is SQL Injection?

SQL injection occurs when a web application fails to properly validate or filter user‑provided data, allowing an attacker to append malicious SQL statements to a predefined query, causing the database to execute unauthorized operations and potentially expose sensitive data.

Example of vulnerable code:

String sql = "delete from table1 where id = " + "id";

If the id parameter is taken directly from the request and an attacker supplies 1001 or 1 = 1 , the final statement becomes:

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

This condition always evaluates to true, causing the entire table1 to be cleared, which is a severe consequence.

Java Project Prevention Methods

The article summarizes four approaches to prevent SQL injection in Java applications:

PreparedStatement – Uses parameter placeholders ("?") so the SQL structure is fixed and the database treats the input as data, not code.

MyBatis #{} – Similar to PreparedStatement, the #{} syntax creates a prepared statement, while ${} performs raw string substitution and should be avoided for user data.

Request‑parameter filtering – Implements a servlet filter that scans all incoming parameters for dangerous keywords or characters and rejects the request if a match is found.

Nginx reverse‑proxy rules – Configures Nginx to block suspicious request methods, query strings, and user‑agent strings that contain typical injection patterns.

1. PreparedStatement

Using a prepared statement, the SQL becomes:

delete from table1 where id = ?

Any attempt to inject additional clauses (e.g., 1001 or 1 = 1 ) will cause a syntax error, preventing the attack.

2. MyBatis #{}

MyBatis’s #{} placeholder works like a prepared statement, safely binding parameters. In contrast, ${} performs direct string replacement and should only be used for non‑user‑controlled values such as table names.

3. Request‑parameter Filtering (Spring Boot Example)

import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
import java.util.Enumeration;

@WebFilter(urlPatterns = "/*", filterName = "sqlFilter")
@Configuration
public class SqlFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        ServletRequest request = servletRequest;
        ServletResponse response = servletResponse;
        Enumeration
names = request.getParameterNames();
        StringBuilder sql = new StringBuilder();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            String[] values = request.getParameterValues(name);
            for (String v : values) {
                sql.append(v);
            }
        }
        if (sqlValidate(sql.toString())) {
            throw new IOException("Parameter contains illegal characters");
        } else {
            filterChain.doFilter(request, response);
        }
    }

    protected static boolean sqlValidate(String str) {
        String s = str.toLowerCase();
        String badStr = "select|update|and|or|delete|insert|truncate|char|into|substr|ascii|declare|exec|count|master|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|" +
                        "'\\*|\\;|\\-|\\--|\\+|\\,|\\//|\\/|\\%|\\#";
        return s.matches(badStr);
    }

    @Override
    public void destroy() {}
}

4. Nginx Reverse‑Proxy Configuration

Place the following directives inside the server block and restart Nginx:

if ($request_method !~* GET|POST) { return 444; }
# Block suspicious query strings
if ($query_string ~* (\$|\'|--|[+|(%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; }
# Additional filters for URI, user‑agent, referer, etc.

These Nginx rules reject requests containing typical injection patterns, malicious user‑agents, or suspicious referers, reducing the attack surface at the network edge.

Source: blog.csdn.net (original article). The remainder of the page contains promotional material for a backend‑focused technical community, which is not part of the instructional content.

JavaMyBatisSQL Injectionnginxweb securityPreparedStatement
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.