Skip to content
IRC-CodingIRC-Coding
SQL InjectionPrepared StatementsWeb SecurityDatabaseOWASP

SQL Injection: Attacks, Protection & Prevention

SQL Injection is a critical security vulnerability. Learn how attackers inject malicious SQL commands and protect with Prepared Statements.

S

schutzgeist

9 min read
SQL Injection: Attacks, Protection & Prevention

SQL Injection: Attacks, Defenses & Prevention

This article explains SQL Injection attacks – including protective measures and best practices.

In a Nutshell

SQL Injection is a vulnerability in web applications where attackers insert malicious SQL commands into input fields to gain unauthorized database access or modify data.

Core Technical Definition

SQL Injection ranks among the most dangerous and common security flaws in web applications. Attackers exploit insecure handling of user input to execute arbitrary SQL commands.

Common attack vectors:

  • Login forms: Bypassing authentication mechanisms
  • Search fields: Extracting data from unintended tables
  • URL parameters: Manipulating database queries
  • API endpoints: Direct SQL command execution

Potential damage:

  • Data theft: Extracting sensitive information
  • Data manipulation: Modifying or deleting records
  • System compromise: Executing operating system commands
  • Denial of Service: Destroying database structures

Key Exam Points

  • Objective: Gaining access to, modifying, or destroying databases
  • Root cause: Unsafe concatenation of user input into database queries
  • Common targets: Login forms, search fields, URL parameters
  • Primary defenses: Prepared Statements, input validation, ORM frameworks
  • Classic attack: admin' OR '1'='1 bypasses password checks
  • OWASP ranking: Injection is in the Top 3 security risks (A03)
  • Principle of least privilege: Web applications should never run with root database access
  • Professional relevance: Critical for software architecture and development

Core Components

  1. Vulnerable queries: Direct SQL string concatenation
  2. Prepared Statements: Parameterized query execution
  3. Input validation: Whitelisting and escaping
  4. ORM frameworks: Hibernate, Entity Framework
  5. Least privilege: Minimal database permissions
  6. Error handling: Preventing database error disclosure
  7. Security testing: Automated scanning tools
  8. Code review: Manual inspection processes

Practical Examples

Vulnerable Code

// HIGHLY DANGEROUS - SQL Injection possible
public User login(String username, String password) {
    String query = "SELECT * FROM users WHERE username = '" + 
                   username + "' AND password = '" + password + "'";
    Statement stmt = connection.createStatement();
    ResultSet rs = stmt.executeQuery(query);
    
    if (rs.next()) {
        return new User(rs.getString("username"), rs.getString("role"));
    }
    return null;
}

// Attack: username = "admin' OR '1'='1" -- "
// Result: SELECT * FROM users WHERE username = 'admin' OR '1'='1' -- ' AND password = ''
// All users are returned!

Secure Alternative Using Prepared Statements

// SECURE - SQL Injection prevented
public User login(String username, String password) {
    String query = "SELECT * FROM users WHERE username = ? AND password = ?";
    PreparedStatement stmt = connection.prepareStatement(query);
    stmt.setString(1, username);
    stmt.setString(2, password);
    ResultSet rs = stmt.executeQuery();
    
    if (rs.next()) {
        return new User(rs.getString("username"), rs.getString("role"));
    }
    return null;
}

Additional Attack Examples

-- Union-Based Injection
' UNION SELECT username, password FROM admins --

-- Blind Injection
' AND (SELECT COUNT(*) FROM users WHERE username='admin' AND password LIKE 'a%') > 0 --

-- Time-Based Injection
' AND (SELECT SLEEP(5)) --

-- Stored Procedure Injection
'; DROP TABLE users; --

Protective Measures

1. Prepared Statements (Parameterized Queries)

// Java
String sql = "SELECT * FROM products WHERE name = ? AND price < ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, productName);
stmt.setDouble(2, maxPrice);

// PHP with PDO
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);

// Python
cursor.execute("SELECT * FROM users WHERE id = %s", [user_id])

2. Input Validation & Escaping

