Redirect Location header validator
Problem this snippet solves:
This iRule demonstrates how to validate the 30x redirects a web application sends back to clients. It intercepts any redirects which are to a domain that is not in a whitelist string data group. The goal is to protect clients from a web application which does not provide complete validation of user-input when generating HTTP redirects. See the OWASP Top Ten page for details on this class of vulnerability:
OWASP Top Ten Unvalidated Redirects and Forwards
Code :
# Validate the 30x redirects the web application sends to clients against a whitelist stored in a data group
# The goal is to prevent the client from being tricked into receiving an unvalidated redirect to a malicious third party site
# by an attacker. See the OWASP Top Ten for details on the vulnerability: https://www.owasp.org/index.php/Top_10_2010-A10-Unvalidated_Redirects_and_Forwards
# The data group format is string. v11 example:
#
#ltm data-group internal my_domain_whitelist_dg {
# records {
# example.com { }
# example.net { }
# example.org { }
# example.co.uk { }
# partner.com { }
# }
# type string
#}
when RULE_INIT {
# Name of the string data group which contains the whitelisted domains
# (ex: legal.com, legal.net, okay.org, etc)
set static::domain_whitelist_dg "my_domain_whitelist_dg"
# Log debug to /var/log/ltm? 1=yes, 0=no.
set static::redirect_debug 1
}
when HTTP_RESPONSE {
# Check if domain is a redirect
if {[HTTP::is_redirect]}{
if {$static::redirect_debug}{
log local0. "[IP::client_addr]:[TCP::client_port]: status=[HTTP::status], Location=[HTTP::header Location], Server=[LB::server]"
}
# Check if the redirect location is an absolute URL
switch -glob [HTTP::header Location] {
"/*" -
"" {
# No Location header value or a local reference so do not check against whitelist
if {$static::redirect_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Location local or empty. Not validating"}
}
default {
# Check Location value against the data group
set hostname [string tolower [URI::host [HTTP::header Location]]]
if {$static::redirect_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Checking $hostname against $static::domain_whitelist_dg"}
# Check the hostname against the whitelist
if {[class match $hostname ends_with $static::domain_whitelist_dg]}{
if {$static::redirect_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Legal redirect to [HTTP::header location]"}
} else {
if {$static::redirect_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Illegal redirect to [HTTP::header location]"}
HTTP::respond 302 Location "http://www.example.com/redirect_blocked.html"
}
}
}
}
}Published Mar 18, 2015
Version 1.0hoolio
Cirrostratus
VP of Solutions at WorldTech IThoolio
Cirrostratus
VP of Solutions at WorldTech ITNo CommentsBe the first to comment