diff --git a/CHANGELOG.md b/CHANGELOG.md index 2955e66..4779dbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,13 @@ # Changelog +## [1.3.0] - 2019-05-02 +### Added +- Security for set-cookie header to prevent dangerous response caching with credentials. -## [1.2.2] - 2017-04-13 +## [1.2.2] - 2019-04-13 ### Fixed - Cache leak for memory plugin - -## [1.2.1] - 2017-04-13 +## [1.2.1] - 2019-04-13 ### Fixed - Added getting Enum values from string implementing cache strategy diff --git a/README.md b/README.md index afe4549..0403e6e 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ Warden is an outgoing request optimizer for creating fast and scalable applicati ![npm](https://img.shields.io/npm/dt/puzzle-warden.svg) ![npm](https://img.shields.io/npm/v/puzzle-warden.svg) [![Known Vulnerabilities](https://snyk.io/test/github/puzzle-js/puzzle-warden/badge.svg)](https://snyk.io/test/github/puzzle-js/puzzle-warden) -[![codecov](https://codecov.io/gh/puzzle-js/puzzle-warden/branch/master/graph/badge.svg)](https://codecov.io/gh/puzzle-js/puzzle-warden) +[![codecov](https://codecov.io/gh/puzzle-js/puzzle-warden/branch/master/graph/badge.svg)](https://codecov.io/gh/puzzle-js/puzzle-warden) +[![Codacy](https://api.codacy.com/project/badge/Grade/e806d72373414fd9818ab2a403f1b36d)](https://www.codacy.com/app/Acanguven/puzzle-warden?utm_source=github.com&utm_medium=referral&utm_content=puzzle-js/puzzle-warden&utm_campaign=Badge_Grade) ## Features - 📥 **Smart Caching** Caches requests by converting HTTP requests to smart key strings. ✅ diff --git a/package.json b/package.json index 3171b78..a776a84 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "puzzle-warden", - "version": "1.2.7", + "version": "1.3.0", "main": "dist/index.js", "types": "dist/index.d.ts", "license": "MIT", "scripts": { - "test": "jest --coverage", + "test": "jest --coverage --silent", "build": "rm -rf dist && ./node_modules/.bin/tsc", "test:watch": "jest --coverage --watch", "lint": "tslint -c tslint.json 'src/**/*.ts'" diff --git a/src/cache-then-network.ts b/src/cache-then-network.ts index 5233da6..7ef6ee5 100644 --- a/src/cache-then-network.ts +++ b/src/cache-then-network.ts @@ -18,7 +18,11 @@ class CacheThenNetwork extends WardenStream { async onResponse(chunk: ResponseChunk, callback: TransformCallback): Promise { if (!chunk.cacheHit && !chunk.error && chunk.response) { - await this.storage.set(chunk.key, chunk.response, this.ms); + if(chunk.response.headers["set-cookie"]){ + console.warn('Detected dangerous response with set-cookie header, not caching', chunk.key); + }else{ + await this.storage.set(chunk.key, chunk.response, this.ms); + } } callback(undefined, chunk); diff --git a/test/cache-then-network.spec.ts b/test/cache-then-network.spec.ts index bf15c66..de12c5b 100644 --- a/test/cache-then-network.spec.ts +++ b/test/cache-then-network.spec.ts @@ -30,7 +30,7 @@ describe("[cache.ts]", () => { expect(cache).to.be.instanceOf(CacheThenNetwork); }); - it("should pass the request to the next chain if cache is invalid", async () => { + it("should pass the request to the next chain if cache is invalid", async () => { // Arrange const ms = undefined; const cache = new CacheThenNetwork(memory, ms); @@ -105,7 +105,8 @@ describe("[cache.ts]", () => { const chunk: any = { key: faker.random.word(), response: { - body: faker.random.word() + body: faker.random.word(), + headers: {} }, cacheHit: false }; @@ -118,4 +119,27 @@ describe("[cache.ts]", () => { // Assert expect(spy.calledWithExactly(undefined, chunk)).to.eq(true); }); + + it("should handle incoming response without caching because of set-cookie", async () => { + // Arrange + const ms = faker.random.number(); + const cache = new CacheThenNetwork(memory, ms); + const chunk: any = { + key: faker.random.word(), + response: { + body: faker.random.word(), + headers: { + 'set-cookie': 'foo=bar' + } + }, + cacheHit: false + }; + const spy = sandbox.stub(); + + // Act + await cache.onResponse(chunk, spy); + + // Assert + expect(spy.calledWithExactly(undefined, chunk)).to.eq(true); + }); });