Forum Discussion

SteveEason's avatar
Oct 17, 2022

iRules to implement Security requirements in headers

We implemented at one point Policies to handle specific Security required header policies, however it appears they are not working currently (v16.1.3.1). The Security headers are for your typical entries, such as X-XSS-Protection, X-Content-Type-Options, X-Frame-Options and X-Cache-Control. None of those policies are showing up on the sites after being implemented. So we are attempting to do the same with iRules instead since I can see those showing up when we add just a simple fake header. 

I was searching DevCentral for some examples of iRules to accomplish what we are looking to accomplish but a lot of the ones I find are REALLY old and don't seem to work in the current version. So I'm hoping someone has a few they might be willing to share. 

For basics we just need to evaluate the current value of specific headers or determine if they exist and either replace or insert the desired value. However, with Cache-Control we need to insert one value if a URI has a specific file type (ie. .jpg, .css, .js, .gif, etc).  For those we want to insert a value of "no-cache". But everything else should have "no-store"

Here is a basic version of what I have started which doesn't include the Cache-Control portion. 

 

when HTTP_RESPONSE { 
    # Remove all instances of the Server header 
    HTTP::header remove Server
    HTTP::header insert "Strict-Transport-Security" "max-age=31536000" 

    if {!([ HTTP::header exists "X-Content-Type-Options" ])} { 
        HTTP::header insert "X-Content-Type-Options" "nosniff"}

    if {!([ HTTP::header exists "X-Frame-Options" ])} { 
        HTTP::header insert "X-Frame-Options" "SAMEORIGIN"}
		
	if {!([ HTTP::header exists "X-XSS-Protection" ])} { 
        HTTP::header insert "X-Frame-Options" "1;mode=block"}	
}

 

I had found one snippet that looked promising for the cache control based on file type, but the current version doesn't like it. 

 

class my_file_types { ".jpg" ".jpeg" ".css" ".js" ".ico" ".png" ".gif" ".svg" ".bmp" ".webp" ".avif" ".jxl" ".woff2" ".ttf" ".woff" ".mp4" }

when HTTP_REQUEST { if { [matchclass [HTTP::uri] ends_with $::my_file_types] } { HTTP::header replace Cache-Control "no-cache" } }

 

Any input would be welcome. I am also starting to dig through the documentation but I'm not a developer so it's a learning curve for me. Plus the situation with the Policies seemed a very easy way to implement these policies but that isn't working. I might open a ticket for that issue.

2 Replies

  • Classes are used to search data groups.

    There's probably way more elegant ways to do this, but the below extracts the ending from the HTTP::path and searches through the list of endings:

    when RULE_INIT {
        set static::endinglist { ".jpg" ".jpeg" ".css" ".js" ".ico" ".png" ".gif" ".svg" ".bmp" ".webp" ".avif" ".jxl" ".woff2" ".ttf" ".woff" ".mp4" }
    }
    when HTTP_REQUEST { 
        if { [lsearch -all $static::endinglist [string range [HTTP::path] [string last "." [HTTP::path]] end]] ne "" } {
            HTTP::header replace Cache-Control "no-cache"
        }
    }
  • Thanks for the input. I'll give that a try and see how that works out in our situation.