Skip to content

Commit

Permalink
PP-13011 add SameSite Lax to cookies
Browse files Browse the repository at this point in the history
Implements `[RFC] SameSite attribute for cookies`

add SameSite=Lax to:
- session
- govuk_pay_cookie_policy
- seen_cookie_message
- govuk_pay_notifications
  • Loading branch information
SandorArpa committed Sep 13, 2024
1 parent 07c9d42 commit 8f38a19
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 14 deletions.
2 changes: 1 addition & 1 deletion app/assets/js/components/notification-banner.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
e.preventDefault()

document.cookie = 'govuk_pay_notifications={"new_contract_terms_banner_dismissed":true}'
+ ';max-age=' + SIX_MONTHS_IN_SECS
+ ';max-age=' + SIX_MONTHS_IN_SECS + ';SameSite=Lax'
runAnalytics()
removeBanner()
}
Expand Down
7 changes: 4 additions & 3 deletions app/browsered/cookie-functions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict'

const DEFAULT_COOKIE_CONSENT = {
analytics: false
analytics: false,
SameSite: 'Lax'
}

const COOKIE_CATEGORIES = {
Expand Down Expand Up @@ -98,7 +99,7 @@ function setConsentCookie (options) {

if (Cookie(cookie)) {
document.cookie = cookie + '=;expires=' + new Date() + ';domain=' +
getCookieDomain() + ';path=/'
getCookieDomain() + ';path=/' + ';SameSite=Lax'
}
}
}
Expand Down Expand Up @@ -155,7 +156,7 @@ function setCookie (name, value, options) {
if (typeof options === 'undefined') {
options = {}
}
var cookieString = name + '=' + value + '; path=/; domain=' + getCookieDomain()
var cookieString = name + '=' + value + '; path=/; domain=' + getCookieDomain() + '; SameSite=Lax'
if (options.days) {
var date = new Date()
date.setTime(date.getTime() + (options.days * 24 * 60 * 60 * 1000))
Expand Down
6 changes: 4 additions & 2 deletions app/utils/cookie.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ function sessionCookie () {
cookie: {
ephemeral: false, // when true, cookie expires when the browser closes
httpOnly: true, // when true, cookie is not accessible from javascript
secureProxy: !DISABLE_INTERNAL_HTTPS
secureProxy: !DISABLE_INTERNAL_HTTPS,
SameSite: 'Lax'
}
})
}
Expand All @@ -41,7 +42,8 @@ function registrationCookie () {
cookie: {
ephemeral: false, // when true, cookie expires when the browser closes
httpOnly: true, // when true, cookie is not accessible from javascript
secureProxy: !DISABLE_INTERNAL_HTTPS // when true, cookie will only be sent over SSL. use key 'secureProxy' instead if you handle SSL not in your node process
secureProxy: !DISABLE_INTERNAL_HTTPS, // when true, cookie will only be sent over SSL. use key 'secureProxy' instead if you handle SSL not in your node process
SameSite: 'Lax'
}
})
}
Expand Down
12 changes: 6 additions & 6 deletions test/unit/browsered/cookie-banner.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,23 @@ describe('Cookie banner', () => {
analyticsTrackingId = 'test-id'
cookieBannerObject.setCookieConsent(true)

expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":true}')
expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":true,"SameSite":"Lax"}')
expect(document.body.innerHTML).to.contain('You’ve accepted analytics cookies.')

expect(analyticsInit.calledOnce).to.be.true
})
it('should not initialise analytics if consented and analyticsTrackingId is not configured ', () => {
cookieBannerObject.setCookieConsent(true)

expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":true}')
expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":true,"SameSite":"Lax"}')
expect(document.body.innerHTML).to.contain('You’ve accepted analytics cookies.')
expect(analyticsInit.calledOnce).to.be.false
})

it('should not initialise analytics if not consented ', () => {
cookieBannerObject.setCookieConsent(false)

expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":false}')
expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":false,"SameSite":"Lax"}')
expect(document.body.innerHTML).to.contain('You told us not to use analytics cookies.')

expect(analyticsInit.calledOnce).to.be.false
Expand All @@ -71,7 +71,7 @@ describe('Cookie banner', () => {

cookieBannerObject = cookieBanner.initCookieBanner()

expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":true}')
expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":true,"SameSite":"Lax"}')
expect(cookieBannerObject.$module.style.display).to.be.equal('none')

expect(analyticsInit.calledOnce).to.be.true
Expand All @@ -83,7 +83,7 @@ describe('Cookie banner', () => {

cookieBannerObject = cookieBanner.initCookieBanner()

expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":false}')
expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":false,"SameSite":"Lax"}')
expect(cookieBannerObject.$module.style.display).to.be.equal('none')

expect(analyticsInit.notCalled).to.be.true
Expand All @@ -96,7 +96,7 @@ describe('Cookie banner', () => {

cookieBannerObject = cookieBanner.initCookieBanner()

expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":true}')
expect(document.cookie).equals('govuk_pay_cookie_policy={"analytics":true,"SameSite":"Lax"}')
expect(cookieBannerObject.$module.style.display).to.be.equal('none')

expect(analyticsInit.notCalled).to.be.true
Expand Down
14 changes: 12 additions & 2 deletions test/unit/browsered/cookie-functions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,22 @@ describe('Cookie functions', () => {
})
describe('setCookieConsent', () => {
it('should set consent cookie correctly', () => {
cookieFunctions.setConsentCookie({ 'analytics': true })
cookieFunctions.setConsentCookie({ 'analytics': true, 'SameSite': 'Lax' })
let analyticsCookie = JSON.parse(cookieFunctions.getCookie('govuk_pay_cookie_policy'))
expect(analyticsCookie.analytics).to.be.equal(true)
expect(analyticsCookie.SameSite).to.be.equal('Lax')
})

it('should update existing analytics and delete analytics cookies if not consented', () => {
document.cookie = 'govuk_pay_cookie_policy={"analytics":true};domain=.example.org'
document.cookie = '_ga=ga1;domain=.example.org'
document.cookie = '_gid=gid1;domain=.example.org'
document.cookie = '_gat_govuk_shared=shared;domain=.example.org'
cookieFunctions.setConsentCookie({ 'analytics': false })
cookieFunctions.setConsentCookie({ 'analytics': false, 'SameSite': 'Lax' })

let analyticsCookie = JSON.parse(cookieFunctions.getCookie('govuk_pay_cookie_policy'))
expect(analyticsCookie.analytics).to.be.equal(false)
expect(analyticsCookie.SameSite).to.be.equal('Lax')
expect(cookieFunctions.getCookie('_ga')).to.be.equal(null)
expect(cookieFunctions.getCookie('_gid')).to.be.equal(null)
expect(cookieFunctions.getCookie('_gat_govuk_shared')).to.be.equal(null)
Expand Down Expand Up @@ -74,6 +76,14 @@ describe('Cookie functions', () => {
expect(expiryDate.getTime()).to.be.greaterThan(previousDateToTargetExpiryDate.getTime())
expect(expiryDate.getTime()).to.be.lessThan(nextDateToTargetExpiryDate.getTime())
})

it('should set SameSite on the cookie', () => {
const cookieExpiryDays = 10
const cookieString = cookieFunctions.setCookie('govuk_pay_cookie_policy',
'{"analytics":false}', { days: cookieExpiryDays })

expect(cookieString).to.contain('SameSite=Lax')
})
})

function addDaysToDate (cookieExpiryDays) {
Expand Down

0 comments on commit 8f38a19

Please sign in to comment.