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!



Brotli Compression

If you look at HTTP Headers as often as I do, you’ve likely noticed something different in Firefox 44 and Chrome 49. In addition to the usual ‘gzip’, ‘deflate’ and ‘sdhc’ , a new value ‘br’ has started to appear for HTTPS connections.





Compared to gzip, Brotli claims to have significantly better (26% smaller) compression density woth comparable decompression speed.

The smaller compressed size allows for better space utilization and faster page loads. We hope that this format will be supported by major browsers in the near future, as the smaller compressed size would give additional benefits to mobile users, such as lower data transfer fees and reduced battery use.


  • Brotli outperforms gzip for typical web assets (e.g. css, html, js) by 17–25 %.
  • Brotli -11 density compared to gzip -9:
  • html (multi-language corpus): 25 % savings
  • js (alexa top 10k): 17 % savings
  • minified js (alexa top 10k): 17 % savings
  • css (alexa top 10k): 20 % savings

NOTE: Brotli is not currently supported Apache HTTPd server (as of 2016feb10), but will likely be added in an upcoming release.[email protected]%3E

Until there is native support, you can pre-compress files by following instructions here…


Google and Facebook bypassing P3P User Privacy Settings

I wrote about P3P a very long time ago, and have implemented it on several websites. Some history, the W3C crafted the P3P policy.
Microsoft introduced P3P support in IE6 (in 2001) and it remains implemented in all current versions of the browser. The primary intended use is to block 3rd party cookies within the browser on behalf of the user.

Interesting enough, Microsoft has had been a bit of a struggle with Google and Facebook, which send the following HTTP response headers.

Google’s Response:

P3P: CP="This is not a P3P policy! See for more info."

Facebook’s response:

P3P: CP="Facebook does not have a P3P policy. Learn why here:"


Java User-Agent detector and caching

It’s often important for a server side application to understand the client platform. There are two common methods used for this.

  1. On the client itself, “capabilities” can be tested.
  2. Unfortunately, the server cannot easily test these, and as such must usually rely upon the HTTP Header information, notably “User-Agent”.

Example User-agent might typically look like this for a common desktop browser, developers can usually determine the platform without a lot of work.

"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; InfoPath.3)"

Determining robots and mobile platforms, unfortunately is a lot more difficult due to the variations. Libraries as those described below simplify this work as standard Java Objects expose the attributes that are commonly expected.

With Maven, the dependencies are all resolved with the following POM addition:


/* Get an UserAgentStringParser and analyze the requesting client */
final UserAgentStringParser parser = UADetectorServiceFactory.getResourceModuleParser();
final ReadableUserAgent agent = parser.parse(request.getHeader("User-Agent"));

out.append("You're a '");
out.append("' on '");

As indicated on the website documentation, running this query for each request uses valuable server resources, it’s best to cache the responses to minimize the impact!

NOTE: the website caching example is hard to copy-paste, here’s a cleaner copy.

package com.example.cache;

import java.util.concurrent.TimeUnit;
import net.sf.uadetector.ReadableUserAgent;
import net.sf.uadetector.UserAgentStringParser;
import net.sf.uadetector.service.UADetectorServiceFactory;

