Skip to content

Commit

Permalink
feat: add secure cookie override to agent (#1515)
Browse files Browse the repository at this point in the history
  • Loading branch information
ejose19 authored and niftylettuce committed Jan 7, 2020
1 parent 64b4dac commit 737697f
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/agent-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ function Agent() {
'key',
'pfx',
'cert',
'disableTLSCerts'
'disableTLSCerts',
'sendSecureCookie'
].forEach(fn => {
// Default setting for all requests from this agent
Agent.prototype[fn] = function(...args) {
Expand Down
9 changes: 8 additions & 1 deletion src/node/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ function Agent(options) {
if (options.rejectUnauthorized === false) {
this.disableTLSCerts();
}

if (options.sendSecureCookie) {
this.sendSecureCookie();
}
}
}

Expand All @@ -76,11 +80,14 @@ Agent.prototype._saveCookies = function(res) {
*/

Agent.prototype._attachCookies = function(req) {
const sendSecureCookie = Boolean(
this._defaults.find(current => current.fn === 'sendSecureCookie')
);
const url = parse(req.url);
const access = new CookieAccessInfo(
url.hostname,
url.pathname,
url.protocol === 'https:'
url.protocol === 'https:' || sendSecureCookie
);
const cookies = this.jar.getCookies(access).toValueString();
req.cookies = cookies;
Expand Down
13 changes: 13 additions & 0 deletions src/node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,19 @@ Request.prototype.disableTLSCerts = function() {
return this;
};

/**
* Sends secure cookies on http and https requests
* Be warned this allows cookie hijacking
*
* @return {Request} for chaining
* @api public
*/

Request.prototype.sendSecureCookie = function() {
this._sendSecureCookie = true;
return this;
};

/**
* Return an http[s] request.
*
Expand Down
82 changes: 82 additions & 0 deletions test/node/secure-cookie.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const request = require('../support/client');
const express = require('express');
const cookieParser = require('cookie-parser');
const http = require('http');

const app = express();

app.use(cookieParser());

app.get('/', (req, res) => {
const cookie = req.header('cookie');
if (cookie === undefined) {
res.cookie('test', 1, { maxAge: 900000, httpOnly: true, secure: true });
res.send('cookie set');
} else {
res.send('cookie sent');
}
});

let base = 'http://localhost';
let server;
before(function listen(done) {
server = http.createServer(app);
server = server.listen(0, function listening() {
base += `:${server.address().port}`;
done();
});
});

const agent1 = request.agent();
const agent2 = request.agent({ sendSecureCookie: true });
const agent3 = request.agent();

describe('Secure cookie', () => {
it('Should receive a secure cookie', () => {
agent1.get(`${base}/`).then(res => {
res.should.have.status(200);
should.exist(res.headers['set-cookie']);
res.headers['set-cookie'][0].should.containEql('Secure');
res.text.should.containEql('cookie set');
});

agent2.get(`${base}/`).then(res => {
res.should.have.status(200);
should.exist(res.headers['set-cookie']);
res.headers['set-cookie'][0].should.containEql('Secure');
res.text.should.containEql('cookie set');
});

agent3.get(`${base}/`).then(res => {
res.should.have.status(200);
should.exist(res.headers['set-cookie']);
res.headers['set-cookie'][0].should.containEql('Secure');
res.text.should.containEql('cookie set');
});
});

it('Should send secure cookie on configured agents', () => {
agent1
.sendSecureCookie()
.get(`${base}/`)
.then(res => {
res.should.have.status(200);
should.not.exist(res.headers['set-cookie']);
res.text.should.containEql('cookie sent');
});

agent2.get(`${base}/`).then(res => {
res.should.have.status(200);
should.not.exist(res.headers['set-cookie']);
res.text.should.containEql('cookie sent');
});
});

it('Should not send secure cookie on default agent', () => {
agent3.get(`${base}/`).then(res => {
res.should.have.status(200);
should.exist(res.headers['set-cookie']);
res.text.should.containEql('cookie set');
});
});
});

0 comments on commit 737697f

Please sign in to comment.