// Whitelist validation
public boolean isValidUsername(String username) {
    return username.matches("^[a-zA-Z0-9_]{3,20}$");
}

// HTML escaping for output
String safeOutput = StringEscapeUtils.escapeHtml4(userInput);

3. ORM Frameworks

// JPA/Hibernate
@Entity
@Table(name="users")
public class User {
    @Id
    private String username;
    private String password;
    
    // Automatic SQL generation, protected against injection
}

public User findByUsername(String username) {
    return entityManager.createQuery(
        "SELECT u FROM User u WHERE u.username = :username", User.class)
        .setParameter("username", username)
        .getSingleResult();
}

4. Least Privilege Principle

-- Web application receives only necessary permissions
GRANT SELECT, INSERT, UPDATE ON app_db.users TO 'webapp'@'localhost';
-- NO DROP, DELETE, ALTER rights!

Strengths and Weaknesses of Protective Measures

Strengths

  • Security: Prevents database compromise
  • Compliance: Meets security standards (GDPR, ISO 27001)
  • Trust: Protects user data and company reputation
  • Cost efficiency: Prevents expensive security incidents

Weaknesses

  • Performance: Prepared Statements may incur slight overhead
  • Complexity: Requires additional development effort
  • Learning curve: Developers need secure coding training
  • Testing: Additional security testing required

Common Exam Questions

  1. What is SQL Injection and how does it work? Injecting SQL code through user input via unsafe string concatenation.

  2. What is the most effective way to prevent SQL Injection? Using Prepared Statements or Parameterized Queries.

  3. Why is input validation alone insufficient? Validation can be bypassed; Prepared Statements provide stronger protection.

  4. What role does the Least Privilege Principle play? Web applications should have only minimal database rights to limit potential damage.

Q&A for Beginners

What is SQL Injection in simple terms?

Imagine a login form. Normally, when you enter your username, the website expects just a name. With SQL Injection, an attacker enters special SQL code that the database executes as a command rather than treating it as plain text.

Can this really happen?

Absolutely. Many websites lack adequate protection. Attackers can steal passwords, delete data, or take over entire databases this way.

How do I know if my website is at risk?

If you insert user input directly into SQL queries without “cleaning” it first, you’re vulnerable. This is especially common in login forms, search fields, and contact forms.

Is protecting against this complicated?

No! The essential rule: always use Prepared Statements. It’s like a shield that prevents user input from being misinterpreted as commands.

A practical guide for regular websites

Step 1: Identify vulnerabilities

What you should check:

  • All login forms
  • Search fields on your website
  • Contact forms
  • Registration forms
  • URL parameters (for example, ?id=123)

Simple test: Enter the following into a search field: ' OR '1'='1 If the website displays strange results or shows all data, it could be vulnerable.

Step 2: Security testing tools

For beginners:

  • SQLMap (free): Automates SQL injection testing
  • Burp Suite Community (free): Intercepts and analyzes web traffic
  • OWASP ZAP (free): Web application security tool

For advanced users:

  • Burp Suite Professional (paid): Extended features
  • Acunetix (paid): Automated security scanning

Simple browser tools:

  • Developer Tools (F12) in your browser
  • Network tab for analyzing requests

Step 3: Run your tests

Procedure:

  1. Analyze the website: Find all forms and parameters
  2. Record traffic: Use Burp Suite or ZAP to see requests
  3. Enter test payloads: Try different SQL injection patterns
  4. Observe responses: Watch for error messages or unusual results

Common test payloads:

' OR '1'='1
' UNION SELECT null,null--
' AND (SELECT COUNT(*) FROM users) > 0
'; DROP TABLE users--