* Caching User Agent parser
* @see
* @author Scott Fredrickson [skotfred]
* @since 2015jan28
* @version 2015jan28
public final class CachedUserAgentStringParser implements UserAgentStringParser {

private final UserAgentStringParser parser = UADetectorServiceFactory.getCachingAndUpdatingParser();
private static final int CACHE_MAX_SIZE = 100;
private static final int CACHE_MAX_HOURS = 2;
* Limited to 100 elements for 2 hours!
private final Cache<String , ReadableUserAgent> cache = CacheBuilder.newBuilder().maximumSize(CACHE_MAX_SIZE).expireAfterWrite(CACHE_MAX_HOURS, TimeUnit.HOURS).build();

* @return [email protected] String}
public String getDataVersion() {
return parser.getDataVersion();
* @param userAgentString [email protected] String}
* @return [email protected] ReadableUserAgent}
public ReadableUserAgent parse(final String userAgentString) {
ReadableUserAgent result = cache.getIfPresent(userAgentString);
if (result == null) {
result = parser.parse(userAgentString);
cache.put(userAgentString, result);
return result;
public void shutdown() {


HTTP Strict Transport Security (HSTS)

The HTTP Strict Transport Security feature lets a web site inform the browser that it should never load the site using HTTP, and should automatically convert all attempts to access the site using HTTP to HTTPS requests instead.

Example Use case:
If a web site accepts a connection through HTTP and redirects to HTTPS, the user in this case may initially talk to the non-encrypted version of the site before being redirected, if, for example, the user types or even just

This opens up the potential for a man-in-the-middle attack, where the redirect could be exploited to direct a user to a malicious site instead of the secure version of the original page.

For HTTP sites on the same domain it is not recommended to add a HSTS header but to do a permanent redirect (301 status code) to the HTTPS site.

Google is always “tweaking” their search algorithms, and, at least at present time, gives greater weight to secure websites.

# Optionally load the headers module:
LoadModule headers_module modules/

<VirtualHost *:443>
# Guarantee HTTPS for 1 Year including Sub Domains
Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"

Then you might (optionally, but recommended) force ALL HTTP users to HTTPS:

# Redirect HTTP connections to HTTPS
<VirtualHost *:80>
ServerAlias *
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
#RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301]

That’s it…


Security through obscurity – hiding your server version information

I’ve recently spent a lot of time reviewing the OWASP documentation, and (like many corporations) realized that I’d neglected to keep up with this configuration item.

By sharing the exact version of each piece of server software you are using, “hackers” are able to quickly identify unpatched systems and their known vulnerabilities.

To make their work harder, there are a few simple steps that the server admin can take to remove this information from the HTTP Headers and error pages.

Apache HTTPd:

  1. sudo vi /etc/apache2/conf-enabled/security.conf
  2. Add:

    ServerTokens ProductOnly
    ServerSignature Off
  3. If using virtual hosts, add the following to each one:
    ServerSignature Off
  4. sudo service apache2 restart

Apache Tomcat:

  1. vi /opt/tomcat7/conf/server.xml
  2. Find the <Connector > entry and add:
  3. cd /opt/tomcat7/lib
  4. mkdir -p org/apache/catalina/util
  5. vi /opt/tomcat7/lib/org/apache/catalina/util/ Tomcat
  6. sudo service tomcat7 restart

PHP “X-Powered-By: PHP/5.x.x-1ubuntuX.X”

  1. sudo vi /etc/php5/apache2/php.ini
    expose_php = Off
  2. sudo service apache2 restart


Preventing Blackberry browser from messing up your UI

I’ve previously given steps to prevent phone numbers (and other elements) from being automatically reformatted by Skype Toolbar and IOS Safari, there is still a small segment of the user population that uses Blackberry devices that can similarly benefit from a little code.

The following stops auto detection and formatting of phone and email addresses on devices with the BlackBerry Browser.


<meta http-equiv="x-rim-auto-match" content="none" />


<meta name="x-rim-auto-match" http-equiv="x-rim-auto-match" forua="true" content="none" />


Content-Security-Policy HTTP Header

There’s yet another new means to ‘help’ client User-Agents with preventing XSS on your websites.

In it’s simplest form you can simply use the following HTTP Header(s), the second one is for earlier versions of Webkit (Chrome/Safari):

Content-Security-Policy: default-src 'self'
Webkit-CSP: default-src 'self'

You can also add to the above to permit assets to load from other sources.
For example, if you were to permit javascript files from you could include:

Content-Security-Policy: default-src 'self'; script-src

Additionally, while failures are noted in the client’s browser console (that most users are not aware of), you can have them sent back to your server by adding a ‘report-uri’ attribute with an appropriate handler:

Content-Security-Policy: default-src 'self'; report-uri


Google ChromeFrame

There was some debate back when this was first revealed in 2009, but the use of ChromeFrame is still relevant for some organizations that are stuck on older browsers for legacy applications.

<meta http-equiv="X-UA-Compatible" content="chrome=1" /><!-- this is for all versions of IE -->
<meta http-equiv="X-UA-Compatible" content="chrome=IE6" /><!-- this is for IE6 and lower -->
<meta http-equiv="X-UA-Compatible" content="chrome=IE7" /><!-- this is for IE7 and lower -->
<meta http-equiv="X-UA-Compatible" content="chrome=IE8" /><!-- this is for IE8 and lower -->
<meta http-equiv="X-UA-Compatible" content="chrome=IE9" /><!-- this is for IE9 and lower -->
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=IE6" /><!-- this is for IE9 and lower, passes Edge to others -->


  1. Installation can be done without Administrative rights on the Windows OS.
  2. Installation will append the ‘chromeframe’ version to the ‘User-Agent’ HTTP header sent by the browser to allow it to be parsed.


Morfeus scanner

I was scanning my server log files the other day and found that this old “bot” is still making the rounds. It help’s to shut the door on this with some configuration. It’s specifically looking for PHP vulnerabilities and is easily identified by the expletive in it’s User-Agent HTTP request headers.