Skip to content

Commit 6ac440d

Browse files
Prevent XSS in the cookie attributes
Closes js-cookiegh-400.
1 parent e7a476b commit 6ac440d

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,9 @@ Cookies.remove('name', { path: '' });
203203
204204
(From [Internet Explorer Cookie Internals (FAQ)](http://blogs.msdn.com/b/ieinternals/archive/2009/08/20/wininet-ie-cookie-internals-faq.aspx))
205205

206-
This means one cannot set a path using `path: window.location.pathname` in case such pathname contains a filename like so: `/check.html` (or at least, such cookie cannot be read correctly).
206+
This means one cannot set a path using `window.location.pathname` in case such pathname contains a filename like so: `/check.html` (or at least, such cookie cannot be read correctly).
207+
208+
In fact, you should never allow untrusted input to set the cookie attributes or you might be exposed to a [XSS attack](https://github.com/js-cookie/js-cookie/issues/396).
207209

208210
### domain
209211

src/js.cookie.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,15 @@
8787
if (attributes[attributeName] === true) {
8888
continue;
8989
}
90-
stringifiedAttributes += '=' + attributes[attributeName];
90+
91+
// Considers RFC 6265 section 5.2:
92+
// ...
93+
// 3. If the remaining unparsed-attributes contains a %x3B (";")
94+
// character:
95+
// Consume the characters of the unparsed-attributes up to,
96+
// not including, the first %x3B (";") character.
97+
// ...
98+
stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];
9199
}
92100
return (document.cookie = key + '=' + value + stringifiedAttributes);
93101
}

test/tests.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,16 @@ QUnit.test('undefined attribute value', function (assert) {
294294
}), 'c=v; path=/', 'should not write undefined unofficial attribute');
295295
});
296296

297+
// github.com/js-cookie/js-cookie/issues/396
298+
QUnit.test('sanitization of attributes to prevent XSS from untrusted input', function (assert) {
299+
assert.expect(1);
300+
assert.strictEqual(Cookies.set('c', 'v', {
301+
path: '/;domain=sub.domain.com',
302+
domain: 'site.com;remove_this',
303+
customAttribute: 'value;;remove_this'
304+
}), 'c=v; path=/; domain=site.com; customAttribute=value', 'should not allow semicolon in a cookie attribute');
305+
});
306+
297307
QUnit.module('remove', lifecycle);
298308

299309
QUnit.test('deletion', function (assert) {

0 commit comments

Comments
 (0)