' OR 'x'='x
' OR 1=1--
' OR 1=1#
' UNION SELECT username,password FROM users--
' UNION SELECT @@version--
' AND SLEEP(5)--
' WAITFOR DELAY '00:00:05'
' AND (SELECT * FROM (SELECT COUNT(*),CONCAT(version(),FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)--
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version()),0x7e))--
' AND (SELECT * FROM (SELECT COUNT(*),CONCAT((SELECT database()),FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)--
' UNION SELECT 1,2,3,4,5,6,7,8,9,10--
' UNION SELECT 1,@@datadir,3,4--
' UNION SELECT SCHEMA_NAME,2 FROM INFORMATION_SCHEMA.SCHEMATA--
' UNION SELECT table_name,2 FROM INFORMATION_SCHEMA.TABLES--
' UNION SELECT column_name,2 FROM INFORMATION_SCHEMA.COLUMNS--
' AND 1=CONVERT(int,(SELECT @@version))
' AND 1=CONVERT(int,(SELECT top 1 name FROM sysobjects WHERE xtype='U'))

Step 4: Document your findings

What you should document:

Test log:

Date: 04.06.2026
Tester: [Your Name]
Website: https://bwww.IRC-Coding.de

Functions tested:
- Login form (/login)
- Search function (/search)
- User profile (/profile?id=123)

Results:
- Login form: Secure (no SQL injection found)
- Search function: VULNERABLE on parameter 'q'
- User profile: Secure

Details of the vulnerability:
URL: /search?q=test'
Error message: "SQL syntax error"
Recommendation: Implement prepared statements

Vulnerability report:

Vulnerability: SQL Injection in search function
Severity: High
Affected function: /search?q=[parameter]
Proof: Entering ' OR '1'='1 displays all results
Impact: Access to all database contents possible

Testing checklist:

  • All forms tested
  • URL parameters checked
  • Error messages documented
  • Screenshots taken
  • Reproduction steps noted

Step 5: Fix and verify

Immediate actions:

  1. Implement prepared statements
  2. Add input validation
  3. Improve error handling (don’t display SQL errors)
  4. Restrict database permissions

Quality assurance:

  • Test again after each change
  • Set up automated scans
  • Conduct regular security audits

Long-term strategy:

  • Train developers on secure coding
  • Code reviews with security focus
  • Automated security testing in your CI/CD pipeline

How to get notified about SQL injection attacks

Set up real-time monitoring

WAF (Web Application Firewall):

  • Cloudflare WAF: Automatically blocks suspicious requests
  • AWS WAF: Integration with Lambda functions for custom rules
  • ModSecurity: Open-source WAF with SQL injection rules

Log analysis tools:

  • ELK Stack (Elasticsearch, Logstash, Kibana): Centralized log analysis
  • Splunk: Enterprise SIEM solution for security alerts
  • Graylog: Open-source log management

Specialized security tools:

  • Fail2Ban: Blocks IP addresses after suspicious activity
  • OSSEC: Host-based intrusion detection system
  • Snort: Network intrusion detection system

Alert setup:

# Example for Fail2Ban with SQL injection detection
[Definition]
failregex = ^.*SQL syntax.*SELECT.*FROM.*$
            ^.*Warning.*mysql_fetch_array().*$
ignoreregex =

# Action: Email and IP block
action = %(action_mwl)s
         %(action_block)s

Set up a monitoring dashboard

Key metrics:

  • Number of SQL injection attempts per hour
  • Blocked IP addresses
  • Failed SQL queries
  • Database connection errors

Alert rules:

  • Immediate notification on >10 SQL injection attempts
  • Weekly report on security incidents
  • Critical alert on successful database access

Framework-specific security

WordPress security

WordPress-specific measures:

// In wp-config.php
define('FORCE_SSL_ADMIN', true);
define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true);

// Prepared statements in WordPress
global $wpdb;
$user_id = get_current_user_id();
$results = $wpdb->get_results( 
    $wpdb->prepare( 
        "SELECT * FROM {$wpdb->prefix}usermeta WHERE user_id = %d", 
        $user_id 
    ) 
);

Essential plugins:

  • Wordfence Security: Firewall and malware scanning
  • Sucuri Security: Hardening and audit logs
  • iThemes Security: File change monitoring

WordPress best practices:

  • Apply updates regularly
  • Use strong passwords for your database
  • Restrict wp-admin by IP address
  • Disable XML-RPC if not needed

Laravel security

Laravel-specific features:

