Web Server Potential SQL Injection Request

This rule detects potential SQL injection attempts in web server requests by identifying common SQL injection patterns in URLs. Such activity may indicate reconnaissance or exploitation attempts by attackers trying to manipulate backend databases or extract sensitive information.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2025/11/19"
  3integration = ["nginx", "apache", "apache_tomcat", "iis", "traefik", "zeek"]
  4maturity = "production"
  5updated_date = "2026/07/01"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10This rule detects potential SQL injection attempts in web server requests by identifying common SQL injection patterns
 11in URLs. Such activity may indicate reconnaissance or exploitation attempts by attackers trying to manipulate backend
 12databases or extract sensitive information.
 13"""
 14from = "now-9m"
 15index = [
 16        "logs-nginx.access-*",
 17        "logs-apache.access-*",
 18        "logs-apache_tomcat.access-*",
 19        "logs-iis.access-*",
 20        "logs-traefik.access-*", 
 21        "logs-zeek.http-*"
 22]
 23language = "eql"
 24license = "Elastic License v2"
 25name = "Web Server Potential SQL Injection Request"
 26risk_score = 73
 27rule_id = "7f7a0ee1-7b6f-466a-85b4-110fb105f5e2"
 28severity = "high"
 29tags = [
 30    "Domain: Web",
 31    "Domain: Network",
 32    "Use Case: Threat Detection",
 33    "Tactic: Reconnaissance",
 34    "Tactic: Credential Access",
 35    "Tactic: Persistence",
 36    "Tactic: Execution",
 37    "Tactic: Command and Control",
 38    "Data Source: Nginx",
 39    "Data Source: Apache",
 40    "Data Source: Apache Tomcat",
 41    "Data Source: IIS",
 42    "Data Source: Traefik",
 43    "Data Source: Zeek", 
 44    "Resources: Investigation Guide"
 45]
 46timestamp_override = "event.ingested"
 47type = "eql"
 48query = '''
 49any where (
 50url.original like~ (
 51    "*dbms_pipe.receive_message%28chr%*",
 52    "*waitfor%20delay%20%270%3a0%3a*",
 53    "*%28select%28sleep%285*", "*%28select%20*from%20pg_sleep%285*", "*%3bselect%20pg_sleep%285*",
 54    "*and%20sleep%28*%29*", "*or%20sleep%28*%29*", "*case%20when*then%20sleep%28*", "*if%28sleep%28*%29*",
 55    "*benchmark%28*%2c*md5%28*",
 56    "*convert%28int%2c%28select%20char%28*",
 57    "*char%28*char%28*char%28*char%28*",
 58    "*concat%28concat%28char%28*",
 59    "*case%20when%20%28*%3d*%29%20then*else*end*",
 60    "*elt%28*%3d*%2c1%29%29*",
 61    "*union%20select%20null%2cnull*", "*union%20all%20select%20null*",
 62    "*union%20all%20select%20*concat%28md5%28*",
 63    "*extractvalue%28*concat%280x*", "*updatexml%28*concat%280x*",
 64    "*procedure%2f%2a%2a%2fanalyse%28extractvalue%28*",
 65    "*gtid_subset%28concat%280x*", "*gtid_subtract%28concat%280x*",
 66    "*mid%28ifnull%28session_user%28%29*",
 67    "*'qq'%2b%28%28select%20@@version%29%29%2b'qq'*",
 68    "*%27%20or%20%271%27%3d%271*", "*%22%20or%20%221%22%3d%221*", "*%27%20or%20%27a%27%3d%27a*",
 69    "*and%201%3d1--*", "*and%201%3d2--*",
 70    "*%29%3bselect*if%28%28ord%28mid%28*",
 71    "*xp_cmdshell*",
 72    "*select%20*into%20outfile*", "*select%20*into%20dumpfile*",
 73    "*load_file%28*", "*load%5ffile%28*",
 74    "*select%20*from%20information_schema.tables*", "*from%20information_schema.columns%20where%20table_schema*",
 75    "*dbms_pipe%2ereceive_message*", "*dbms_lock%2esleep*",
 76    "*select%20@@version*", "*select%20user%28%29*", "*select%20current_user%28%29*", "*select%20database%28%29*",
 77    "*sp_executesql%20*exec%20*", "*xp_dirtree*"
 78  )
 79  or
 80  url.query like~ (
 81    "*dbms_pipe.receive_message(chr*",
 82    "*waitfor delay '0:0:*",
 83    "*(select(sleep(5*", "*(select*from pg_sleep(5*", "*;select pg_sleep(5*",
 84    "*and sleep(*)*", "*or sleep(*)*", "*case when*then sleep(*", "*if(sleep(*)*",
 85    "*benchmark(*,*md5(*",
 86    "*convert(int,(select char(*",
 87    "*char(*char(*char(*char(*",
 88    "*concat(concat(char(*",
 89    "*case when (*=*) then*else*end*",
 90    "*elt(*=*,1))*",
 91    "*union select null,null*", "*union all select null*",
 92    "*union all select*concat(md5(*",
 93    "*extractvalue(*concat(0x*", "*updatexml(*concat(0x*",
 94    "*procedure/**/analyse(extractvalue(*",
 95    "*gtid_subset(concat(0x*", "*gtid_subtract(concat(0x*",
 96    "*mid(ifnull(session_user()*",
 97    "*'qq'+((select @@version))+'qq'*",
 98    "*' or '1'='1*", "*\" or \"1\"=\"1*", "*' or 'a'='a*",
 99    "*and 1=1--*", "*and 1=2--*",
100    "*);select*if((ord(mid(*",
101    "*xp_cmdshell*",
102    "*select*into outfile*", "*select*into dumpfile*",
103    "*load_file(*",
104    "*select*from information_schema.tables*", "*from information_schema.columns where table_schema*",
105    "*dbms_pipe.receive_message*", "*dbms_lock.sleep*",
106    "*select @@version*", "*select user()*", "*select current_user()*", "*select database()*",
107    "*sp_executesql*exec*", "*xp_dirtree*"
108  )
109)
110'''
111note = """## Triage and analysis
112
113### Investigating Web Server Potential SQL Injection Request
114
115SQL injection (SQLi) attempts to manipulate backend database queries via unsanitized
116input passed through web request parameters. This rule flags requests whose URL or
117query string contains structural patterns characteristic of automated SQLi tooling
118(sqlmap and similar) or manual exploitation techniques, spanning boolean-blind,
119time-based, error-based, and UNION-based extraction methods across MySQL, MSSQL,
120PostgreSQL, and Oracle syntax.
121
122#### Possible investigation steps
123
124- Identify the full request and response context:
125  - `url.original` / `url.query` — full injected payload
126  - `http.request.method`, `http.response.status_code` — was the request accepted (2xx) or rejected (4xx/5xx/WAF block)?
127  - `source.ip`, `source.as.organization.name`, `source.geo.*` — is this a known scanner IP, hosting/VPS ASN, or unexpected geography for this application's userbase?
128  - `user_agent.original`  check for tool signatures (`sqlmap`, `Assetnote`, `Nessus`, `Nuclei`, etc.) vs. a spoofed browser UA
129- Determine which SQLi technique is present, since it changes the likely intent and next steps:
130  - **Boolean-blind** (`AND 1=1--`, `CASE WHEN...THEN...ELSE`)  attacker inferring true/false conditions one bit/char at a time; usually high request volume against the same parameter
131  - **Time-based blind** (`SLEEP`, `BENCHMARK`, `WAITFOR DELAY`, `pg_sleep`)  look for abnormal response latency on matching requests to confirm exploitation succeeded vs. was blocked
132  - **Error-based** (`EXTRACTVALUE`, `UPDATEXML`, `GTID_SUBSET`, `CONVERT(INT,...)`)  check `http.response.status_code`/body for a 500 or a reflected DB error message; if present, the attacker likely received leaked data directly
133  - **UNION-based** (`UNION SELECT NULL,...`, `UNION ALL SELECT...CONCAT(MD5(...`)  attacker is enumerating column count or confirming a reflection point to pull data directly into the page body
134  - **Stacked queries** (`;SELECT...`, `;EXEC xp_cmdshell`)  most severe; if the DB driver allows multiple statements, this can lead to command execution (`xp_cmdshell`) rather than just data disclosure
135- Pivot on the target parameter and endpoint (e.g. `url.path`, the specific query-string key such as `id=`, `sort=`, `column=`) to see:
136  - How many distinct payloads/techniques were tried against the same parameter (suggests automated technique-fuzzing by a single tool run)
137  - Whether the same `source.ip` hit multiple endpoints/parameters (broader scan) or repeatedly refined one payload (targeted exploitation attempt)
138- Check for a correlated spike in requests from the same IP/ASN in a tight time window  sqlmap and similar tools generate many rapid, near-identical requests when fuzzing technique/column count/character position.
139- If the backend database technology is known, cross-check the payload's SQL dialect (MySQL vs. MSSQL vs. PostgreSQL functions) against what the application actually runs — a payload using the wrong dialect's functions will simply error out and fail, lowering severity.
140- If available, correlate with database-side audit logs (e.g. MSSQL Audit `event.code: 33205`, slow query logs) for the same timeframe/client IP to confirm whether the payload actually reached and executed against the database.
141
142### False positive analysis
143
144- **Vulnerability scanners and security tooling** are the most common source of noise: Assetnote, Burp Suite, Qualys, Nessus, Acunetix, and similar tools intentionally send these exact payloads as part of authorized scanning. Check `user_agent.original` for scanner signatures and cross-reference `source.ip`/ASN against your organization's known scanning infrastructure or third-party ASM vendor.
145- Legitimate application traffic containing SQL-like keywords is rare given the specificity of these patterns (chained `CHAR()` calls, `ELT(n=n,1)` self-comparisons, hex-delimited `CONCAT`), but verify against applications that accept raw SQL fragments as legitimate input (e.g., internal admin/reporting tools with a "custom query" field) if any exist in your environment.
146- Consider adding a suppression/exception for confirmed, recurring authorized scanning sources rather than tuning the query patterns themselves, to avoid reducing detection coverage against real attackers using the same tools.
147
148### Response and remediation
149
150- If the request reached the application layer unblocked (`event.outcome: success` / 2xx response) and the payload matches an error-based or UNION-based technique, treat as a potential confirmed data exposure — check application/database logs for evidence of returned sensitive data.
151- If a stacked-query or `xp_cmdshell` payload succeeded, escalate immediately — this can lead to OS-level command execution, not just data disclosure.
152- Validate that the affected endpoint uses parameterized queries/prepared statements; SQL injection at this scale of tooling almost always indicates raw string concatenation in the query layer.
153- If exploitation is confirmed, review the database account's privileges used by the web application (least privilege should prevent `xp_cmdshell`, `INFORMATION_SCHEMA` enumeration, or cross-database access even if injection succeeds).
154- Block or rate-limit the source IP/ASN at the WAF or reverse proxy if not already filtered, and consider a virtual-patch WAF rule for the specific vulnerable parameter while the application fix is developed.
155- Review other requests from the same source IP across the retention window for prior reconnaissance (e.g., directory enumeration, parameter fuzzing) that may have preceded the injection attempt.
156"""
157
158[[rule.threat]]
159framework = "MITRE ATT&CK"
160
161[[rule.threat.technique]]
162id = "T1505"
163name = "Server Software Component"
164reference = "https://attack.mitre.org/techniques/T1505/"
165
166[rule.threat.tactic]
167id = "TA0003"
168name = "Persistence"
169reference = "https://attack.mitre.org/tactics/TA0003/"
170
171[[rule.threat]]
172framework = "MITRE ATT&CK"
173
174[[rule.threat.technique]]
175id = "T1059"
176name = "Command and Scripting Interpreter"
177reference = "https://attack.mitre.org/techniques/T1059/"
178
179[[rule.threat.technique.subtechnique]]
180id = "T1059.004"
181name = "Unix Shell"
182reference = "https://attack.mitre.org/techniques/T1059/004/"
183
184[rule.threat.tactic]
185id = "TA0002"
186name = "Execution"
187reference = "https://attack.mitre.org/tactics/TA0002/"
188
189[[rule.threat]]
190framework = "MITRE ATT&CK"
191
192[[rule.threat.technique]]
193id = "T1071"
194name = "Application Layer Protocol"
195reference = "https://attack.mitre.org/techniques/T1071/"
196
197[rule.threat.tactic]
198id = "TA0011"
199name = "Command and Control"
200reference = "https://attack.mitre.org/tactics/TA0011/"
201
202[[rule.threat]]
203framework = "MITRE ATT&CK"
204
205[[rule.threat.technique]]
206id = "T1595"
207name = "Active Scanning"
208reference = "https://attack.mitre.org/techniques/T1595/"
209
210[[rule.threat.technique.subtechnique]]
211id = "T1595.002"
212name = "Vulnerability Scanning"
213reference = "https://attack.mitre.org/techniques/T1595/002/"
214
215[[rule.threat.technique.subtechnique]]
216id = "T1595.003"
217name = "Wordlist Scanning"
218reference = "https://attack.mitre.org/techniques/T1595/003/"
219
220[rule.threat.tactic]
221id = "TA0043"
222name = "Reconnaissance"
223reference = "https://attack.mitre.org/tactics/TA0043/"
224
225[[rule.threat]]
226framework = "MITRE ATT&CK"
227
228[[rule.threat.technique]]
229id = "T1190"
230name = "Exploit Public-Facing Application"
231reference = "https://attack.mitre.org/techniques/T1190/"
232
233[rule.threat.tactic]
234id = "TA0001"
235name = "Initial Access"
236reference = "https://attack.mitre.org/tactics/TA0001/"

Triage and analysis

Investigating Web Server Potential SQL Injection Request

SQL injection (SQLi) attempts to manipulate backend database queries via unsanitized input passed through web request parameters. This rule flags requests whose URL or query string contains structural patterns characteristic of automated SQLi tooling (sqlmap and similar) or manual exploitation techniques, spanning boolean-blind, time-based, error-based, and UNION-based extraction methods across MySQL, MSSQL, PostgreSQL, and Oracle syntax.

Possible investigation steps

  • Identify the full request and response context:
    • url.original / url.query — full injected payload
    • http.request.method, http.response.status_code — was the request accepted (2xx) or rejected (4xx/5xx/WAF block)?
    • source.ip, source.as.organization.name, source.geo.* — is this a known scanner IP, hosting/VPS ASN, or unexpected geography for this application's userbase?
    • user_agent.original — check for tool signatures (sqlmap, Assetnote, Nessus, Nuclei, etc.) vs. a spoofed browser UA
  • Determine which SQLi technique is present, since it changes the likely intent and next steps:
    • Boolean-blind (AND 1=1--, CASE WHEN...THEN...ELSE) — attacker inferring true/false conditions one bit/char at a time; usually high request volume against the same parameter
    • Time-based blind (SLEEP, BENCHMARK, WAITFOR DELAY, pg_sleep) — look for abnormal response latency on matching requests to confirm exploitation succeeded vs. was blocked
    • Error-based (EXTRACTVALUE, UPDATEXML, GTID_SUBSET, CONVERT(INT,...)) — check http.response.status_code/body for a 500 or a reflected DB error message; if present, the attacker likely received leaked data directly
    • UNION-based (UNION SELECT NULL,..., UNION ALL SELECT...CONCAT(MD5(...) — attacker is enumerating column count or confirming a reflection point to pull data directly into the page body
    • Stacked queries (;SELECT..., ;EXEC xp_cmdshell) — most severe; if the DB driver allows multiple statements, this can lead to command execution (xp_cmdshell) rather than just data disclosure
  • Pivot on the target parameter and endpoint (e.g. url.path, the specific query-string key such as id=, sort=, column=) to see:
    • How many distinct payloads/techniques were tried against the same parameter (suggests automated technique-fuzzing by a single tool run)
    • Whether the same source.ip hit multiple endpoints/parameters (broader scan) or repeatedly refined one payload (targeted exploitation attempt)
  • Check for a correlated spike in requests from the same IP/ASN in a tight time window — sqlmap and similar tools generate many rapid, near-identical requests when fuzzing technique/column count/character position.
  • If the backend database technology is known, cross-check the payload's SQL dialect (MySQL vs. MSSQL vs. PostgreSQL functions) against what the application actually runs — a payload using the wrong dialect's functions will simply error out and fail, lowering severity.
  • If available, correlate with database-side audit logs (e.g. MSSQL Audit event.code: 33205, slow query logs) for the same timeframe/client IP to confirm whether the payload actually reached and executed against the database.

False positive analysis

  • Vulnerability scanners and security tooling are the most common source of noise: Assetnote, Burp Suite, Qualys, Nessus, Acunetix, and similar tools intentionally send these exact payloads as part of authorized scanning. Check user_agent.original for scanner signatures and cross-reference source.ip/ASN against your organization's known scanning infrastructure or third-party ASM vendor.
  • Legitimate application traffic containing SQL-like keywords is rare given the specificity of these patterns (chained CHAR() calls, ELT(n=n,1) self-comparisons, hex-delimited CONCAT), but verify against applications that accept raw SQL fragments as legitimate input (e.g., internal admin/reporting tools with a "custom query" field) if any exist in your environment.
  • Consider adding a suppression/exception for confirmed, recurring authorized scanning sources rather than tuning the query patterns themselves, to avoid reducing detection coverage against real attackers using the same tools.

Response and remediation

  • If the request reached the application layer unblocked (event.outcome: success / 2xx response) and the payload matches an error-based or UNION-based technique, treat as a potential confirmed data exposure — check application/database logs for evidence of returned sensitive data.
  • If a stacked-query or xp_cmdshell payload succeeded, escalate immediately — this can lead to OS-level command execution, not just data disclosure.
  • Validate that the affected endpoint uses parameterized queries/prepared statements; SQL injection at this scale of tooling almost always indicates raw string concatenation in the query layer.
  • If exploitation is confirmed, review the database account's privileges used by the web application (least privilege should prevent xp_cmdshell, INFORMATION_SCHEMA enumeration, or cross-database access even if injection succeeds).
  • Block or rate-limit the source IP/ASN at the WAF or reverse proxy if not already filtered, and consider a virtual-patch WAF rule for the specific vulnerable parameter while the application fix is developed.
  • Review other requests from the same source IP across the retention window for prior reconnaissance (e.g., directory enumeration, parameter fuzzing) that may have preceded the injection attempt.

Related rules

to-top