SameSite cookies

Recently, while reading through the updated 2017 OWASP Top Ten RC1 documentation, last updated in 2013, I noticed a recommendation to use Cookies with the “SameSite=strict” value set to reduce CSRF exposure in section A8.

Consider using the “SameSite=strict” flag on all cookies, which is increasingly supported in browsers.

Similar to the way that HttpOnly and Secure attributes have been added, SameSite allows for additional control.

Per the documentation, as of April 2017 the SameSite attribute is implemented in Chrome 51 and Opera 39. Firefox has an open defect, but I would expect it to be added soon to follow Chrome.


Set-Cookie: CookieName=CookieValue; SameSite=Lax;
Set-Cookie: CookieName=CookieValue; SameSite=Strict;

According to the specification you can issue the SameSite flag without a value and Strict will be assumed:


Set-Cookie: CookieName=CookieValue; SameSite

As many programming languages and server runtime environments do not yet support this for session cookies, you can use the Apache Tier1 configuration to append them.


Header edit Set-Cookie ^(JSESSIONID.*)$ $1;SameSite=Strict
Header edit Set-Cookie ^(PHPSESSID.*)$ $1;SameSite=Strict

It looks like PHP.INI might support the following attribute in a future release, but it’s not there yet!

session.cookie_samesite

REFERENCES:

Renaming PHPSESSID

Like in Java, securing/renaming the PHP Session ID is simply a configuration item, generally this value is set as a cookie, but occasionally gets used in cases of URL Rewriting.

On Ubuntu your settings can be changed as follows, Windows will use the same settings in the appropriate file:

  1. sudo vi /etc/php5/apache2/php.ini
  2. Modify the following values as needed:

    session.name = "PHPSESSID"
    session.cookie_httponly = 1

REFERENCES

Renaming JSESSIONID

Older versions of Apache Tomcat, as well as the older servlet specifications required that several configuration values need to be set. With servlet 3, you can now modify the name of the session cookie (as well as the ‘rewriting’ attribute name) in the web.xml file

In web.xml: (servlet 3.x)

<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<name>mysessionid</name><!-- default is jsessionid -->
<http-only>true</http-only>
<!-- secure>true</secure-->
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>

Alternately for Tomcat7, modify TOMCAT_HOME\conf\context.xml:
<Context path="/exampleApp" sessionCookieName="myid">

If you are using spring security, then you should try setting disable-url-rewriting attribute of <http> element to true.

REFERENCES:

HTTP Session Hijacking (Firesheep)

This topic, and Firefox add-on have received a lot of press lately, as such I figured that I’d capture some comments on the topic. HTTP Session hijacking is nothing new, anyone with the ability to monitor your non-secured network traffic can do this with little effort… what’s happened here is that there are now some really simple to use tools to do the job.

In the past, someone would have to passively monitor your network traffic with a tool like WireShark, and all they’d really have to do is wait for you to access a website to watch the ‘HTTP Cookies’ (or even a URL that contains a ‘session id’). With that information, they simply need to use the same value that you do to essentially take over your session and your current state. Banks are particularly at risk for this, but in most cases they use HTTPS/SSL for all secure data including logins. Social websites such as Facebook and even GMail, often default to non-secure logins to maximize their server and network performance.

Best defense here… never use non-secure login forms, especially when using a public wireless (or wired) network.

Interesting enough, there’s now a Firefox add-on that monitors for usage of Firesheep on the network, unfortunately neither of these currently work in Linux… links below!

Clientside Session Timeout’s

There comes a time in web application development that you need to ‘timeout’ idle users. This comes in a variety of ways, here’s a few common reasons that you may desire this activity.

  • Security – you don’t want to leave sensitive data on a users screen when they’ve gone to lunch or left for the day.
  • Server Resources – persisting/keeping an active ‘session’ available on the server takes resources (the exact type varies, but this is usually database, memory or file resources)
  • Server ‘enforced’ session timeout’s and the potential errors and lost data experienced by the users in that circumstance.

My personal approach to this has evolved over time, here’s a brief synopsis:

  1. Use standard server-side session timeout, often leading to a bad user experience when they loose data on a form submit.
  2. Use META REFRESH…where timeout is in seconds, in this example it’s 60 seconds (1 minute).
    <meta http-equiv="refresh" content="60;url=http://www.giantgeek.com/" />
  3. Use javascript 'timeout' (problem is that this is not 'measureable')
    
    <script type="text/javascript">
    setTimeout("javascript:myTimeout();",minutes*60000); // code minutes
    </script>
  4. Use javascript countdown timer and custom code event.

<html>
<head>
<title>Timeout example</title>
<script type=”text/javascript”>
var build=’testing’;
var timerID = 0;
var loadTime = null;
var stopTime = null;
function xload(){
loadTime=grvMillis();
grvWindowStatus(build);
grvSetTimeout();
}
function xclose(){
grvWindowStatus(”);
}
function grvMillis(){
return new Date().getTime();
}
// Start timer
function grvTimerUpdate(){
timerID = grvTimerClear(timerID);
if(loadTime == null){
loadTime=grvMillis();// Start Time
}
// Calculate Current Time in seconds
var timeNow = grvMillis();

var think = calcMinSec( calcTimeDiff(timeNow,loadTime) );
var remain = calcMinSec( calcTimeDiff(stopTime,timeNow) );
grvWindowStatus(build + ” ” + think + ” ” + remain );
timerID = setTimeout(“grvTimerUpdate()”,1000);
}
function calcMinSec(diff){
var mm = removeDecimal(diff/60);
var ss = zeroPad(removeDecimal(diff-(mm*60)),2);
return (mm + “:” + ss);
}
function calcTimeDiff(tmpStart,tmpStop){
var diff = (tmpStart – tmpStop)/1000;
return diff;
}
function removeDecimal(val){
var rc=””;
val = val + “”;
if(val!=””){
var pos = val.indexOf(“.”);
if(pos > -1){
rc=val.substr(0,val.indexOf(“.”));
} else {
rc=val;
}
}
return rc;
}
function zeroPad(x,sz){
x = x + “”;
while(x.length < sz){
x = “0” + x;
}
return x;
}
function grvTimerClear(x){ // this clears a timer from the queue
if(x){
clearTimeout(x);
x = 0;
}
return x;
}
function grvSetTimeout(){
var min=45; xID=grvTimeout(“javascript:grvTimeoutUSER()”,min); // EXAMPLE: this could be conditional!
stopTime = grvCalculateTimeout(min);
grvTimerUpdate();
}
function grvCalculateTimeout(mins){
var timeNow = grvMillis();
var exp = timeNow + (mins*60*1000);
var timeExp = new Date(exp).getTime();
return timeExp;
}
function grvTimeout(x,minutes){ // this sets a timer(request) in a queue
return setTimeout(x,minutes*60000);
}
function grvTimeoutUSER(){
alert(‘Session Inactivity Timeout [USER]’);
// DO WHAT YOU NEED TO HERE!}
function grvWindowStatus(txt){
window.defaultStatus=txt;
}
</script>
</head>
<body onunload=”xclose();” onload=”xload();”>
</body>
</html>

Another benefit of this last solution is that you also have access to the user “Think Time” and can therefore measure how long the user spends on a given page.

Cheers!