// Eloquent ORM (automatically secure)
$users = User::where('email', $request->email)->get();

// Query builder with parameter binding
$users = DB::select('SELECT * FROM users WHERE email = ?', [$email]);

// Raw queries with binding
$users = DB::select('SELECT * FROM users WHERE name = :name', ['name' => $name]);

Laravel security packages:

  • Laravel Security: Additional validation rules
  • Laravel Firewall: Request filtering
  • Laravel Audit: Activity logging

Configuration:

// config/database.php
'mysql' => [
    'strict' => true,
    'options' => [
        PDO::ATTR_EMULATE_PREPARES => false,
    ],
],

Astro security

Astro-specific considerations:

  • Static site generation: No dynamic database connection
  • API routes: Secure serverless functions
  • Environment variables: Keep sensitive data out of client code

API route security:

// src/pages/api/search.js
import { query } from '@astrojs/db';

export async function GET({ url }) {
  const searchTerm = url.searchParams.get('q');
  
  // Input validation
  if (!searchTerm || searchTerm.length > 100) {
    return new Response('Invalid input', { status: 400 });
  }
  
  // Prepared statement with Astro DB
  const results = await query(
    'SELECT * FROM posts WHERE title LIKE ? LIMIT 10',
    [`%${searchTerm}%`]
  );
  
  return Response.json(results);
}

Astro security best practices:

  • Set Content Security Policy (CSP) headers
  • Implement API rate limiting
  • Use environment variables for database credentials
  • Update dependencies regularly

Node.js/React/Next.js Security

Securing your Node.js backend:

// mysql2 package with prepared statements
const mysql = require('mysql2/promise');

async function searchUsers(searchTerm) {
  const connection = await mysql.createConnection({
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME
  });
  
  // Prepared statement
  const [rows] = await connection.execute(
    'SELECT * FROM users WHERE username LIKE ?',
    [`%${searchTerm}%`]
  );
  
  await connection.end();
  return rows;
}

Next.js API routes:

// pages/api/search.js
import { query } from '../../lib/db';

export default async function handler(req, res) {
  if (req.method !== 'GET') {
    return res.status(405).json({ message: 'Method not allowed' });
  }
  
  const { q } = req.query;
  
  // Input validation
  if (!q || typeof q !== 'string' || q.length > 100) {
    return res.status(400).json({ message: 'Invalid search term' });
  }
  
  try {
    const results = await query({
      query: 'SELECT * FROM posts WHERE title LIKE ? LIMIT 10',
      values: [`%${q}%`]
    });
    
    res.status(200).json(results);
  } catch (error) {
    console.error('Database error:', error);
    res.status(500).json({ message: 'Internal server error' });
  }
}

React frontend security:

// API calls with input validation
const searchPosts = async (searchTerm) => {
  // Client-side validation
  if (!searchTerm || searchTerm.length > 100) {
    throw new Error('Invalid search term');
  }
  
  const response = await fetch(`/api/search?q=${encodeURIComponent(searchTerm)}`);
  
  if (!response.ok) {
    throw new Error('Search failed');
  }
  
  return response.json();
};

Essential security packages for Node.js:

  • Helmet: HTTP header security
  • express-rate-limit: Rate limiting
  • helmet-csp: Content Security Policy
  • bcrypt: Password hashing
  • jsonwebtoken: JWT authentication

Next.js security configuration:

// next.config.js
const helmet = require('helmet');

module.exports = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          {
            key: 'X-Frame-Options',
            value: 'DENY'
          },
          {
            key: 'X-Content-Type-Options',
            value: 'nosniff'
          },
          {
            key: 'Referrer-Policy',
            value: 'origin-when-cross-origin'
          }
        ]
      }
    ];
  }
};

Key resources

  1. https://owasp.org/www-community/attacks/SQL_Injection
  2. https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
  3. https://portswigger.net/web-security/sql-injection

Further reading on SQL

SQL and database security are critical to building robust applications. These articles cover essential concepts to master SQL and security best practices.

Security and protection

Back to Blog
Share:

Related Posts