/ open source

Sessions not set SameSite cookie Firefox vs Chome iframe

This matter comes into play when you are embedding an iframe into your application (e.g. maybe your application is a SasS or you have a single sign on scenario), and you need to allow the embedded iframe to set cookies.

tldr: https://twitter.com/rowan_m/status/1279013752520740865

I was working on a single sign on application exhibiting the following behaviour:

On Firefox, in the embedded iframe, cookies were being set (in this case it was a PHP application with PHPSESSID being set, but these were not being set in Chrome). In this case the single sign on application was failing.

This was due to the differences in security policy of cookies with / without the SameSite attribute set.

Ultimately, in our security context (yours might be different), the flag needed was "SameSite=None" on our session cookie. This allowed the iframe to load, and create a session cookie in Chrome as well as Firefox.

At the time of writing the version of Firefox was 81.0, and the Chrome was version 85.0.4183.102.

Finer details SameSie Cookie within iframes:

The "SameSite=None; Secure" cookie flag was needed.

On recent version of Firefox the feature is behind a flag (about:config) "network.cookie.sameSite.laxByDefault" disabled by default.
If you want Firefix to behave the same as Chrome, then enable network.cookie.sameSite.laxByDefault by setting it to true.

But on Chrome they've already made laxByDefault the default, which means the default security stance is stricter. As long as I'm understanding correctly, I found this difference in default security surprising given Firefox is tooted as privacy first (but it's also not fair when consider the development capacity of Google compared to Mozilla).

How we resolved it

In modern languages it may be more trivial to edit session cookies at the application layer however this was a legacy php application, which has since been dockerised. Rather than refactor the application to use PHP's session_set_save_handler and create a custom session handler, we put an apache container in proxy mode in-front of the php application. Here is an excerpt:

version: "3.3"
services:
  php:
    build: ./docker-images/php/
    volumes:
      - "./app:/var/www/html"
    env_file:
      - ".env"

  db:
    image: mysql:5.6.49
    volumes:
      - db-data:/var/lib/mysql/data
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    env_file:
      - ".env"
  apache:
    build: ./docker-images/apache
    ports:
      - "8082:80"
volumes:
  db-data:

To configure apache in proxy mode we applied the following configuration:

# Proxy to php container
ProxyPass "/" "http://php/"
ProxyPassReverse "/" "http://php/"

To add the SameSite cookie flag, rather crudely, we use the header module available in apache:

# Enforce cookie samesite policy
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=None

A helpful resource for building the apache docker container in proxy mode is the README on the docker image which points out first copy the default apache config out of the apache image version you're using:

docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > my-httpd.conf

Edit it , e.g by enabling the proxy modules and use the header edit module.

LoadModule headers_module modules/mod_headers.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_module modules/mod_proxy.so

Then copy config into your own docker image:

FROM httpd:2.4
COPY ./my-httpd.conf /usr/local/apache2/conf/httpd.conf

Extra reading:

(https://blog.heroku.com/chrome-changes-samesite-cookie )
(https://web.dev/samesite-cookie-recipes/)
https://stackoverflow.com/questions/63171554/samesite-none-not-working-on-chrome-incognito

Please note Chrome incognito mode still blocks SameSite=None third party cookies which makes development a little trickier (but you can change this https://stackoverflow.com/questions/63171554/samesite-none-not-working-on-chrome-incognito)