A look into sessions and security
Part #3: The score approach
In the third article I’ve reached the conclusion that the most important concepts when thinking about secure sessions are Coherence and Validity. I’ve also touched a very delicate point when dealing with those: false positives. No one wants to keep kicking the user out or worse, preventing the user to log back in when he/she haven’t done anything wrong. While this is a very valid point I’d argue that it’s best to wrongfully do so instead of getting your application hacked. There’s another way, though: keeping a score.
Score? What is this all about?
In theory it’s as straightforward as it sounds: Keeping a score, giving or taking points depending on the situation. In practice (and context) it’s much more complicated than that.
This approach makes a lot of sense because it lets us deal with the boolean concept of validity in a mathematical way, and therefore easily translatable to code.
Before we begin we need to decide if we’ll initially consider a session to be inherently valid or invalid. In security we more often than not apply the concept I like to call “guilty until proven innocent”: to be suspicious until we have some level of certainty. I often tell a little joke to my students, saying that the best security experts are “paranoid control freaks”. There’s a lot of truth — and efficiency — in that.
When dealing with sessions though, this concept doesn’t apply for a very simple reason: In order to consider a session invalid we need to collect data about it to determine it’s inconsistency and therefore unless a session was previously locked (see the past article on that), we have no other option than to consider it valid from the beginning.
Defining points, severities and thresholds
The entire point of this article is to provide ideas to make a system from which we can determine a session’s apparent validity. For that we’ll need an initial value, a scale, defining severity (and it’s numerical value) for each of the possible transgressions and finally a threshold from which a session can no longer be considered valid.
Scale, initial value, and threshold
We begin our scale considering a session to be perfectly valid (10). The valid threshold goes until 8 and if it goes any lower than that we need to take action. The kind of action to be taken will be determined, obviously, by how low the session will descent on our scale.
On suspicion and action
Between 7 and 6 (Suspicious), detailed logging must take place. It’s when we keep our user under heavy scrutiny and while maintaining a decent level of privacy we need to know which actions the user will take in our application (e.g. is he/she going to delete something? modify something?).
Taking the complexity up to a whole different level, we could (should?) implement a level of granularity that raises the security on our application even more: I’d argue that, on applications that need a strict security implementation, actions should begin to be less and less available to the user as he/she proceeds. A “level 7” score, for an example, shouldn’t be able to “truly delete” something, while a level 6 should be logged out and forced to log back in. Anything below that should be automatically locked and analysed.
 This goes beyond the scope of this article, but a very good reference for this can be found, as usual, at OWASP: more specifically in the ASVS project.
 The good ol’ “flagging x deleting” strategy.
Collected data, transgressions and severity
As we’ve determined, we need to collect some data about the session in order to be able to define it’s validity. I’d argue that the more data (always respecting a decent level of privacy) we have the best. User browser, OS (if possible), IP address, and so on.
Also, for the purposes of consistency of implementation, we should define the possible severities and their quantified values. I’d propose a simple Low (-1), Medium (-2), High (-4) and Critical (-5) set, with the advantage that, if necessity arrives, we could easily insert middle-grounds between them.
While it may appear that low transgressions may not be useful, the concept here resides on the number of occurrences inside a session. It’s basically asking “How many times a user can do this inside the same session?”.
I obviously didn’t — and won’t — covered all possible cases of what I call “transgression”, but I’ll explore an additional one in here, which I believe to be self-explanatory (similar to the IP case).
Transgression: User’s browser changes inside a session
Proposed Value (Severity): -1 (low)
Transgression: User’s IP changes inside a session
Proposed Value (Severity): -2 (medium)
Transgression: Session token mismatch/non-existent
Proposed Value (Severity): -4 (high)
Transgression: User‘s role changes without admin intervention
Proposed Value (Severity): -5 (critical)
Transgression: Attempt to change the User’s account ID inside a session
Proposed Value (Severity): -5 (critical)
I believe you’ve got the idea at this point.
“But… but… in my case this is not…”
I know, I know, believe me. There are a lot of practical issues to be considered, but security isn’t optional or dependent on whims and special cases. It simply can’t be.
The advantage of this approach, when allied with consistent logging and debugging practices, is that not only the number of false positives should drop but you can also learn and refine the score system as you go.
On the next (and last) article of this series I’ll talk about sessions & time and present a logical sketch that encompasses the topics covered here. See you then!