@contrast/protect
Advanced tools
Comparing version 1.21.0 to 1.22.0
@@ -18,3 +18,3 @@ /* | ||
module.exports = function(core) { | ||
module.exports = function (core) { | ||
const { scopes: { sources }, logger } = core; | ||
@@ -26,3 +26,3 @@ | ||
if (!sourceContext) { | ||
logger.debug(`source context not available in ${callPoint}`); | ||
logger.debug('source context not available in %s', callPoint); | ||
return null; | ||
@@ -29,0 +29,0 @@ } |
@@ -18,3 +18,7 @@ /* | ||
const { BLOCKING_MODES, isString } = require('@contrast/common'); | ||
const { | ||
BLOCKING_MODES, | ||
isString, | ||
Rule: { UNTRUSTED_DESERIALIZATION } | ||
} = require('@contrast/common'); | ||
@@ -41,3 +45,3 @@ const NODE_SERIALIZE_RCE_TOKEN = '_$$ND_FUNC$$_'; | ||
hardening.handleUntrustedDeserialization = function(sourceContext, sinkContext) { | ||
const ruleId = 'untrusted-deserialization'; | ||
const ruleId = UNTRUSTED_DESERIALIZATION; | ||
const mode = sourceContext.policy[ruleId]; | ||
@@ -44,0 +48,0 @@ const { name, value, stacktraceOpts } = sinkContext; |
@@ -401,3 +401,3 @@ /* | ||
inputAnalysis.handleVirtualPatches = function(sourceContext, requestInput) { | ||
const ruleId = 'virtual-patch'; | ||
const ruleId = Rule.VIRTUAL_PATCH; | ||
@@ -444,3 +444,3 @@ if (!Object.keys(requestInput).filter(Boolean).length || !sourceContext?.virtualPatchesEvaluators.length) return; | ||
inputAnalysis.handleIpDenylist = function(sourceContext, ipDenylist) { | ||
const ruleId = 'ip-denylist'; | ||
const ruleId = Rule.IP_DENYLIST; | ||
@@ -447,0 +447,0 @@ if (!sourceContext || !ipDenylist.length) return; |
@@ -39,59 +39,76 @@ /* | ||
function install() { | ||
depHooks.resolve({ name: 'express', version: '>=4.0.0 <5.0.0', file: 'lib/middleware/query.js' }, (query) => patcher.patch(query, { | ||
name: 'Express.query', | ||
patchType, | ||
post(data) { | ||
data.result = patcher.patch(data.result, { | ||
name: 'Express.query', | ||
patchType, | ||
pre(data) { | ||
const [req, , origNext] = data.args; | ||
depHooks.resolve( | ||
{ name: 'express', version: '>=4.0.0 <5.0.0', file: 'lib/middleware/query.js' }, | ||
(query) => patcher.patch(query, { | ||
name: 'express.query', | ||
patchType, | ||
post(data) { | ||
data.result = patcher.patch(data.result, { | ||
name: 'express.query', | ||
patchType, | ||
pre(data) { | ||
const [req, , origNext] = data.args; | ||
function contrastNext(origErr) { | ||
const sourceContext = protect.getSourceContext('Express.query'); | ||
let securityException; | ||
function contrastNext(origErr) { | ||
const sourceContext = protect.getSourceContext('express.query'); | ||
let securityException; | ||
// It is possible for the query to be already parsed by `qs` | ||
// which means that we've already handled/analyzed it. | ||
// So we check whether we already have the `parsedQuery` property in the context | ||
if (sourceContext && req.query && Object.keys(req.query).length && (!('parsedQuery' in sourceContext))) { | ||
sourceContext.parsedQuery = req.query; | ||
// It is possible for the query to be already parsed by `qs` | ||
// which means that we've already handled/analyzed it. | ||
// So we check whether we already have the `parsedQuery` property in the context | ||
if (sourceContext && req.query && Object.keys(req.query).length && (!('parsedQuery' in sourceContext))) { | ||
sourceContext.parsedQuery = req.query; | ||
try { | ||
inputAnalysis.handleQueryParams(sourceContext, req.query); | ||
} catch (err) { | ||
if (isSecurityException(err)) { | ||
securityException = err; | ||
} else { | ||
logger.error({ err }, 'Unexpected error during input analysis'); | ||
try { | ||
inputAnalysis.handleQueryParams(sourceContext, req.query); | ||
} catch (err) { | ||
if (isSecurityException(err)) { | ||
securityException = err; | ||
} else { | ||
logger.error({ err }, 'Unexpected error during input analysis'); | ||
} | ||
} | ||
} | ||
const error = securityException || origErr; | ||
origNext(error); | ||
} | ||
const error = securityException || origErr; | ||
data.args[2] = contrastNext; | ||
} | ||
}); | ||
} | ||
})); | ||
origNext(error); | ||
depHooks.resolve( | ||
{ name: 'express', version: '>=4.0.0 <5.0.0', file: 'lib/router/layer.js' }, | ||
(Layer) => { | ||
const name = 'express.Layer.prototype.match'; | ||
patcher.patch(Layer.prototype, 'match', { | ||
name, | ||
patchType, | ||
post(data) { | ||
const layer = data.obj; | ||
// we can exit early if | ||
// the layer doesn't match the request or | ||
// the layer doesn't recognize any parameters | ||
if (!data.result || !layer.keys || layer.keys.length === 0) { | ||
return; | ||
} | ||
data.args[2] = contrastNext; | ||
const sourceContext = protect.getSourceContext(name); | ||
if (!sourceContext) { | ||
return; | ||
} | ||
sourceContext.parsedParams = layer.params; | ||
inputAnalysis.handleUrlParams(sourceContext, layer.params); | ||
} | ||
}); | ||
} | ||
})); | ||
depHooks.resolve({ name: 'express', version: '>=4.0.0 <5.0.0', file: 'lib/router/layer.js' }, (Layer) => { | ||
patcher.patch(Layer.prototype, 'handle_request', { | ||
name: 'express.Layer.prototype.handle_request', | ||
patchType, | ||
pre(data) { | ||
const { obj: { params } } = data; | ||
const sourceContext = protect.getSourceContext('Express.Layer.handle_request'); | ||
if (sourceContext && params && Object.keys(params).length) { | ||
sourceContext.parsedParams = params; | ||
inputAnalysis.handleUrlParams(sourceContext, params); | ||
} | ||
} | ||
return Layer; | ||
}); | ||
}); | ||
} | ||
@@ -98,0 +115,0 @@ |
@@ -25,3 +25,4 @@ /* | ||
traverseKeysAndValues, | ||
agentLibIDListTypes | ||
agentLibIDListTypes, | ||
Rule: { SQL_INJECTION, PATH_TRAVERSAL, CMD_INJECTION, NOSQL_INJECTION_MONGO, SSJS_INJECTION, REFLECTED_XSS } | ||
} = require('@contrast/common'); | ||
@@ -55,3 +56,3 @@ | ||
inputTracing.handlePathTraversal = function(sourceContext, sinkContext) { | ||
const ruleId = 'path-traversal'; | ||
const ruleId = PATH_TRAVERSAL; | ||
const results = getResultsByRuleId(ruleId, sourceContext); | ||
@@ -72,3 +73,3 @@ | ||
inputTracing.handleCommandInjection = function(sourceContext, sinkContext) { | ||
const ruleId = 'cmd-injection'; | ||
const ruleId = CMD_INJECTION; | ||
const results = getResultsByRuleId(ruleId, sourceContext); | ||
@@ -99,3 +100,3 @@ | ||
inputTracing.handleSqlInjection = function(sourceContext, sinkContext) { | ||
const ruleId = 'sql-injection'; | ||
const ruleId = SQL_INJECTION; | ||
const results = getResultsByRuleId(ruleId, sourceContext); | ||
@@ -136,3 +137,3 @@ | ||
inputTracing.nosqlInjectionMongo = function (sourceContext, sinkContext) { | ||
const ruleId = 'nosql-injection-mongo'; | ||
const ruleId = NOSQL_INJECTION_MONGO; | ||
const nosqlInjectionMongoResults = | ||
@@ -246,3 +247,3 @@ getResultsByRuleId(ruleId, sourceContext) || []; | ||
inputTracing.ssjsInjection = function(sourceContext, sinkContext) { | ||
const ruleId = 'ssjs-injection'; | ||
const ruleId = SSJS_INJECTION; | ||
let sinkValuesArr = []; | ||
@@ -298,3 +299,3 @@ | ||
inputTracing.handleReflectedXss = function(sourceContext, sinkContext) { | ||
const ruleId = 'reflected-xss'; | ||
const ruleId = REFLECTED_XSS; | ||
const results = getResultsByRuleId(ruleId, sourceContext); | ||
@@ -301,0 +302,0 @@ |
{ | ||
"name": "@contrast/protect", | ||
"version": "1.21.0", | ||
"version": "1.22.0", | ||
"description": "Contrast service providing framework-agnostic Protect support", | ||
@@ -21,5 +21,5 @@ "license": "SEE LICENSE IN LICENSE", | ||
"@contrast/agent-lib": "^7.0.1", | ||
"@contrast/common": "1.12.0", | ||
"@contrast/core": "1.19.0", | ||
"@contrast/esm-hooks": "1.15.0", | ||
"@contrast/common": "1.13.0", | ||
"@contrast/core": "1.20.0", | ||
"@contrast/esm-hooks": "1.16.0", | ||
"@contrast/scopes": "1.4.0", | ||
@@ -26,0 +26,0 @@ "ipaddr.js": "^2.0.1", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
191306
5131
+ Added@contrast/agentify@1.11.0(transitive)
+ Added@contrast/common@1.13.0(transitive)
+ Added@contrast/config@1.15.0(transitive)
+ Added@contrast/core@1.20.0(transitive)
+ Added@contrast/dep-hooks@1.2.0(transitive)
+ Added@contrast/esm-hooks@1.16.0(transitive)
+ Added@contrast/logger@1.4.0(transitive)
+ Added@contrast/patcher@1.7.0(transitive)
+ Added@contrast/reporter@1.18.0(transitive)
+ Added@contrast/rewriter@1.4.2(transitive)
- Removed@contrast/agentify@1.10.0(transitive)
- Removed@contrast/common@1.12.0(transitive)
- Removed@contrast/config@1.14.0(transitive)
- Removed@contrast/core@1.19.0(transitive)
- Removed@contrast/dep-hooks@1.1.2(transitive)
- Removed@contrast/esm-hooks@1.15.0(transitive)
- Removed@contrast/logger@1.3.0(transitive)
- Removed@contrast/patcher@1.6.0(transitive)
- Removed@contrast/reporter@1.17.0(transitive)
- Removed@contrast/rewriter@1.4.1(transitive)
Updated@contrast/common@1.13.0
Updated@contrast/core@1.20.0
Updated@contrast/esm-hooks@1.16.0