Forum Discussion

steveh's avatar
steveh
Icon for Nimbostratus rankNimbostratus
Jun 18, 2008

irule based persistence - security problem

A security issue was identified recently, that I'd like to address with my irules, however the implementation is not so straight forward it seems.

I've had nothing but problems trying to use 'persist lookup' and 'session lookup' commands in my irules, but i can't see the reason for the infamous "prerequisite operation not in progress" error.

NB: due to my delivery model, there can be no default pool configured for the virtual server. pool usage is decided and handled in the irule.

What I'm trying to achieve is simple (or so I thought): store the uri, used to get the session, in the persistence table, and verify that all subsequent requests referencing that session use the same 'uri' as the initial request where the session as issued under.

iRule:

 
 when CLIENT_ACCEPTED { 
 set add_persist 1 
 set DEBUG 1 
 } 
  
 when HTTP_REQUEST { 
 set req_uri [string tolower [URI::path [HTTP::uri] 1 1]] 
 switch -glob $req_uri { 
 "/" - 
 "/?Open*" - 
 "*.exe*" - 
 "*.dll*" - 
 "*.pl*|" - 
 "*.php*;*" - 
 "/index.html" - 
 "/manager*" - 
 "/status*" - 
 "/sysProps*" - 
 "/healthCheck*" { 
  Unautorized Access Attempted 
 log local0. "Unauthorized access by Host [IP::remote_addr] detected for URI: [HTTP::uri]" 
 HTTP::respond 404 "Access ForbiddenThis security violation has been logged." 
 } 
 } 
 set http_request_time [clock clicks -milliseconds] 
 set request_log_line "[HTTP::request_num] - [IP::remote_addr] - [HTTP::method] - [HTTP::version] - [HTTP::host] - \"[HTTP::uri]\" - \" [HTTP::header value Referer] \" - \"[HTTP::header User-Agent]\" - \"[HTTP::cookie value JSESSIONID]\" - [SSL::cipher name] - [SSL::cipher version] - [SSL::cipher bits]" 
 if { [HTTP::cookie exists JSESSIONID] } { 
 set sid [HTTP::cookie JSESSIONID] 
 set orig_uri [session lookup uie [list $sid any virtual]] 
 log local0.crit "lookup original URI: $orig_uri" 
 if { $DEBUG } { 
 log local0.crit "Got request with sid: $sid; req-URI: $req_uri; http-request: [HTTP::uri]" 
 } 
 if { $orig_uri equals $req_uri } { 
 if { $DEBUG } { 
 log local0.crit "orig: $orig_uri, curr: $req_uri; got valid result from lookup and servicing request" 
 } 
 persist uie $sid 
 } else { 
 if we get here, we have an error 
 if { $DEBUG } { 
 log local0.crit "Persistence entry: [HTTP::cookie JSESSIONID] has URI: $orig_uri, but I got $req_uri. Request cannot be handled!" 
 } 
 HTTP::respond 404 "Access ForbiddenThis security violation has been logged." 
 } 
 } 
 switch -glob [string tolower [HTTP::uri]] { 
 "/client01*" { 
 Maintenance page redirect 
 HTTP::redirect http://www.foo.com/maintenance/maintenance.htm 
 } 
 "/sec_prod*" { 
 use pool eapp_clu01 
 } 
 "/sec_stage*" { 
 use pool stage_clu04 
 } 
 } 
 } 
  
 when HTTP_RESPONSE { 
 HTTP::header replace Server "HaloWeb" 
 HTTP::header replace X-Powered-By "HaloWeb Hosting Solution" 
 if { [HTTP::cookie exists "JSESSIONID"] and $add_persist } { 
 set persist_string "[HTTP::cookie JSESSIONID]:$req_uri" 
 set sid [HTTP::cookie JSESSIONID] 
 persist add uie $sid 1920 
 session add uie $sid $req_uri 1920 
 if { $DEBUG } { 
 log local0.crit "Create new persistence hash: $sid, stored URI: $req_uri" 
 } 
 set add_persist 0 
 } 
 if { [HTTP::header exists "Content-Length"] } { 
 set content_length [HTTP::header "Content-Length"] 
 } else { 
 set content_length 1 
 } 
 set http_response_time [clock clicks -milliseconds] 
 log local0. "$request_log_line - [HTTP::status] - $content_length - [expr $http_response_time - $http_request_time] - pool [LB::server pool] - node [LB::server addr]:[LB::server port]" 
 } 
 

Any help appreciated.

thanks,

steve

1 Reply

  • Spark's explanation seems appropriate:

     

     

     

    http://devcentral.f5.com/Default.aspx?tabid=53&view=topic&postid=10181&ptarget=23693

     

    spark

     

    I see that the documentation indeed does not list AUTH_SUCCESS as an allowed event for the session command. The lists of allowed events are currently one of the biggest weaknesses of the iRules wiki; I can assure you that we're working on it. Please also know that the session command is allowed in the AUTH_SUCCESS event, as well as most others.

     

     

    The most common reason for the "Prerequisite operation not in progress" error when using the session or persist commands is that you don't have a default pool defined. By default, persist and session records are tied to a pool, so if you don't currently have one then you get that error (but it may happen in other ways too; this is just the most common). So, either assign a default pool, or specify that the record should not be tied to a pool (via the "any virtual" option), and that should fix the error.

     

     

     

     

    The session wiki page has details on the any virtual option:

     

     

     

    http://devcentral.f5.com/Wiki/default.aspx/iRules/session

     

     

    When using the latter key specification above (e.g. = { any virtual }), the session command expects the key (the data and associated "any virtual" commands) to be a single argument; in other words, a list. Often, users will want to specify some variable data in such a command. However, the usual way of creating a list (via braces, as shown above) will inhibit variable and command expansion. See http://devcentral.f5.com/Default.aspx?tabid=63&articleType=ArticleView&articleId=120 for more information on this. To use variables and commands with these key specifications, users should either use the list command to construct a list, or use double quotes, which Tcl will interpret as a list. See the last two examples below.

     

     

     

     

    Aaron