Skip to content

Commit 9f71f2e

Browse files
committed
Improve attack detection with header analysis
- Include headers in pattern detection (Referer, etc.) - Add HAS_REFERER flag for requests with Referer header - Include Referer content in payload analysis - Fix redirect URL handling in downloader for HuggingFace CDN - Increase payload snippet size to 300 chars This enables detection of SQLi attacks hidden in Referer headers, a common attack vector found in real-world nginx logs.
1 parent 010eda1 commit 9f71f2e

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ pkg/
2222

2323
# macOS
2424
.DS_Store
25+
test_app/

lib/ai_bouncer/classifier.rb

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,22 @@ def self.request_to_text(method:, path:, body: "", user_agent: "", params: {}, h
7373
parts << "BODY_SIZE:#{size_bucket}"
7474
end
7575

76-
# Header count
77-
parts << "HEADERS:#{headers.size}" if headers.any?
76+
# Header analysis
77+
if headers.any?
78+
parts << "HEADERS:#{headers.size}"
79+
# Include header values for pattern detection
80+
headers.each do |name, value|
81+
next if value.nil? || value.empty?
82+
# Flag suspicious header names
83+
if name.downcase == "referer" || name.downcase == "referrer"
84+
parts << "HAS_REFERER"
85+
end
86+
end
87+
end
7888

79-
# Suspicious pattern detection
80-
combined = "#{path} #{body} #{params.values.join(' ')}"
89+
# Suspicious pattern detection - include headers in combined text
90+
header_values = headers.values.compact.join(' ')
91+
combined = "#{path} #{body} #{params.values.join(' ')} #{header_values}"
8192

8293
if combined =~ /\b(SELECT|INSERT|UPDATE|DELETE|DROP|UNION|OR\s+\d|--|')/i
8394
parts << "FLAG:SQL_KEYWORDS"
@@ -95,9 +106,17 @@ def self.request_to_text(method:, path:, body: "", user_agent: "", params: {}, h
95106
parts << "FLAG:CMD_INJECTION"
96107
end
97108

98-
# Include payload snippet
99-
payload = body.to_s.empty? ? params.to_s : body.to_s
100-
parts << "PAYLOAD:#{payload[0, 200]}" unless payload.empty?
109+
# Include payload snippet (body, params, and suspicious headers)
110+
payload_parts = []
111+
payload_parts << body.to_s unless body.to_s.empty?
112+
payload_parts << params.to_s unless params.empty?
113+
# Include Referer if present (common attack vector)
114+
if headers["Referer"] || headers["referer"]
115+
referer = headers["Referer"] || headers["referer"]
116+
payload_parts << "REFERER:#{referer}" unless referer.empty?
117+
end
118+
payload = payload_parts.join(" ")
119+
parts << "PAYLOAD:#{payload[0, 300]}" unless payload.empty?
101120

102121
parts.join(" ")
103122
end

lib/ai_bouncer/downloader.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ def download_file(url, dest_path, max_redirects: 5)
7676

7777
uri = URI.parse(url)
7878

79+
raise DownloadError, "Invalid URL: #{url}" unless uri.host
80+
7981
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
8082
http.read_timeout = 300 # 5 minutes for large files
8183
http.open_timeout = 30
@@ -93,6 +95,11 @@ def download_file(url, dest_path, max_redirects: 5)
9395
end
9496
when Net::HTTPRedirection
9597
new_url = response["location"]
98+
# Handle relative redirects
99+
new_uri = URI.parse(new_url)
100+
if new_uri.relative?
101+
new_url = URI.join("#{uri.scheme}://#{uri.host}:#{uri.port}", new_url).to_s
102+
end
96103
download_file(new_url, dest_path, max_redirects: max_redirects - 1)
97104
else
98105
raise DownloadError, "HTTP #{response.code}: #{response.message} for #{url}"

0 commit comments

Comments
 (0)