HTTP triggers and the flow store

triggers

#1

To cut to the chase on this somewhat longer note:

When using flow store variables
to pass information from HTTP request
triggers to HTTP response triggers, it
is good practice to explicitly unset
a flow store variable after it’s last
accessed in the response trigger.

Read on if you’re interested in why.

The “Flow.” object in an HTTP trigger is tied to the TCP connection between the HTTP client and HTTP server where the action is happening. So setting a Flow.store variable associates the variable with the TCP connection, not directly with the HTTP request/response pair.

Through the use of HTTP persistent connections (aka keepalive), a single TCP connection commonly handles a sequence of multiple HTTP request/response pairs. That makes it possible to write trigger logic where a flow store variable is set in an early HTTP request trigger but lives on in a way that it’s available to future, unrelated HTTP response triggers.

Here’s an example of how that might happen.

Suppose you’re interested in analyzing web login traffic for a user named ‘charlie’ and that traffic is distinguishable because it includes ‘charlie’ in the HTTP request payload. Suppose that such a login HTTP request for ‘charlie’ flows over a TCP connection followed by a second non-login HTTP request. Here’s how the trigger logic might play out.

Trigger A executes on HTTP Request #1 (which does involve charlie logging in):

if http request payload mention charlie
   Flow.store.userName=”charlie”   //this line is executed
else
   exit

Trigger B executes on the response to HTTP request #1: (which does involve charlie)

var user = Flow.store.userName   //user var correctly gets ‘charlie’
if user is charlie
   // processing continues

All good so far.

Trigger A later executes again on HTTP request #2 (which does not involve a charlie login):

if http request payload mention charlie
   Flow.store.userName=”charlie”   
else
   exit   //this line is executed, userName does not get (re)set

Trigger B executes on response to HTTP request #2 (which again, does not involve charlie):

var user = Flow.store.userName   // user var incorrectly gets ‘charlie’ because it’s
                                 // associated with the flow and hasn’t been changed
                                 // or unset
if user is charlie
   // processing incorrectly continues

You can avoid this pitfall by paying careful attention to your logic across the A and B triggers to ensure such a code path isn’t possible. But one “sledgehammer” way to ensure such code paths don’t happen is to simply clear any flow variable after it’s been retrieved into a local trigger variable. In the example above, you would adapt the logic of trigger B by adding a line as follows:

var user = Flow.store.userName
Flow.store.userName = null;
if user is charlie
   // processing continues

#2

Thanks for laying this out for us - really nicely done.