The only problem I can see with your code is that there is no command "Discard". When I try to load your rule I get an error stating invalid command.
More than likely a reject will do what you want. Try this code out.
when HTTP_REQUEST {
if { [HTTP::uri] contains "'" } {
log local0. "found quote in URI"
reject
}
}
I've verified that it will identify single quotes within a uri.
With regards to string literals. You can also enclose them with curly braces instead of quotes. This code is functionally equivalent to the above:
when HTTP_REQUEST {
if { [HTTP::uri] contains {'} } {
log local0. "found quote in URI"
reject
}
}
Another thing to keep in mind when dealing with special characters in the URI is to make sure you decode the URI before you do a string comparison. Spaces will convert to %20, double quotes to %22, percent sign to %25, etc. Single quotes are not encoded by browsers by default but that's not to stop someone from replacing the quote with "%27" in the URI. What's more, you can encode a string multiple times so some times a single decoding isn't good enough.
The following strings are equivalent URIs.
http://www.foo.com/path?foo'bar
http://www.foo.com/path?foo%27bar
http://www.foo.com/path?foo%2527bar
http://www.foo.com/path?foo%252527bar
http://www.foo.com/path?foo%25252527bar
So to correctly cover all bases, you'll want to build a loop to call decode on the uri until the decoded version doesnt' change. Luckily we have a method to decode the URI, but you'll have to code the loop. Something like this should do the trick.
when HTTP_REQUEST {
loop until URI is fully decoded
set tmpUri [HTTP::uri]
set uri [URI::decode $tmpUri]
while { $uri ne $tmpUri } {
set tmpUri $uri
set uri [URI::decode $tmpUri]
}
if { $uri contains "'" } {
log local0. "found quote in URI"
reject
}
}
-Joe