diff --git a/internal/apps/agent/nginx/waf_runtime.lua b/internal/apps/agent/nginx/waf_runtime.lua index e5586891..cee05b80 100644 --- a/internal/apps/agent/nginx/waf_runtime.lua +++ b/internal/apps/agent/nginx/waf_runtime.lua @@ -439,6 +439,72 @@ local function security_match_any(haystacks, patterns) return false end +-- SQL sleep/benchmark: require digit arg to avoid product names like sleep(better). +local function security_match_sql_timed(haystacks) + for _, hay in ipairs(haystacks) do + if type(hay) == "string" and hay ~= "" then + if string.find(hay, "sleep(%d", 1, true) or string.find(hay, "benchmark(%d", 1, true) then + return true + end + -- Also accept sleep( 1 ) with optional spaces: sleep( + digit + local i = 1 + while true do + local s, e = string.find(hay, "sleep(", i, true) + if not s then break end + local rest = string.sub(hay, e + 1) + if string.match(rest, "^%s*%d") then return true end + i = e + 1 + end + i = 1 + while true do + local s, e = string.find(hay, "benchmark(", i, true) + if not s then break end + local rest = string.sub(hay, e + 1) + if string.match(rest, "^%s*%d") then return true end + i = e + 1 + end + end + end + return false +end + +-- XSS: tag/event handlers and URI schemes; skip prose like "javascript: the good parts". +local function security_match_xss(haystacks) + local tag_like = { "