@contrast/protect 1.53.1 → 1.54.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/package.json +15 -12
  2. package/lib/error-handlers/common-handler.test.js +0 -52
  3. package/lib/error-handlers/index.test.js +0 -32
  4. package/lib/error-handlers/init-domain.test.js +0 -22
  5. package/lib/error-handlers/install/express.test.js +0 -290
  6. package/lib/error-handlers/install/fastify.test.js +0 -130
  7. package/lib/error-handlers/install/hapi.test.js +0 -102
  8. package/lib/error-handlers/install/koa2.test.js +0 -83
  9. package/lib/error-handlers/install/restify.test.js +0 -57
  10. package/lib/get-source-context.test.js +0 -35
  11. package/lib/hardening/handlers.test.js +0 -89
  12. package/lib/hardening/index.test.js +0 -31
  13. package/lib/hardening/install/node-serialize0.test.js +0 -58
  14. package/lib/index.test.js +0 -53
  15. package/lib/input-analysis/handlers.test.js +0 -1604
  16. package/lib/input-analysis/index.test.js +0 -45
  17. package/lib/input-analysis/install/body-parser1.test.js +0 -134
  18. package/lib/input-analysis/install/busboy1.test.js +0 -81
  19. package/lib/input-analysis/install/cookie-parser1.test.js +0 -144
  20. package/lib/input-analysis/install/express.test.js +0 -241
  21. package/lib/input-analysis/install/fastify.test.js +0 -96
  22. package/lib/input-analysis/install/formidable1.test.js +0 -114
  23. package/lib/input-analysis/install/hapi.test.js +0 -292
  24. package/lib/input-analysis/install/http.test.js +0 -270
  25. package/lib/input-analysis/install/koa-body5.test.js +0 -92
  26. package/lib/input-analysis/install/koa-bodyparser4.test.js +0 -92
  27. package/lib/input-analysis/install/koa2.test.js +0 -259
  28. package/lib/input-analysis/install/multer1.test.js +0 -209
  29. package/lib/input-analysis/install/qs6.test.js +0 -79
  30. package/lib/input-analysis/install/restify.test.js +0 -98
  31. package/lib/input-analysis/install/universal-cookie4.test.js +0 -70
  32. package/lib/input-analysis/ip-analysis.test.js +0 -71
  33. package/lib/input-analysis/virtual-patches.test.js +0 -106
  34. package/lib/input-tracing/handlers/index.test.js +0 -1236
  35. package/lib/input-tracing/index.test.js +0 -62
  36. package/lib/input-tracing/install/child-process.test.js +0 -133
  37. package/lib/input-tracing/install/eval.test.js +0 -78
  38. package/lib/input-tracing/install/fs.test.js +0 -108
  39. package/lib/input-tracing/install/function.test.js +0 -81
  40. package/lib/input-tracing/install/http.test.js +0 -85
  41. package/lib/input-tracing/install/http2.test.js +0 -83
  42. package/lib/input-tracing/install/marsdb.test.js +0 -126
  43. package/lib/input-tracing/install/mongodb.test.js +0 -280
  44. package/lib/input-tracing/install/mssql.test.js +0 -81
  45. package/lib/input-tracing/install/mysql.test.js +0 -108
  46. package/lib/input-tracing/install/postgres.test.js +0 -117
  47. package/lib/input-tracing/install/sequelize.test.js +0 -78
  48. package/lib/input-tracing/install/spdy.test.js +0 -76
  49. package/lib/input-tracing/install/sqlite3.test.js +0 -88
  50. package/lib/input-tracing/install/vm.test.js +0 -176
  51. package/lib/make-response-blocker.test.js +0 -99
  52. package/lib/make-source-context.test.js +0 -219
  53. package/lib/policy.test.js +0 -446
  54. package/lib/semantic-analysis/handlers.test.js +0 -379
  55. package/lib/semantic-analysis/index.test.js +0 -38
  56. package/lib/semantic-analysis/install/libxmljs.test.js +0 -156
  57. package/lib/semantic-analysis/utils/xml-analysis.test.js +0 -156
  58. package/lib/throw-security-exception.test.js +0 -37
@@ -1,45 +0,0 @@
1
- 'use strict';
2
-
3
- const sinon = require('sinon');
4
- const { expect } = require('chai');
5
- const proxyquire = require('proxyquire');
6
- const mocks = require('@contrast/test/mocks');
7
-
8
- describe('protect input-analysis', function () {
9
- let modulesMock, installStub, core, inputAnalysis;
10
- beforeEach(function () {
11
- installStub = sinon.stub();
12
- modulesMock = (propertyName) => function (core) {
13
- if (propertyName) {
14
- core.protect.inputAnalysis[propertyName] = { install: installStub };
15
- }
16
- };
17
- core = mocks.core();
18
- core.depHooks = mocks.depHooks();
19
- core.protect = mocks.protect();
20
-
21
- inputAnalysis = proxyquire('.', {
22
- './handlers': modulesMock,
23
- './install/http': modulesMock('httpInstrumentation'),
24
- './install/fastify': modulesMock('fastify3Instrumentation'),
25
- './install/koa2': modulesMock('koa2Instrumentation'),
26
- './install/koa-body5': modulesMock('koaBody5Instrumentation'),
27
- './install/koa-bodyparser4': modulesMock('koaBodyparser4Instrumentation'),
28
- './install/express': modulesMock('expressInstrumentation'),
29
- './install/body-parser1': modulesMock('bodyParser1Instrumentation'),
30
- './install/cookie-parser1': modulesMock('cookieParser1Instrumentation'),
31
- './install/formidable1': modulesMock('formidable1Instrumentation'),
32
- './install/multer1': modulesMock('multer1Instrumentation'),
33
- './install/qs6': modulesMock('qs6Instrumentation'),
34
- './install/restify': modulesMock('restifyInstrumentation'),
35
- './install/universal-cookie4': modulesMock('universalCookie4Instrumentation'),
36
- './install/hapi': modulesMock('hapiInstrumentation'),
37
- // Total of 15 modules required - 1 handlers and 14 modules to be installed
38
- });
39
- });
40
-
41
- it('calls the install method on all hooks', function () {
42
- inputAnalysis(core).install();
43
- expect(installStub).to.have.callCount(14);
44
- });
45
- });
@@ -1,134 +0,0 @@
1
- 'use strict';
2
-
3
- const sinon = require('sinon');
4
- const { expect } = require('chai');
5
- const scopes = require('@contrast/scopes');
6
- const mocks = require('@contrast/test/mocks');
7
- const SecurityException = require('../../security-exception');
8
- const secEx = SecurityException.create();
9
- const bodyParserInstr = require('./body-parser1');
10
-
11
- describe('protect input-analysis body-parser v1.x', function () {
12
- let core, inputAnalysis, bodyParserMock, patchedBodyParser, body, nextStub;
13
-
14
-
15
- beforeEach(function () {
16
- core = mocks.core();
17
- core.logger = mocks.logger();
18
- core.scopes = scopes(core);
19
- core.protect = mocks.protect();
20
- require('../../get-source-context')(core);
21
- core.depHooks = mocks.depHooks();
22
-
23
- inputAnalysis = core.protect.inputAnalysis;
24
- body = { parameter: 'parsed' };
25
- const bodyParserFn = (payload) => (req, res, next) => {
26
- if (payload) {
27
- req.body = payload;
28
- }
29
-
30
- next();
31
- };
32
- bodyParserMock = (payload) => bodyParserFn(payload);
33
- nextStub = sinon.stub();
34
-
35
- ['json', 'raw', 'text', 'urlencoded'].forEach((property) => {
36
- bodyParserMock[property] = (payload) => (req, res, next) => {
37
- if (payload) {
38
- req.body = payload;
39
- }
40
- next();
41
- };
42
- });
43
-
44
- bodyParserInstr(core).install();
45
- core.depHooks.resolve.yield(bodyParserMock);
46
- patchedBodyParser = core.depHooks.resolve.yield(bodyParserMock)[0];
47
- });
48
-
49
- it('calls `.handleParsedBody` when parsing is successful and in right context', function () {
50
- core.scopes.sources.run({ protect: {} }, () => {
51
- patchedBodyParser(body)({}, {}, nextStub);
52
- });
53
-
54
- core.scopes.sources.run({ protect: {} }, () => {
55
- patchedBodyParser.json()({ body }, {}, nextStub);
56
- });
57
-
58
- expect(inputAnalysis.handleParsedBody).to.have.been.calledTwice;
59
- expect(inputAnalysis.handleParsedBody).to.have.been.calledWithMatch({ parsedBody: body }, body);
60
- expect(nextStub).to.have.been.calledTwice;
61
- });
62
-
63
- it('calls `.handleParsedBody` when parsing is successful, in right context with the body parsed by JSON.parse when bodyParser.text method is used', function () {
64
-
65
- core.scopes.sources.run({ protect: {} }, () => {
66
- patchedBodyParser.text()({ body: JSON.stringify(body) }, {}, nextStub);
67
- });
68
-
69
- expect(inputAnalysis.handleParsedBody).to.have.been.calledOnceWith({ parsedBody: body }, body);
70
- expect(nextStub).to.have.been.calledOnce;
71
- });
72
-
73
- it('logs an error if parsing the body in case of bodyParser.text throws an error', function () {
74
-
75
- core.scopes.sources.run({ protect: {} }, () => {
76
- patchedBodyParser.text()({ body: 'not-a-valid-JSON' }, {}, nextStub);
77
- });
78
-
79
- expect(core.logger.error).to.have.been.calledOnceWithExactly(sinon.match.any, 'Error parsing with bodyParser.text()');
80
- expect(nextStub).to.have.been.calledOnce;
81
- });
82
-
83
- it('does not call `.handleParsedBody` when not in context', function () {
84
- core.scopes.sources.run({}, () => {
85
- patchedBodyParser(body)({}, {}, nextStub);
86
- });
87
-
88
- core.scopes.sources.run({}, () => {
89
- patchedBodyParser.json()({ body }, {}, nextStub);
90
- });
91
-
92
- expect(inputAnalysis.handleParsedBody).not.to.have.been.called;
93
- expect(nextStub).to.have.been.calledTwice;
94
- });
95
-
96
- it('does not call `.handleParsedBody` when `body-parser` does not return a result', function () {
97
- core.scopes.sources.run({ protect: {} }, () => {
98
- patchedBodyParser(null);
99
- });
100
-
101
- core.scopes.sources.run({ protect: {} }, () => {
102
- patchedBodyParser.json()({}, {}, nextStub);
103
- });
104
-
105
- core.scopes.sources.run({ protect: {} }, () => {
106
- patchedBodyParser.json()({ body: {} }, {}, nextStub);
107
- });
108
-
109
- expect(inputAnalysis.handleParsedBody).not.to.have.been.called;
110
- expect(nextStub).to.have.been.calledTwice;
111
- });
112
-
113
- it('handles a case with SecurityException from `.handleParsedBody`', function () {
114
- inputAnalysis.handleParsedBody.throws(secEx);
115
- core.scopes.sources.run({ protect: {} }, () => {
116
- patchedBodyParser(body)({}, {}, nextStub);
117
- });
118
-
119
- expect(nextStub).to.have.been.calledWith(secEx);
120
- });
121
-
122
- it('handles a case with an error in the input analysis from `.handleParsedBody`', function () {
123
- const err = new Error('Input Analysis Error');
124
-
125
- inputAnalysis.handleParsedBody.throws(err);
126
- core.scopes.sources.run({ protect: {} }, () => {
127
- patchedBodyParser(body)({}, {}, nextStub);
128
- });
129
-
130
- expect(core.logger.error).to.have.been.calledWith({ err }, 'Unexpected error during input analysis');
131
- expect(nextStub).to.have.been.calledOnce;
132
- expect(nextStub).not.to.have.been.calledWith(err);
133
- });
134
- });
@@ -1,81 +0,0 @@
1
- 'use strict';
2
-
3
- const sinon = require('sinon');
4
- const { expect } = require('chai');
5
- const scopes = require('@contrast/scopes');
6
- const patcher = require('@contrast/patcher');
7
- const mocks = require('@contrast/test/mocks');
8
- const busboyInstr = require('./busboy1');
9
-
10
- describe('protect input-analysis busboy v1.x', function () {
11
- let core, inputAnalysis, mockBusboy;
12
-
13
- beforeEach(function () {
14
- core = mocks.core();
15
- core.logger = mocks.logger();
16
- core.scopes = scopes(core);
17
- core.protect = mocks.protect();
18
- require('../../get-source-context')(core);
19
- core.depHooks = mocks.depHooks();
20
- core.patcher = patcher(core);
21
-
22
- inputAnalysis = core.protect.inputAnalysis;
23
-
24
- mockBusboy = function () { };
25
- mockBusboy.prototype.emit = function () { };
26
- sinon.spy(mockBusboy.prototype, 'emit');
27
- sinon.spy(core.patcher, 'patch');
28
-
29
- busboyInstr(core).install();
30
- core.depHooks.resolve.yield(mockBusboy);
31
- core.patcher.patch.resetHistory();
32
- });
33
-
34
- it('calls patcher on the `.emit` method', function () {
35
- core.depHooks.resolve.yield(mockBusboy);
36
-
37
- expect(core.patcher.patch).to.have.been.calledOnce;
38
- expect(core.patcher.patch).to.have.been.calledWithMatch(mockBusboy.prototype, 'emit', {
39
- name: 'busboy.prototype.emit',
40
- patchType: 'protect-input-analysis',
41
- pre: sinon.match.func
42
- });
43
- });
44
-
45
- it('calls `.handleFileUploadName` when there is a multipart file and it is in right context', function () {
46
- core.scopes.sources.run({ protect: {} }, () => {
47
- mockBusboy.prototype.emit('file', null, null, 'filename');
48
- });
49
-
50
- expect(inputAnalysis.handleFileUploadName).to.have.been.calledOnce;
51
- expect(inputAnalysis.handleFileUploadName).to.have.been.calledWithMatch({}, ['filename']);
52
- });
53
-
54
-
55
- it('does not call `.handleFileUploadName` when not in context', function () {
56
- core.scopes.sources.run({}, () => {
57
- mockBusboy.prototype.emit('file', null, null, 'filename');
58
- });
59
-
60
- expect(inputAnalysis.handleFileUploadName).not.to.have.been.called;
61
- });
62
-
63
- it('does not call `.handleFileUploadName` when `.emit` is not called with `file` event', function () {
64
- core.scopes.sources.run({ protect: {} }, () => {
65
- mockBusboy.prototype.emit('not-file', null, null, 'filename');
66
- });
67
-
68
- expect(inputAnalysis.handleParsedBody).not.to.have.been.called;
69
- expect(core.logger.debug).not.to.have.been.called;
70
- });
71
-
72
- it('does not call `.handleFileUploadName` when `.emit` call does not contain a filename', function () {
73
- core.scopes.sources.run({ protect: {} }, () => {
74
- mockBusboy.prototype.emit('not-file');
75
- });
76
-
77
- expect(inputAnalysis.handleParsedBody).not.to.have.been.called;
78
- expect(core.logger.debug).not.to.have.been.called;
79
- });
80
- });
81
-
@@ -1,144 +0,0 @@
1
- 'use strict';
2
-
3
- const sinon = require('sinon');
4
- const { expect } = require('chai');
5
- const scopes = require('@contrast/scopes');
6
- const patcher = require('@contrast/patcher');
7
- const mocks = require('@contrast/test/mocks');
8
- const SecurityException = require('../../security-exception');
9
- const secEx = SecurityException.create();
10
- const cookieParserInstr = require('./cookie-parser1');
11
-
12
- describe('protect input-analysis cookie-parser v1.x', function () {
13
- let core, inputAnalysis, cookieParserMock, patchedCookieParser, cookie, signedCookie, nextStub;
14
-
15
-
16
- beforeEach(function () {
17
- core = mocks.core();
18
- core.logger = mocks.logger();
19
- core.scopes = scopes(core);
20
- core.protect = mocks.protect();
21
- require('../../get-source-context')(core);
22
- core.depHooks = mocks.depHooks();
23
- core.patcher = patcher(core);
24
-
25
- inputAnalysis = core.protect.inputAnalysis;
26
- cookie = {
27
- cookie: { parameter: 'parsed' },
28
- };
29
- signedCookie = {
30
- signedCookie: { secret: 'parsed' }
31
- };
32
- cookieParserMock = (cookies) => (req, res, next) => {
33
- req.cookies = cookies?.cookie;
34
- req.signedCookies = cookies?.signedCookie;
35
- next();
36
- };
37
- nextStub = sinon.stub();
38
- sinon.spy(core.patcher, 'patch');
39
-
40
- cookieParserInstr(core).install();
41
- patchedCookieParser = core.depHooks.resolve.yield(cookieParserMock)[0];
42
- core.patcher.patch.resetHistory();
43
- });
44
-
45
- it('calls patcher on the `cookie-parser` module export', function () {
46
- core.depHooks.resolve.yield(cookieParserMock);
47
-
48
- expect(core.patcher.patch).to.have.been.calledOnce;
49
- expect(core.patcher.patch).to.have.been.calledWithMatch(cookieParserMock, {
50
- name: 'cookie-parser',
51
- patchType: 'protect-input-analysis',
52
- post: sinon.match.func
53
- });
54
- });
55
-
56
- it('calls `.handleCookies` when parsing normal cookies is successful and in right context', function () {
57
- core.scopes.sources.run({ protect: {} }, () => {
58
- const cParser = patchedCookieParser(cookie);
59
- cParser({}, {}, nextStub);
60
- });
61
-
62
- expect(core.patcher.patch).to.have.been.calledOnce;
63
- expect(core.patcher.patch).to.have.been.calledWithMatch(sinon.match.func, {
64
- name: 'cookie-parser',
65
- patchType: 'protect-input-analysis',
66
- pre: sinon.match.func
67
- });
68
-
69
- expect(nextStub).to.have.been.calledOnce;
70
- expect(inputAnalysis.handleCookies).to.have.been.calledOnce;
71
- expect(inputAnalysis.handleCookies).to.have.been.calledWithMatch({ parsedCookies: { ...cookie.cookie } }, { ...cookie.cookie });
72
- });
73
-
74
- it('calls `.handleCookies` when parsing signed cookies is successful and in right context', function () {
75
- core.scopes.sources.run({ protect: {} }, () => {
76
- const cParser = patchedCookieParser(signedCookie);
77
- cParser({}, {}, nextStub);
78
- });
79
-
80
- expect(core.patcher.patch).to.have.been.calledOnce;
81
- expect(core.patcher.patch).to.have.been.calledWithMatch(sinon.match.func, {
82
- name: 'cookie-parser',
83
- patchType: 'protect-input-analysis',
84
- pre: sinon.match.func
85
- });
86
-
87
- expect(nextStub).to.have.been.calledOnce;
88
- expect(inputAnalysis.handleCookies).to.have.been.calledOnce;
89
- expect(inputAnalysis.handleCookies).to.have.been.calledWithMatch({ parsedCookies: { ...signedCookie.signedCookie } }, { ...signedCookie.signedCookie });
90
- });
91
-
92
- it('does not call `.handleCookies` when not in context', function () {
93
- core.scopes.sources.run({}, () => {
94
- const cParser = patchedCookieParser(cookie);
95
- cParser({}, {}, nextStub);
96
- });
97
-
98
- expect(inputAnalysis.handleCookies).not.to.have.been.called;
99
- expect(nextStub).to.have.been.calledOnce;
100
- });
101
-
102
- it('does not call `.handleCookies` when `cookie-parser` does not return a result', function () {
103
- core.scopes.sources.run({ protect: {} }, () => {
104
- const cParser = patchedCookieParser();
105
- cParser({}, {}, nextStub);
106
- });
107
-
108
- core.scopes.sources.run({ protect: {} }, () => {
109
- const cParser = patchedCookieParser({});
110
- cParser({}, {}, nextStub);
111
- });
112
-
113
- expect(inputAnalysis.handleCookies).not.to.have.been.called;
114
- expect(core.logger.debug).not.to.have.been.called;
115
- expect(nextStub).to.have.been.calledTwice;
116
- });
117
-
118
- it('handles a case with SecurityException from `.handleCookies`', function () {
119
- inputAnalysis.handleCookies.throws(secEx);
120
- core.scopes.sources.run({ protect: {} }, () => {
121
- const cParser = patchedCookieParser(cookie);
122
- cParser({}, {}, nextStub);
123
- });
124
-
125
- expect(nextStub).to.have.been.calledOnceWith(secEx);
126
- });
127
-
128
- it('handles a case with an error in the input analysis from `.handleCookies`', function () {
129
- const err = new Error('Input Analysis Error');
130
-
131
- inputAnalysis.handleCookies.throws(err);
132
- core.scopes.sources.run({ protect: {} }, () => {
133
- const cParser = patchedCookieParser(cookie);
134
- cParser({}, {}, nextStub);
135
- });
136
-
137
- expect(core.logger.error).to.have.been.calledWith(
138
- { err, funcKey: 'protect-input-analysis:cookie-parser' },
139
- 'Unexpected error during input analysis'
140
- );
141
- expect(nextStub).to.have.been.calledOnce;
142
- expect(nextStub).not.to.have.been.calledWith(err);
143
- });
144
- });
@@ -1,241 +0,0 @@
1
- 'use strict';
2
-
3
- const sinon = require('sinon');
4
- const { expect } = require('chai');
5
- const scopes = require('@contrast/scopes');
6
- const patcher = require('@contrast/patcher');
7
- const mocks = require('@contrast/test/mocks');
8
- const SecurityException = require('../../security-exception');
9
- const secEx = SecurityException.create();
10
- const expressInstr = require('./express');
11
-
12
- describe('protect input-analysis express', function () {
13
- let core,
14
- inputAnalysis,
15
- expressQueryMock,
16
- requestMock,
17
- nextStub,
18
- query,
19
- Layer;
20
-
21
- beforeEach(function () {
22
- core = mocks.core();
23
- core.logger = mocks.logger();
24
- core.scopes = scopes(core);
25
- core.protect = mocks.protect();
26
- require('../../get-source-context')(core);
27
- core.depHooks = mocks.depHooks();
28
- core.patcher = patcher(core);
29
- sinon.spy(core.patcher, 'patch');
30
-
31
- query = { parameter: 'parsed-query' };
32
- expressQueryMock = (payload) => (req, res, next) => {
33
- req.query = payload;
34
- next();
35
- };
36
-
37
- requestMock = {
38
- get query() {
39
- return { parameter: 'parsed-query' };
40
- }
41
- };
42
-
43
- Layer = sinon.stub();
44
- Layer.prototype.match = sinon.stub().returns(true);
45
-
46
- core.depHooks.resolve.withArgs({ name: 'express', version: '4', file: 'lib/middleware/query.js' }).yields(expressQueryMock);
47
- core.depHooks.resolve.withArgs({ name: 'express', version: '5', file: 'lib/request.js' }).yields(requestMock);
48
-
49
- nextStub = sinon.stub();
50
-
51
- inputAnalysis = core.protect.inputAnalysis;
52
- expressInstr(core).install();
53
- expressQueryMock = core.patcher.patch.getCall(0).returnValue;
54
- core.patcher.patch.resetHistory();
55
- });
56
-
57
- describe('express4 query patch', function () {
58
- it('calls `.handleQueryParams` when parsing is successful and in right context', function () {
59
- core.scopes.sources.run({ protect: {} }, () => {
60
- const queryParser = expressQueryMock(query);
61
- queryParser({}, {}, nextStub);
62
- });
63
-
64
- expect(core.patcher.patch).to.have.been.calledOnce;
65
- expect(core.patcher.patch).to.have.been.calledWithMatch(sinon.match.func, {
66
- name: 'express.query',
67
- patchType: 'protect-input-analysis',
68
- pre: sinon.match.func
69
- });
70
-
71
- expect(nextStub).to.have.been.calledOnce;
72
- expect(inputAnalysis.handleQueryParams).to.have.been.calledOnce;
73
- expect(inputAnalysis.handleQueryParams).to.have.been.calledWithMatch({ parsedQuery: query }, query);
74
- });
75
-
76
- it('does not call `.handleQueryParams` when not in context', function () {
77
- core.scopes.sources.run({}, () => {
78
- const queryParser = expressQueryMock(query);
79
- queryParser({}, {}, nextStub);
80
- });
81
-
82
- expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
83
- expect(nextStub).to.have.been.calledOnce;
84
- });
85
-
86
- it('does not call `.handleQueryParams` when no query is passed to`express.query`', function () {
87
- core.scopes.sources.run({ protect: {} }, () => {
88
- const queryParser = expressQueryMock();
89
- queryParser({}, {}, nextStub);
90
- });
91
-
92
- expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
93
- expect(nextStub).to.have.been.calledOnce;
94
- });
95
-
96
- it('does not call `.handleQueryParams` when query was already parsed', function () {
97
- core.scopes.sources.run({ protect: { parsedQuery: query } }, () => {
98
- const queryParser = expressQueryMock();
99
- queryParser({}, {}, nextStub);
100
- });
101
-
102
- expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
103
- expect(nextStub).to.have.been.calledOnce;
104
- });
105
-
106
- it('handles a case with SecurityException from `.handleQueryParams`', function () {
107
- inputAnalysis.handleQueryParams.throws(secEx);
108
- core.scopes.sources.run({ protect: {} }, () => {
109
- const queryParser = expressQueryMock(query);
110
- queryParser({}, {}, nextStub);
111
- });
112
-
113
- expect(nextStub).to.have.been.calledOnceWith(secEx);
114
- });
115
-
116
- it('handles a case with an error in the input analysis from `.handleQueryParams`', function () {
117
- const err = new Error('Input Analysis Error');
118
-
119
- inputAnalysis.handleQueryParams.throws(err);
120
- core.scopes.sources.run({ protect: {} }, () => {
121
- const queryParser = expressQueryMock(query);
122
- queryParser({}, {}, nextStub);
123
- });
124
-
125
- expect(core.logger.error).to.have.been.calledWith(
126
- { err, funcKey: 'protect-input-analysis:express.query' },
127
- 'Unexpected error during input analysis'
128
- );
129
- expect(nextStub).to.have.been.calledOnce;
130
- expect(nextStub).not.to.have.been.calledWith(err);
131
- });
132
- });
133
-
134
- describe('express5 query get patch', function() {
135
- it('does not call `.handleQueryParams` when not in context', function () {
136
- core.scopes.sources.run({}, () => {
137
- requestMock.query;
138
- });
139
-
140
- expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
141
- });
142
-
143
- it('does not call `.handleQueryParams` when no query exists', function () {
144
- requestMock = {
145
- get query() {
146
- return {};
147
- }
148
- };
149
- core.scopes.sources.run({ protect: {} }, () => {
150
- requestMock.query;
151
- });
152
-
153
- expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
154
- });
155
-
156
- it('does not call `.handleQueryParams` when query was already parsed', function () {
157
- core.scopes.sources.run({ protect: { parsedQuery: query } }, () => {
158
- requestMock.query;
159
- });
160
-
161
- expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
162
- });
163
-
164
- it('calls `.handleQueryParams` when parsing is successful and in right context', function () {
165
- core.scopes.sources.run({ protect: {} }, () => {
166
- requestMock.query;
167
- });
168
-
169
- expect(inputAnalysis.handleQueryParams).to.have.been.calledOnce;
170
- expect(inputAnalysis.handleQueryParams).to.have.been.calledWithMatch({ parsedQuery: query }, query);
171
- });
172
- });
173
-
174
- ['4', '5'].forEach((v) => {
175
- describe(`express${v} Layer.prototype.match`, function() {
176
- let layer;
177
- beforeEach(function() {
178
- const args = v === '4'
179
- ? { name: 'express', version: '4', file: 'lib/router/layer.js' }
180
- : { name: 'router', version: '2', file: 'lib/layer.js' };
181
- core.depHooks.resolve.withArgs(args).yields(Layer);
182
- expressInstr(core).install();
183
- layer = { keys: ['foo'], params: { foo: 'bar' }, route: { path: '/test' } };
184
- });
185
-
186
- it('calls `.handleUrlParams` when parsing is successful and in right context', function () {
187
- core.scopes.sources.run({ protect: {} }, () => {
188
- Reflect.apply(Layer.prototype.match, layer, ['/bar']);
189
- });
190
-
191
- expect(inputAnalysis.handleUrlParams).to.have.been.calledOnce;
192
- expect(inputAnalysis.handleUrlParams).to.have.been.calledWithMatch({ parsedParams: layer.params }, layer.params);
193
- });
194
-
195
- it('does not call `.handleUrlParams` when match returns false', function () {
196
- Layer.prototype.match.returns(false);
197
-
198
- core.scopes.sources.run({}, () => {
199
- Reflect.apply(Layer.prototype.match, layer, ['/bar']);
200
- });
201
-
202
- expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
203
- });
204
-
205
- it('does not call `.handleUrlParams` when the route path is undefined', function () {
206
- core.scopes.sources.run({}, () => {
207
- Reflect.apply(Layer.prototype.match, { ...layer, route: undefined }, ['/bar']);
208
- });
209
-
210
- expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
211
- });
212
-
213
- it('does not call `.handleUrlParams` when the route path is `*`', function () {
214
- core.scopes.sources.run({}, () => {
215
- Reflect.apply(Layer.prototype.match, { ...layer, route: { path: '*' } }, ['/bar']);
216
- });
217
-
218
- expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
219
- });
220
-
221
- it('does not call `.handleUrlParams` when not in context', function () {
222
- core.scopes.sources.run({}, () => {
223
- Reflect.apply(Layer.prototype.match, layer, ['/bar']);
224
- });
225
-
226
- expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
227
- });
228
-
229
- it('does not call `.handleUrlParams` when no params are present on the current layer', function () {
230
- layer = { keys: [], params: {} };
231
-
232
- core.scopes.sources.run({ protect: {} }, () => {
233
- Reflect.apply(Layer.prototype.match, layer, ['/bar']);
234
- });
235
-
236
- expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
237
- });
238
-
239
- });
240
- });
241
- });