Skip to content

Commit d557113

Browse files
authored
fix(fetch): send cookies set with Path back to the exact path (#1861)
A cookie stored with an explicit Path was only sent to paths below it, never to the path itself, because the match compared the directory part of the request path. The check now follows RFC 6265 section 5.1.4: identical paths match, and otherwise the cookie path has to be a directory prefix of the request path. That also closes the other half of the same bug, where a sibling path such as /loginX/y matched a cookie scoped to /login.
1 parent 085f525 commit d557113

2 files changed

Lines changed: 24 additions & 3 deletions

File tree

‎src/fetch/cookies.ts‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,14 @@ export default class Cookies {
213213
return false;
214214
}
215215

216-
// check if path matches
217-
const path = this.getPath(urlparts.pathname);
218-
if (path.substr(0, (cookie.path as string).length) !== cookie.path) {
216+
// check if the request path path-matches the cookie path (RFC 6265 section 5.1.4):
217+
// identical paths match, otherwise the cookie path must be a directory prefix
218+
const pathname = urlparts.pathname || '/';
219+
const cookiePath = cookie.path as string;
220+
if (
221+
pathname !== cookiePath &&
222+
!(pathname.startsWith(cookiePath) && (cookiePath.endsWith('/') || pathname.charAt(cookiePath.length) === '/'))
223+
) {
219224
return false;
220225
}
221226

‎test/fetch/cookies-test.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,22 @@ describe('Cookie Tests', () => {
291291
assert.strictEqual(biskviit.match(cookie, 'https://example.com/def/'), true);
292292
assert.strictEqual(biskviit.match(cookie, 'http://example.com/def/'), false);
293293
});
294+
295+
it('should match a cookie on the exact request path (RFC 6265 section 5.1.4)', () => {
296+
let cookie = {
297+
name: 'zzz',
298+
value: 'abc',
299+
path: '/def',
300+
expires: new Date(Date.now() + 10000),
301+
domain: 'example.com',
302+
secure: false,
303+
httponly: false
304+
};
305+
assert.strictEqual(biskviit.match(cookie, 'http://example.com/def'), true);
306+
assert.strictEqual(biskviit.match(cookie, 'http://example.com/def/'), true);
307+
assert.strictEqual(biskviit.match(cookie, 'http://example.com/def/ghi'), true);
308+
assert.strictEqual(biskviit.match(cookie, 'http://example.com/defghi'), false);
309+
});
294310
});
295311

296312
describe('#parse', () => {

0 commit comments

Comments
 (0)