Socket
Socket
Sign inDemoInstall

should-send-same-site-none

Package Overview
Dependencies
0
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.1 to 2.0.0

30

index.js

@@ -10,3 +10,3 @@ function intToString(intValue) {

// Don’t send `SameSite=None` to known incompatible clients.
function shouldSendSameSiteNone(useragent) {
function isSameSiteNoneCompactible(useragent) {
return !isSameSiteNoneIncompatible(useragent);

@@ -115,2 +115,28 @@ }

module.exports = shouldSendSameSiteNone;
var shouldSendSameSiteNone = function(req, res, next) {
var end = res.end;
res.end = function() {
var ua = req.get("user-agent");
var isCompatible = isSameSiteNoneCompactible(ua);
var cookies = res.get("Set-Cookie");
var removeSameSiteNone = function(str) {
return str.replace(/ SameSite=None;?/g, "");
};
if (!isCompatible && cookies) {
if (Array.isArray(cookies)) {
cookies = cookies.map(removeSameSiteNone);
} else {
cookies = removeSameSiteNone(cookies);
}
res.set("Set-Cookie", cookies);
}
end.apply(this, arguments);
};
next();
};
module.exports = {
shouldSendSameSiteNone: shouldSendSameSiteNone,
isSameSiteNoneCompactible: isSameSiteNoneCompactible
};

@@ -1,2 +0,8 @@

const shouldSendSameSiteNone = require("./index");
const express = require("express");
const supertest = require("supertest");
var http = require("http");
const {
isSameSiteNoneCompactible,
shouldSendSameSiteNone
} = require("./index");

@@ -76,16 +82,156 @@ const negativeTestCases = {

for (const i in positiveTestCases) {
if (positiveTestCases.hasOwnProperty(i)) {
test(`Test ${i} (true)`, () => {
expect(shouldSendSameSiteNone(positiveTestCases[i])).toBe(true);
describe("isSameSiteNoneCompactible", () => {
for (const i in positiveTestCases) {
if (positiveTestCases.hasOwnProperty(i)) {
it(`Test ${i} (true)`, () => {
expect(isSameSiteNoneCompactible(positiveTestCases[i])).toBe(true);
});
}
}
for (const i in negativeTestCases) {
if (negativeTestCases.hasOwnProperty(i)) {
it(`Test ${i} (false)`, () => {
expect(isSameSiteNoneCompactible(negativeTestCases[i])).toBe(false);
});
}
}
});
describe("shouldSendSameSiteNone with mutiple cookies", () => {
let app, server;
beforeEach(done => {
app = new express();
app.use(shouldSendSameSiteNone);
app.get("/", (req, res, next) => {
res.cookie("foo", "bar", { sameSite: "none" });
res.cookie("koo", "mar", { sameSite: "none" });
res.send("ok");
});
server = http.createServer(app);
server.listen(done);
});
afterEach(done => {
server.close(done);
});
for (const i in negativeTestCases) {
if (negativeTestCases.hasOwnProperty(i)) {
it(`Remove SameSite=None attributes in ${i}`, async done => {
const response = await supertest(app)
.get("/")
.set("User-Agent", negativeTestCases[i]);
const expected = ["foo=bar; Path=/;,koo=mar; Path=/;"];
expect(response.header["set-cookie"]).toEqual(expected);
expect(response.text).toEqual("ok");
done();
});
}
}
}
for (const i in negativeTestCases) {
if (negativeTestCases.hasOwnProperty(i)) {
test(`Test ${i} (false)`, () => {
expect(shouldSendSameSiteNone(negativeTestCases[i])).toBe(false);
for (const i in positiveTestCases) {
if (positiveTestCases.hasOwnProperty(i)) {
it(`Keep SameSite=None attributes in ${i}`, async done => {
const response = await supertest(app)
.get("/")
.set("User-Agent", positiveTestCases[i]);
const expected = [
"foo=bar; Path=/; SameSite=None,koo=mar; Path=/; SameSite=None"
];
expect(response.header["set-cookie"]).toEqual(expected);
expect(response.text).toEqual("ok");
done();
});
}
}
});
describe("shouldSendSameSiteNone with single cookies", () => {
let app, server;
beforeEach(done => {
app = new express();
app.use(shouldSendSameSiteNone);
app.get("/", (req, res, next) => {
res.cookie("foo", "bar", { sameSite: "none" });
res.send("ok");
});
server = http.createServer(app);
server.listen(done);
});
afterEach(done => {
server.close(done);
});
for (const i in negativeTestCases) {
if (negativeTestCases.hasOwnProperty(i)) {
it(`Remove SameSite=None attributes in ${i}`, async done => {
const response = await supertest(app)
.get("/")
.set("User-Agent", negativeTestCases[i]);
const expected = ["foo=bar; Path=/;"];
expect(response.header["set-cookie"]).toEqual(expected);
expect(response.text).toEqual("ok");
done();
});
}
}
}
for (const i in positiveTestCases) {
if (positiveTestCases.hasOwnProperty(i)) {
it(`Keep SameSite=None attributes in ${i}`, async done => {
const response = await supertest(app)
.get("/")
.set("User-Agent", positiveTestCases[i]);
const expected = ["foo=bar; Path=/; SameSite=None"];
expect(response.header["set-cookie"]).toEqual(expected);
expect(response.text).toEqual("ok");
done();
});
}
}
});
describe("shouldSendSameSiteNone with no cookies", () => {
let app, server;
beforeEach(done => {
app = new express();
app.use(shouldSendSameSiteNone);
app.get("/", (req, res, next) => {
res.send("ok");
});
server = http.createServer(app);
server.listen(done);
});
afterEach(done => {
server.close(done);
});
for (const i in negativeTestCases) {
if (negativeTestCases.hasOwnProperty(i)) {
it(`Remove SameSite=None attributes in ${i}`, async done => {
const response = await supertest(app)
.get("/")
.set("User-Agent", negativeTestCases[i]);
expect(response.header["set-cookie"]).toEqual(undefined);
expect(response.text).toEqual("ok");
done();
});
}
}
for (const i in positiveTestCases) {
if (positiveTestCases.hasOwnProperty(i)) {
it(`Keep SameSite=None attributes in ${i}`, async done => {
const response = await supertest(app)
.get("/")
.set("User-Agent", positiveTestCases[i]);
expect(response.header["set-cookie"]).toEqual(undefined);
expect(response.text).toEqual("ok");
done();
});
}
}
});

8

package.json
{
"name": "should-send-same-site-none",
"version": "1.0.1",
"version": "2.0.0",
"description": "A simple utility to detect incompatible user agents for `SameSite=None` cookie attribute",
"main": "index.js",
"scripts": {
"test": "jest"
"test": "jest --detectOpenHandles"
},

@@ -16,4 +16,6 @@ "repository": {

"devDependencies": {
"jest": "^24.9.0"
"express": "^4.17.1",
"jest": "^24.9.0",
"supertest": "^4.0.2"
}
}
# should-send-same-site-none
This is a small utility function for detecting incompatible user agents (browsers) for the `SameSite=None` cookie attribute.
The module comes with:
With Chrome 80 in February 2020, [Chrome will treat cookies that have no declared SameSite value as `SameSite=Lax` cookies](https://blog.chromium.org/2019/10/developers-get-ready-for-new.html). Other browser vendors are expected to follow Google’s lead.
- A small **utility function** `isSameSiteNoneCompactible` for detecting incompatible user agents (browsers) for the `SameSite=None` cookie attribute.
Some browsers, including some versions of Chrome, Safari and UC Browser, might handle the None value in unintended ways, requiring developers to code exceptions for those clients.
- A **Express middleware** `shouldSendSameSiteNone` for automatically removing `SameSite=None` from response header when reqesting client is incompatible with `SameSite=None`.
## Background
`shouldSendSameSiteNone` utility function detect incompatible user agents based on the [list of known incompatible clients](https://www.chromium.org/updates/same-site/incompatible-clients) and returns `true` if the given user-agent string is compatible with `SameSite=None` cookie attribute.
With Chrome 80 in February 2020, Chrome will treat cookies that have no declared SameSite value as `SameSite=Lax` cookies. Other browser vendors are expected to follow Google’s lead. (See this [Blog Post](https://blog.chromium.org/2019/10/developers-get-ready-for-new.html)).
If you manage cross-site cookies, you will need to apply the SameSite=None; Secure setting to those cookies. However, some browsers, including some versions of Chrome, Safari and UC Browser, might handle the None value in unintended ways, requiring developers to code exceptions for those clients.
`isSameSiteNoneCompactible` utility function detects incompatible user agents based on a [list of known incompatible clients](https://www.chromium.org/updates/same-site/incompatible-clients) and returns `true` if the given user-agent string is compatible with `SameSite=None` cookie attribute.
For Express.js, `shouldSendSameSiteNone` middleware automatically removes `SameSite=None` from set-cookie response header when the reqesting client is incompatible with `SameSite=None`.
## Usage
#### Function: `isSameSiteNoneCompactible`
```
var shouldSendSameSiteNone = require('should-send-same-site-none');
// import shouldSendSameSiteNone from 'should-send-same-site-none';
var ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) AppleWebKit/537.36 (KHTML, like Gecko)';
import { isSameSiteNoneCompactible } from 'should-send-same-site-none';
const ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) ....';
if (shouldSendSameSiteNone(ua)) {

@@ -28,3 +36,20 @@ console.log("Yes, the browser is compatible and we can set SameSite=None cookies");

#### Middleware: `shouldSendSameSiteNone`
```
const express = require('express');
const { shouldSendSameSiteNone } = require('should-send-same-site-none');
const app = express();
app.use(shouldSendSameSiteNone); // Apply middle ware before routes
app.get('/', function (req, res) {
res.send('hello world');
});
app.listen(3000);
```
## Running tests

@@ -84,3 +109,2 @@

Compatibilities of the following clients are unclear:

@@ -91,5 +115,2 @@

Please file an issue if additional incompatible clients are identified.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚑️ by Socket Inc