@contrast/protect 1.54.0 → 1.54.2

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 +14 -11
  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 -1237
  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,83 +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
-
10
- describe('protect error-handlers koa2', function () {
11
- let core,
12
- errorHandler,
13
- Koa,
14
- onerror,
15
- store,
16
- ctx;
17
-
18
- beforeEach(function () {
19
- core = mocks.core();
20
- core.config = mocks.config();
21
- core.logger = mocks.logger();
22
- core.scopes = scopes(core);
23
- core.protect = mocks.protect();
24
- require('../../get-source-context')(core);
25
- core.depHooks = mocks.depHooks();
26
- core.patcher = patcher(core);
27
-
28
- store = {
29
- protect: {
30
- block: sinon.stub(),
31
- securityException: ['block', 'cmd-injection']
32
- }
33
- };
34
-
35
- Koa = function () { };
36
-
37
- Koa.prototype.handleRequest = function () { };
38
-
39
- core.depHooks.resolve.yields(Koa);
40
-
41
- errorHandler = require('./koa2')(core);
42
- errorHandler.install();
43
-
44
- onerror = sinon.stub();
45
- ctx = {
46
- onerror,
47
- };
48
- Koa.prototype.handleRequest(ctx);
49
- });
50
-
51
- it('should block the request when there is SecurityException', function () {
52
- const error = SecurityException.create();
53
-
54
- core.scopes.sources.run(store, () => {
55
- ctx.onerror(error);
56
- expect(core.logger.info).not.to.have.been.called;
57
- expect(store.protect.block).to.have.been.calledWith('block', 'cmd-injection');
58
- expect(ctx.body).to.equal('');
59
- });
60
- });
61
-
62
- it('should not block the request when there is SecurityException but sourceContext is missing', function () {
63
- const error = SecurityException.create();
64
-
65
- core.scopes.sources.run({}, () => {
66
- ctx.onerror(error);
67
- expect(core.logger.info).to.have.been.calledWith(
68
- { funcKey: 'protect-error-handling:koa.ctx.onerror' },
69
- 'source context not found; unable to handle response'
70
- );
71
- });
72
- });
73
-
74
- it('should skip the instrumentation when there is no SecurityException', function () {
75
- const error = new Error('Error');
76
-
77
- core.scopes.sources.run({}, () => {
78
- ctx.onerror(error);
79
- expect(core.logger.info).not.to.have.been.called;
80
- expect(store.protect.block).not.to.have.been.called;
81
- });
82
- });
83
- });
@@ -1,57 +0,0 @@
1
- 'use strict';
2
-
3
- const { expect } = require('chai');
4
- const sinon = require('sinon');
5
- const { initProtectFixture } = require('@contrast/test/fixtures');
6
- const SecurityException = require('../../security-exception');
7
-
8
- describe('protect error-handlers restify v8+', function () {
9
- let core, simulateRequestScope, Server, store;
10
-
11
- beforeEach(function () {
12
- ({ core, simulateRequestScope } = initProtectFixture());
13
-
14
- Server = { prototype: { _onHandlerError: sinon.stub().returnsArg(0) } };
15
- store = { protect: { block: sinon.stub(), securityException: ['block'] } };
16
-
17
- core.depHooks.resolve
18
- .withArgs({ name: 'restify', file: 'lib/server.js', version: '>=8 <12' })
19
- .yields(Server);
20
-
21
- core.protect.errorHandlers.restifyErrorHandler.install();
22
- });
23
-
24
- it('blocks the request when a security exception is handled', function () {
25
- const err = SecurityException.create();
26
-
27
- simulateRequestScope(() => {
28
- Server.prototype._onHandlerError(err);
29
-
30
- expect(store.protect.block).to.have.been.calledWith(...store.protect.securityException);
31
- }, store);
32
- });
33
-
34
- it('does not block the request when context is missing', function () {
35
- const err = SecurityException.create();
36
-
37
- simulateRequestScope(() => {
38
- Server.prototype._onHandlerError(err);
39
- expect(store.protect.block).not.to.have.been.called;
40
- expect(core.logger.info).to.have.been.calledWith(
41
- sinon.match.object,
42
- 'source context not found; unable to handle response',
43
- );
44
- }, {});
45
- });
46
-
47
- it('does not handle other errors', function () {
48
- const err = new Error();
49
-
50
- simulateRequestScope(() => {
51
- const result = Server.prototype._onHandlerError(err);
52
- expect(store.protect.block).not.to.have.been.called;
53
- expect(core.logger.info).not.to.have.been.called;
54
- expect(result).to.equal(err);
55
- }, store);
56
- });
57
- });
@@ -1,35 +0,0 @@
1
- 'use strict';
2
-
3
- const { expect } = require('chai');
4
- const { initProtectFixture } = require('@contrast/test/fixtures');
5
-
6
- describe('protect get-source-context', function () {
7
- let core, getSourceContext;
8
-
9
- beforeEach(function () {
10
- ({ core } = initProtectFixture());
11
- ({ getSourceContext } = core.protect);
12
- });
13
-
14
- it('returns the sourceContext when there is `allowed` property in it', function () {
15
- core.scopes.sources.run({ protect: { test: 'store' } }, () => {
16
- const result = getSourceContext();
17
- expect(result).to.deep.equal({ test: 'store' });
18
- });
19
- });
20
-
21
- it('logs a debug log when the sourceContext is missing and returns null', function () {
22
- core.scopes.sources.run({ protect: null }, () => {
23
- const result = getSourceContext();
24
- expect(result).to.null;
25
- });
26
- });
27
-
28
- it('returns null when the protect store has a thruthy `allowed` property', function () {
29
- core.scopes.sources.run({ protect: { allowed: true } }, () => {
30
- const result = getSourceContext();
31
- expect(core.logger.debug).not.to.have.been.called;
32
- expect(result).to.null;
33
- });
34
- });
35
- });
@@ -1,89 +0,0 @@
1
- 'use strict';
2
-
3
- const { expect } = require('chai');
4
- const mocks = require('@contrast/test/mocks');
5
- const { create: createSecurityException } = require('../security-exception');
6
- const handlersFactory = require('./handlers');
7
-
8
- describe('protect hardening handlers', function () {
9
- let core, handlers, map, sourceContext;
10
-
11
- const exception = createSecurityException();
12
- const sinkContext = {
13
- name: 'node-serialize.unserialize',
14
- value: '"foo":"_$$ND_FUNC$$_while(true)',
15
- get stack() {
16
- return [{
17
- file: 'index.js',
18
- lineNumber: 123,
19
- method: '',
20
- type: 'Function',
21
- }];
22
- },
23
- };
24
-
25
- function makePolicy(mode) {
26
- return {
27
- 'untrusted-deserialization': mode,
28
- };
29
- }
30
-
31
- beforeEach(function () {
32
- map = {};
33
- sourceContext = {
34
- resultsMap: map,
35
- };
36
- core = mocks.core();
37
- core.protect = mocks.protect();
38
- core.protect.hardening = {};
39
- core.protect.throwSecurityException.throws(exception);
40
- handlers = handlersFactory(core);
41
- });
42
-
43
- ['block', 'block_at_perimeter'].forEach((mode) => {
44
- it(`${mode}`, function () {
45
- sourceContext.policy = makePolicy(mode);
46
-
47
- expect(function () {
48
- handlers.handleUntrustedDeserialization(sourceContext, sinkContext);
49
- }).to.throw(exception.constructor);
50
-
51
- expect(map).to.have.deep.property('untrusted-deserialization', [{
52
- blocked: true,
53
- exploitMetadata: [{ deserializer: 'node-serialize.unserialize', command: false }],
54
- sinkContext,
55
- value: sinkContext.value,
56
- }]);
57
- });
58
- });
59
-
60
- it('monitor', function () {
61
- sourceContext.policy = makePolicy('monitor');
62
-
63
- handlers.handleUntrustedDeserialization(sourceContext, sinkContext);
64
-
65
- expect(map).to.have.deep.property('untrusted-deserialization', [{
66
- blocked: false,
67
- exploitMetadata: [{ deserializer: 'node-serialize.unserialize', command: false }],
68
- sinkContext,
69
- value: sinkContext.value,
70
- }]);
71
- });
72
-
73
- it('off', function () {
74
- sourceContext.policy = makePolicy('off');
75
-
76
- handlers.handleUntrustedDeserialization(sourceContext, sinkContext);
77
-
78
- expect(map).not.to.have.deep.property('untrusted-deserialization');
79
- });
80
-
81
- it('returns if the result value type is incorrect', function () {
82
- sourceContext.policy = makePolicy('monitor');
83
- sinkContext.value = true;
84
-
85
- handlers.handleUntrustedDeserialization(sourceContext, sinkContext);
86
-
87
- expect(map).not.to.have.deep.property('untrusted-deserialization');
88
- });
89
- });
@@ -1,31 +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 hardening', function () {
9
- let modulesMock, installStub, core, hardening;
10
- beforeEach(function () {
11
- installStub = sinon.stub();
12
- modulesMock = (propertyName) => function (core) {
13
- if (propertyName) {
14
- core.protect.hardening[propertyName] = { install: installStub };
15
- }
16
- };
17
- core = mocks.core();
18
- core.protect = mocks.protect();
19
-
20
- hardening = proxyquire('.', {
21
- './handlers': modulesMock,
22
- './install/node-serialize0': modulesMock('nodeSerialize0Instrumentation'),
23
- // Total of 2 modules required - 1 handlers and 1 module to be installed
24
- });
25
- });
26
-
27
- it('calls the install method on nodeSerialize0Instrumentation', function () {
28
- hardening(core).install();
29
- expect(installStub).to.have.been.calledOnce;
30
- });
31
- });
@@ -1,58 +0,0 @@
1
- 'use strict';
2
-
3
- const { expect } = require('chai');
4
- const sinon = require('sinon');
5
- const patcher = require('@contrast/patcher');
6
- const scopes = require('@contrast/scopes');
7
- const mocks = require('@contrast/test/mocks');
8
- const instrumentationFactory = require('./node-serialize0');
9
-
10
- describe('protect hardening node-serialize0', function () {
11
- let core, mockLib, hardening;
12
-
13
- beforeEach(function () {
14
- mockLib = {
15
- unserialize() { }
16
- };
17
-
18
- core = mocks.core();
19
- core.logger = mocks.logger();
20
- core.depHooks = mocks.depHooks();
21
- core.depHooks.resolve.yields(mockLib);
22
- core.patcher = patcher(core);
23
- core.scopes = scopes(core);
24
- core.protect = mocks.protect();
25
- require('../../get-source-context')(core);
26
- hardening = core.protect.hardening;
27
-
28
- instrumentationFactory(core).install();
29
- });
30
-
31
- it('calls hardening handler when called in sources scope', function () {
32
- const value = '"foo":"_$$ND_FUNC$$_while(true)';
33
- const sourceContext = {};
34
- const store = { protect: sourceContext };
35
- const sinkContext = {
36
- name: 'node-serialize.unserialize',
37
- value,
38
- stacktraceOpts: { constructorOpt: mockLib.unserialize, prependFrames: [sinon.match.func] }
39
- };
40
-
41
- core.scopes.sources.run(store, function () {
42
- mockLib.unserialize(value);
43
- });
44
-
45
- expect(hardening.handleUntrustedDeserialization).to.have.been.calledWith(
46
- sourceContext,
47
- sinkContext
48
- );
49
- });
50
-
51
- it('hardening handler is not called when out of sources scope', function () {
52
- const value = '"foo":"_$$ND_FUNC$$_while(true)';
53
-
54
- mockLib.unserialize(value);
55
-
56
- expect(hardening.handleUntrustedDeserialization).not.to.have.been.called;
57
- });
58
- });
package/lib/index.test.js DELETED
@@ -1,53 +0,0 @@
1
- 'use strict';
2
-
3
- const { expect } = require('chai');
4
- const proxyquire = require('proxyquire');
5
- const mocks = require('@contrast/test/mocks');
6
-
7
- const moduleMock = (moduleName, mock) => (deps) => {
8
- deps.protect[moduleName] = mock[moduleName];
9
- };
10
-
11
- describe('protect', function () {
12
- let core, protectMock, protectModule, modulesWithInstall;
13
-
14
- beforeEach(function () {
15
- protectMock = mocks.protect();
16
- core = mocks.core();
17
- core.logger = mocks.logger();
18
- core.config = mocks.config();
19
- core.scopes = mocks.scopes();
20
- core.config.protect.rules = {
21
- ['nosql-injection']: { mode: 'monitor' },
22
- ['cmd-injection']: { mode: 'block' },
23
- ['path-traversal']: { mode: 'off' }
24
- };
25
- core.config.protect.rules.disabled_rules = ['sql-injection'];
26
- core.rewriter = mocks.rewriter();
27
- protectModule = proxyquire('.', {
28
- './input-analysis': moduleMock('inputAnalysis', protectMock),
29
- './input-tracing': moduleMock('inputTracing', protectMock),
30
- './semantic-analysis': moduleMock('semanticAnalysis', protectMock),
31
- './hardening': moduleMock('hardening', protectMock),
32
- './error-handlers': moduleMock('errorHandlers', protectMock),
33
- });
34
- modulesWithInstall = ['inputAnalysis', 'inputTracing', 'hardening', 'errorHandlers'];
35
- });
36
-
37
- it('installs components and initializes policy', function () {
38
- core.config.getEffectiveValue.withArgs('protect.enable').returns(true);
39
- protectModule(core).install();
40
-
41
- modulesWithInstall.forEach((module) => {
42
- expect(protectMock[module].install).to.have.been.calledOnce;
43
- });
44
-
45
- expect(core.protect.getPolicy()).to.deep.include({
46
- rulesMask: 48,
47
- 'cmd-injection': 'block',
48
- 'nosql-injection': 'monitor',
49
- });
50
-
51
- expect(core.rewriter.install).to.have.been.calledWith('protect');
52
- });
53
- });