@contrast/assess
Advanced tools
Comparing version 1.35.0 to 1.36.0
@@ -21,3 +21,3 @@ /* | ||
isString, | ||
StringPrototypeToLowerCase, | ||
primordials: { StringPrototypeToLowerCase }, | ||
} = require('@contrast/common'); | ||
@@ -24,0 +24,0 @@ const semver = require('semver'); |
@@ -18,3 +18,3 @@ /* | ||
const { isString, ArrayPrototypeJoin, UtilInspect } = require('@contrast/common'); | ||
const { isString, primordials: { ArrayPrototypeJoin } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
@@ -28,2 +28,3 @@ const { createAppendTags } = require('../../tag-utils'); | ||
assess: { | ||
inspect, | ||
getSourceContext, | ||
@@ -75,3 +76,3 @@ eventFactory: { createPropagationEvent }, | ||
const { args: origArgs, obj, result, hooked, orig } = data; | ||
if (!result || !(getSourceContext(PROPAGATOR))) return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
@@ -99,3 +100,3 @@ const resultInfo = tracker.getData(result); | ||
methodName: 'prototype.join', | ||
context: `${object.value}.join('${UtilInspect(args[0].value) || ''})`, | ||
context: `${object.value}.join('${inspect(args[0].value) || ''})`, | ||
object, | ||
@@ -102,0 +103,0 @@ result: { |
@@ -65,3 +65,3 @@ 'use strict'; | ||
it('propagates correclty nested arrays', function () { | ||
it('propagates correctly nested arrays', function () { | ||
simulateRequestScope(function () { | ||
@@ -90,3 +90,3 @@ const str = trackString('tracked', { tags: { untrusted: [0, 6] } }); | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in source context', function () { | ||
simulateRequestScope(function () { | ||
@@ -96,3 +96,3 @@ const value = trackString('foo'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -99,0 +99,0 @@ |
@@ -17,3 +17,3 @@ /* | ||
const { isString, ArrayPrototypeJoin, StringPrototypeSubstring } = require('@contrast/common'); | ||
const { isString, primordials: { ArrayPrototypeJoin, StringPrototypeSubstring, BufferPrototypeToString } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
@@ -36,3 +36,2 @@ const { getAdjustedUntrackedValue } = require('../../tag-utils'); | ||
const name = 'global.Buffer.prototype.toString'; | ||
const bufferToString = patcher.unwrap(Buffer.prototype.toString); | ||
@@ -104,3 +103,3 @@ patcher.patch(global.Buffer.prototype, 'toString', { | ||
if (i == 0) { | ||
const value = argType == 'string' ? arg : bufferToString.call(arg); | ||
const value = argType == 'string' ? arg : BufferPrototypeToString.call(arg); | ||
// todo (NODE-3455): make sure tag ranges are included in substring | ||
@@ -107,0 +106,0 @@ return { tracked: true, value: StringPrototypeSubstring.call(value, 0, 50) }; |
@@ -138,3 +138,3 @@ 'use strict'; | ||
it('does not propagate if not in proper scope', function () { | ||
it('does not propagate if no assess policy in request store', function () { | ||
simulateRequestScope(() => { | ||
@@ -144,4 +144,4 @@ const result = global.ContrastMethods.tag(['', ''], trackString('bar')); | ||
expect(data).to.be.null; | ||
}, null); | ||
}, { assess: { policy: null } }); | ||
}); | ||
}); |
@@ -18,8 +18,5 @@ /* | ||
const { | ||
DataflowTag: { URL_ENCODED } | ||
} = require('@contrast/common'); | ||
const { | ||
createFullLengthCopyTags | ||
} = require('../../tag-utils'); | ||
const { DataflowTag: { URL_ENCODED } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createFullLengthCopyTags } = require('../../tag-utils'); | ||
const { patchType, createObjectLabel } = require('../common'); | ||
@@ -29,5 +26,5 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -47,3 +44,3 @@ dataflow: { tracker } | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -50,0 +47,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -66,3 +66,3 @@ | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -69,0 +69,0 @@ |
@@ -18,8 +18,5 @@ /* | ||
const { | ||
DataflowTag: { WEAK_URL_ENCODED } | ||
} = require('@contrast/common'); | ||
const { | ||
createFullLengthCopyTags | ||
} = require('../../../tag-utils'); | ||
const { DataflowTag: { WEAK_URL_ENCODED } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createFullLengthCopyTags } = require('../../../tag-utils'); | ||
const { patchType } = require('../../common'); | ||
@@ -29,6 +26,6 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -41,3 +38,3 @@ dataflow: { tracker } | ||
install() { | ||
depHooks.resolve({ name: 'ejs', file: 'lib/utils.js', version: '>=2.6.2' }, (ejsUtils, version) => { | ||
depHooks.resolve({ name: 'ejs', file: 'lib/utils.js', version: '>=2.6.2' }, (ejsUtils) => { | ||
const name = 'ejs.utils.escapeXML'; | ||
@@ -49,3 +46,3 @@ patcher.patch(ejsUtils, 'escapeXML', { | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -52,0 +49,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -52,3 +52,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -58,3 +58,3 @@ const value = trackString('foo'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -61,0 +61,0 @@ |
@@ -19,3 +19,3 @@ /* | ||
const { EOL } = require('os'); | ||
const { ArrayPrototypeJoin } = require('@contrast/common'); | ||
const { primordials: { ArrayPrototypeJoin, StringPrototypeSubstring } } = require('@contrast/common'); | ||
const { patchType } = require('../../common'); | ||
@@ -69,3 +69,3 @@ const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { code } = rewriter.rewriteSync(`${WRAPPER_PREFIX}${data.obj.source}${WRAPPER_SUFFIX}`, REWRITE_OPTS); | ||
data.obj.source = code.substring(code.indexOf('{') + 1, code.lastIndexOf('}')); | ||
data.obj.source = StringPrototypeSubstring.call(code, code.indexOf('{') + 1, code.lastIndexOf('}')); | ||
} catch (err) { | ||
@@ -72,0 +72,0 @@ logger.error( |
@@ -21,5 +21,4 @@ /* | ||
} = require('@contrast/common'); | ||
const { | ||
createEscapeTagRanges | ||
} = require('../../tag-utils'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createEscapeTagRanges } = require('../../tag-utils'); | ||
const { patchType, createObjectLabel } = require('../common'); | ||
@@ -29,5 +28,5 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -40,3 +39,2 @@ dataflow: { tracker } | ||
install() { | ||
[ | ||
@@ -58,3 +56,3 @@ { | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -61,0 +59,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -30,3 +30,3 @@ | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -36,3 +36,3 @@ const value = trackString('?test=str'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -39,0 +39,0 @@ |
@@ -18,8 +18,5 @@ /* | ||
const { | ||
DataflowTag: { HTML_ENCODED } | ||
} = require('@contrast/common'); | ||
const { | ||
createEscapeTagRanges | ||
} = require('../../tag-utils'); | ||
const { DataflowTag: { HTML_ENCODED } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createEscapeTagRanges } = require('../../tag-utils'); | ||
const { patchType } = require('../common'); | ||
@@ -29,6 +26,6 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -49,3 +46,3 @@ dataflow: { tracker } | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -52,0 +49,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -31,3 +31,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -37,3 +37,3 @@ const value = trackString('<script>alert("hello");</script>'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -56,3 +56,3 @@ | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}); | ||
}); | ||
@@ -59,0 +59,0 @@ |
@@ -18,8 +18,5 @@ /* | ||
const { | ||
DataflowTag: { WEAK_URL_ENCODED } | ||
} = require('@contrast/common'); | ||
const { | ||
createFullLengthCopyTags | ||
} = require('../../tag-utils'); | ||
const { DataflowTag: { WEAK_URL_ENCODED } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createFullLengthCopyTags } = require('../../tag-utils'); | ||
const { patchType, createObjectLabel } = require('../common'); | ||
@@ -29,5 +26,5 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -47,3 +44,3 @@ dataflow: { tracker } | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -50,0 +47,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -56,3 +56,3 @@ | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -62,3 +62,3 @@ const value = trackString('?test=str'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -65,0 +65,0 @@ |
@@ -17,4 +17,4 @@ /* | ||
const { primordials: { StringPrototypeSlice } } = require('@contrast/common'); | ||
const { patchType } = require('../common'); | ||
const { StringPrototypeSlice } = require('@contrast/common'); | ||
@@ -25,3 +25,3 @@ module.exports = function (core) { | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { getSourceContext } | ||
} = core; | ||
@@ -38,5 +38,3 @@ | ||
if (!sources.getStore()?.assess || instrumentation.isLocked()) { | ||
return; | ||
} | ||
if (!getSourceContext()) return; | ||
@@ -43,0 +41,0 @@ const untrackedPath = StringPrototypeSlice.call(` ${args[0]}`, 1); |
@@ -18,8 +18,5 @@ /* | ||
const { | ||
DataflowTag: { HTML_ENCODED } | ||
} = require('@contrast/common'); | ||
const { | ||
createFullLengthCopyTags | ||
} = require('../../tag-utils'); | ||
const { DataflowTag: { HTML_ENCODED } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createFullLengthCopyTags } = require('../../tag-utils'); | ||
const { patchType } = require('../common'); | ||
@@ -29,6 +26,6 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -41,3 +38,3 @@ dataflow: { tracker } | ||
install() { | ||
depHooks.resolve({ name: 'handlebars', version: '>=4.0.0' }, (handlebars, version) => { | ||
depHooks.resolve({ name: 'handlebars', version: '>=4.0.0' }, (handlebars) => { | ||
const name = 'handlebars.Utils.escapeExpression'; | ||
@@ -50,3 +47,3 @@ | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -53,0 +50,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -59,3 +59,3 @@ 'use strict'; | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -62,0 +62,0 @@ |
@@ -26,5 +26,5 @@ /* | ||
depHooks, | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -44,61 +44,59 @@ eventFactory: { createPropagationEvent }, | ||
const def = Object.getPrototypeOf(boolean)?._definition; | ||
def && | ||
patcher.patch(def.coerce, 'method', { | ||
name: 'joi.boolean.coerce', | ||
patchType, | ||
post(data) { | ||
if ( | ||
!data.result?.value || | ||
typeof data.result.value !== 'boolean' || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!def?.coerce) return; | ||
const argInfo = tracker.getData(data.args[0]); | ||
patcher.patch(def.coerce, 'method', { | ||
name: 'joi.boolean.coerce', | ||
patchType, | ||
post(data) { | ||
if ( | ||
!data.result?.value || | ||
typeof data.result.value !== 'boolean' || | ||
!getSourceContext() | ||
) return; | ||
if (!argInfo) return; | ||
const argInfo = tracker.getData(data.args[0]); | ||
if (!argInfo) return; | ||
const event = createPropagationEvent({ | ||
name: 'Joi.boolean.coerce', | ||
moduleName: 'joi', | ||
methodName: 'boolean.coerce', | ||
history: [{ ...argInfo }], | ||
object: { | ||
const event = createPropagationEvent({ | ||
name: 'Joi.boolean.coerce', | ||
moduleName: 'joi', | ||
methodName: 'boolean.coerce', | ||
history: [{ ...argInfo }], | ||
object: { | ||
tracked: false, | ||
value: 'Joi.boolean', | ||
}, | ||
args: [ | ||
{ tracked: true, value: argInfo.value }, | ||
{ | ||
tracked: false, | ||
value: 'Joi.boolean', | ||
}, | ||
args: [ | ||
{ tracked: true, value: argInfo.value }, | ||
{ | ||
tracked: false, | ||
value: { | ||
...inspect(data.args[1]), | ||
original: argInfo.value, | ||
}, | ||
value: { | ||
...inspect(data.args[1]), | ||
original: argInfo.value, | ||
}, | ||
], | ||
result: { | ||
tracked: false, | ||
value: data.result, | ||
}, | ||
source: 'P0', | ||
tags: { | ||
...argInfo.tags, | ||
[ALPHANUM_SPACE_HYPHEN]: [0, argInfo.value.length - 1], | ||
}, | ||
target: 'P0', | ||
stacktraceOpts: { | ||
prependFrames: [data.orig], | ||
}, | ||
}); | ||
], | ||
result: { | ||
tracked: false, | ||
value: data.result, | ||
}, | ||
source: 'P0', | ||
tags: { | ||
...argInfo.tags, | ||
[ALPHANUM_SPACE_HYPHEN]: [0, argInfo.value.length - 1], | ||
}, | ||
target: 'P0', | ||
stacktraceOpts: { | ||
prependFrames: [data.orig], | ||
}, | ||
}); | ||
if (event) { | ||
Object.assign(argInfo, event); | ||
} | ||
}, | ||
}); | ||
if (event) { | ||
Object.assign(argInfo, event); | ||
} | ||
}, | ||
}); | ||
} | ||
return (core.assess.dataflow.propagation.joiInstrumentation.booleanCoerce = { | ||
return core.assess.dataflow.propagation.joiInstrumentation.booleanCoerce = { | ||
install() { | ||
@@ -110,3 +108,3 @@ depHooks.resolve( | ||
}, | ||
}); | ||
}; | ||
}; |
@@ -18,5 +18,3 @@ /* | ||
const { | ||
DataflowTag: { HTML_ENCODED }, | ||
} = require('@contrast/common'); | ||
const { DataflowTag: { HTML_ENCODED } } = require('@contrast/common'); | ||
const { patchType } = require('../../common'); | ||
@@ -27,5 +25,5 @@ | ||
depHooks, | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -46,8 +44,3 @@ eventFactory: { createPropagationEvent }, | ||
post(data) { | ||
if ( | ||
!data.result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!data.result || !getSourceContext()) return; | ||
@@ -54,0 +47,0 @@ const argInfo = tracker.getData(data.args[0]); |
@@ -30,4 +30,4 @@ /* | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -39,126 +39,123 @@ eventFactory: { createPropagationEvent }, | ||
const joiInstrumentation = | ||
(core.assess.dataflow.propagation.joiInstrumentation = { | ||
install() { | ||
callChildComponentMethodsSync(joiInstrumentation, 'install'); | ||
}, | ||
uninstall() { | ||
callChildComponentMethodsSync(joiInstrumentation, 'uninstall'); | ||
}, | ||
patchValidateAsync(parentObj, parentObjType) { | ||
patcher.patch(parentObj, 'validateAsync', { | ||
name: `Joi.${parentObjType}.validateAsync`, | ||
patchType, | ||
post(data) { | ||
const childNodes = data.obj?.$_terms.items?.length | ||
? data.obj.$_terms.items | ||
: data.obj?.$_terms.keys?.length | ||
? data.obj.$_terms.keys | ||
: null; | ||
const joiInstrumentation = core.assess.dataflow.propagation.joiInstrumentation = { | ||
install() { | ||
callChildComponentMethodsSync(joiInstrumentation, 'install'); | ||
}, | ||
uninstall() { | ||
callChildComponentMethodsSync(joiInstrumentation, 'uninstall'); | ||
}, | ||
patchValidateAsync(parentObj, parentObjType) { | ||
patcher.patch(parentObj, 'validateAsync', { | ||
name: `Joi.${parentObjType}.validateAsync`, | ||
patchType, | ||
post(data) { | ||
const childNodes = data.obj?.$_terms.items?.length | ||
? data.obj.$_terms.items | ||
: data.obj?.$_terms.keys?.length | ||
? data.obj.$_terms.keys | ||
: null; | ||
if ( | ||
(!childNodes && !data.obj?.$_terms?.externals?.length) || | ||
if ( | ||
(!childNodes && !data.obj?.$_terms?.externals?.length) || | ||
(childNodes && | ||
!childNodes.find((i) => { | ||
const schema = i?.schema || i; | ||
return schema.$_terms?.externals?.length; | ||
})) || | ||
!childNodes.find((i) => { | ||
const schema = i?.schema || i; | ||
return schema.$_terms?.externals?.length; | ||
})) || | ||
!core.config.assess.trust_custom_validators || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
!getSourceContext() | ||
) | ||
return; | ||
data.result.then((result) => { | ||
const metadata = { | ||
origFn: data.orig, | ||
methodName: parentObjType, | ||
target: 'R', | ||
}; | ||
data.result.then((result) => { | ||
const metadata = { | ||
origFn: data.orig, | ||
methodName: parentObjType, | ||
target: 'R', | ||
}; | ||
if (isString(result)) { | ||
if (isString(result)) { | ||
tagCustomValidatedString( | ||
createPropagationEvent, | ||
tracker.getData(result), | ||
metadata | ||
); | ||
} else if (isNonEmptyObject(result)) { | ||
traverseValues(result, (_path, _key, value) => { | ||
tagCustomValidatedString( | ||
createPropagationEvent, | ||
tracker.getData(result), | ||
tracker.getData(value), | ||
metadata | ||
); | ||
} else if (isNonEmptyObject(result)) { | ||
traverseValues(result, (_path, _key, value) => { | ||
tagCustomValidatedString( | ||
createPropagationEvent, | ||
tracker.getData(value), | ||
metadata | ||
); | ||
}); | ||
} | ||
}) | ||
.catch(err => err); | ||
}, | ||
}); | ||
}, | ||
patchCustomValidate(parentObj, objName) { | ||
patcher.patch(parentObj.rules.custom, 'validate', { | ||
name: `joi.${objName}.custom.valdiate`, | ||
patchType, | ||
post(data) { | ||
const { | ||
args: [input, schema], | ||
result, | ||
orig, | ||
} = data; | ||
}); | ||
} | ||
}) | ||
.catch(err => err); | ||
}, | ||
}); | ||
}, | ||
patchCustomValidate(parentObj, objName) { | ||
patcher.patch(parentObj.rules.custom, 'validate', { | ||
name: `joi.${objName}.custom.valdiate`, | ||
patchType, | ||
post(data) { | ||
const { | ||
args: [input, schema], | ||
result, | ||
orig, | ||
} = data; | ||
if ( | ||
!result || | ||
if ( | ||
!result || | ||
!input || | ||
(result.value === input && | ||
(result.messages?.source || result.local?.error)) || | ||
(result.messages?.source || result.local?.error)) || | ||
!core.config.assess.trust_custom_validators || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
!getSourceContext() | ||
) | ||
return; | ||
const inspectedSecondArg = inspect(schema); | ||
const metadata = { | ||
origFn: orig, | ||
inspectedSecondArg, | ||
methodName: `${objName}.custom.validate`, | ||
target: 'R', | ||
}; | ||
const validation = (trackingInfo) => { | ||
const inspectedSecondArg = inspect(schema); | ||
const metadata = { | ||
origFn: orig, | ||
inspectedSecondArg, | ||
methodName: `${objName}.custom.validate`, | ||
target: 'R', | ||
}; | ||
const validation = (trackingInfo) => { | ||
tagCustomValidatedString( | ||
createPropagationEvent, | ||
trackingInfo, | ||
metadata | ||
); | ||
}; | ||
handleReferences(tracker, schema, validation); | ||
if (isString(result)) { | ||
validation(tracker.getData(result)); | ||
input === result && | ||
tagCustomValidatedString( | ||
createPropagationEvent, | ||
trackingInfo, | ||
metadata | ||
tracker.getData(input), | ||
{ ...metadata, target: 'P0' } | ||
); | ||
}; | ||
} else if (isNonEmptyObject(result)) { | ||
traverseValues(result, (path, _key, value) => { | ||
const argValue = path.reduce((obj, k) => obj[k] || obj, input); | ||
handleReferences(tracker, schema, validation); | ||
if (isString(result)) { | ||
validation(tracker.getData(result)); | ||
input === result && | ||
argValue === value && | ||
tagCustomValidatedString( | ||
createPropagationEvent, | ||
tracker.getData(input), | ||
tracker.getData(argValue), | ||
{ ...metadata, target: 'P0' } | ||
); | ||
} else if (isNonEmptyObject(result)) { | ||
traverseValues(result, (path, _key, value) => { | ||
const argValue = path.reduce((obj, k) => obj[k] || obj, input); | ||
}); | ||
} | ||
}, | ||
}); | ||
} | ||
}; | ||
validation(tracker.getData(result)); | ||
argValue === value && | ||
tagCustomValidatedString( | ||
createPropagationEvent, | ||
tracker.getData(argValue), | ||
{ ...metadata, target: 'P0' } | ||
); | ||
}); | ||
} | ||
}, | ||
}); | ||
}, | ||
}); | ||
require('./any')(core); | ||
@@ -165,0 +162,0 @@ require('./expression')(core); |
@@ -20,3 +20,6 @@ /* | ||
isNonEmptyObject, | ||
ArrayPrototypeJoin, | ||
primordials: { | ||
ArrayPrototypeJoin, | ||
ArrayPrototypeSlice | ||
} | ||
} = require('@contrast/common'); | ||
@@ -29,2 +32,3 @@ const { patchType } = require('../../common'); | ||
patcher, | ||
assess: { getSourceContext } | ||
} = core; | ||
@@ -48,5 +52,5 @@ | ||
if (isInReference) { | ||
path = ArrayPrototypeJoin.call(refTargetPath.slice(0, -1), '.'); | ||
path = ArrayPrototypeJoin.call(ArrayPrototypeSlice.call(refTargetPath, 0, -1), '.'); | ||
schema.__CONTRAST__.inReferenceTargets.add(path); | ||
refPath = refPath.slice(0, -1); | ||
refPath = ArrayPrototypeSlice.call(refPath, 0, -1); | ||
} | ||
@@ -125,3 +129,3 @@ | ||
return (core.assess.dataflow.propagation.joiInstrumentation.keys = { | ||
return core.assess.dataflow.propagation.joiInstrumentation.keys = { | ||
install() { | ||
@@ -138,2 +142,3 @@ depHooks.resolve( | ||
if (!getSourceContext()) return; | ||
traverseSchemas(joi, value, value); | ||
@@ -145,3 +150,3 @@ }, | ||
}, | ||
}); | ||
}; | ||
}; |
@@ -26,5 +26,5 @@ /* | ||
depHooks, | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -42,61 +42,59 @@ eventFactory: { createPropagationEvent }, | ||
const def = Object.getPrototypeOf(number)?._definition; | ||
def && | ||
patcher.patch(def.coerce, 'method', { | ||
name: 'joi.number.coerce', | ||
patchType, | ||
post(data) { | ||
if ( | ||
!data.result?.value || | ||
data.result.errors || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!def?.coerce) return; | ||
const argInfo = tracker.getData(data.args[0]); | ||
patcher.patch(def.coerce, 'method', { | ||
name: 'joi.number.coerce', | ||
patchType, | ||
post(data) { | ||
if ( | ||
!data.result?.value || | ||
data.result.errors || | ||
!getSourceContext() | ||
) return; | ||
if (!argInfo) return; | ||
const argInfo = tracker.getData(data.args[0]); | ||
if (!argInfo) return; | ||
const event = createPropagationEvent({ | ||
name: 'Joi.number.coerce', | ||
moduleName: 'joi', | ||
methodName: 'number.coerce', | ||
history: [{ ...argInfo }], | ||
object: { | ||
const event = createPropagationEvent({ | ||
name: 'Joi.number.coerce', | ||
moduleName: 'joi', | ||
methodName: 'number.coerce', | ||
history: [{ ...argInfo }], | ||
object: { | ||
tracked: false, | ||
value: 'Joi.number', | ||
}, | ||
args: [ | ||
{ tracked: true, value: argInfo.value }, | ||
{ | ||
tracked: false, | ||
value: 'Joi.number', | ||
}, | ||
args: [ | ||
{ tracked: true, value: argInfo.value }, | ||
{ | ||
tracked: false, | ||
value: { | ||
...inspect(data.args[1]), | ||
original: argInfo.value, | ||
}, | ||
value: { | ||
...inspect(data.args[1]), | ||
original: argInfo.value, | ||
}, | ||
], | ||
result: { | ||
tracked: false, | ||
value: data.result, | ||
}, | ||
source: 'P0', | ||
tags: { | ||
...argInfo.tags, | ||
[LIMITED_CHARS]: [0, argInfo.value.length - 1], | ||
}, | ||
target: 'P0', | ||
stacktraceOpts: { | ||
prependFrames: [data.orig], | ||
}, | ||
}); | ||
], | ||
result: { | ||
tracked: false, | ||
value: data.result, | ||
}, | ||
source: 'P0', | ||
tags: { | ||
...argInfo.tags, | ||
[LIMITED_CHARS]: [0, argInfo.value.length - 1], | ||
}, | ||
target: 'P0', | ||
stacktraceOpts: { | ||
prependFrames: [data.orig], | ||
}, | ||
}); | ||
if (event) { | ||
Object.assign(argInfo, event); | ||
} | ||
}, | ||
}); | ||
if (event) { | ||
Object.assign(argInfo, event); | ||
} | ||
}, | ||
}); | ||
} | ||
return (core.assess.dataflow.propagation.joiInstrumentation.numberCoerce = { | ||
return core.assess.dataflow.propagation.joiInstrumentation.numberCoerce = { | ||
install() { | ||
@@ -108,3 +106,3 @@ depHooks.resolve( | ||
}, | ||
}); | ||
}; | ||
}; |
@@ -42,5 +42,5 @@ /* | ||
depHooks, | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -52,4 +52,3 @@ eventFactory: { createPropagationEvent }, | ||
} | ||
}, | ||
} | ||
}, | ||
@@ -118,6 +117,4 @@ } = core; | ||
(validatorName === 'validate' && data.result) || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
!getSourceContext() | ||
) return; | ||
@@ -153,6 +150,4 @@ const inspectedSchema = inspect(schema); | ||
!args[1].schema.$_getRule('isoDate') || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
!getSourceContext() | ||
) return; | ||
@@ -201,3 +196,3 @@ const argInfo = tracker.getData(args[0]); | ||
return (joiInstrumentation.stringSchema = { | ||
return joiInstrumentation.stringSchema = { | ||
install() { | ||
@@ -237,4 +232,4 @@ depHooks.resolve( | ||
); | ||
}, | ||
}); | ||
} | ||
}; | ||
}; |
@@ -19,4 +19,7 @@ /* | ||
const { | ||
StringPrototypeSplit, | ||
ArrayPrototypeJoin, | ||
primordials: { | ||
StringPrototypeSplit, | ||
ArrayPrototypeJoin, | ||
ArrayPrototypeSlice, | ||
}, | ||
DataflowTag: { CUSTOM_VALIDATED } | ||
@@ -79,6 +82,6 @@ } = require('@contrast/common'); | ||
let refTargetPath = contrastData && ArrayPrototypeJoin.call(schema.state.path, '.'); | ||
const inReferenceTargetPath = contrastData && ArrayPrototypeJoin.call(schema.state.path.slice(0, -1), '.'); | ||
const inReferenceTargetPath = contrastData && ArrayPrototypeJoin.call(ArrayPrototypeSlice.call(schema.state.path, 0, -1), '.'); | ||
if (contrastData?.inReferenceTargets.has(inReferenceTargetPath)) { | ||
refTargetPath = ArrayPrototypeJoin.call( | ||
schema.state.path.slice(0, -1), | ||
ArrayPrototypeSlice.call(schema.state.path, 0, -1), | ||
'.' | ||
@@ -85,0 +88,0 @@ ); |
@@ -19,3 +19,3 @@ /* | ||
const { | ||
isNonEmptyObject, isString, traverseValues, ArrayPrototypeJoin | ||
isNonEmptyObject, isString, traverseValues, primordials: { ArrayPrototypeJoin } | ||
} = require('@contrast/common'); | ||
@@ -28,5 +28,5 @@ const { createMergedTags } = require('../../../tag-utils'); | ||
depHooks, | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -51,4 +51,3 @@ eventFactory: { createPropagationEvent }, | ||
!result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
!getSourceContext() | ||
) return; | ||
@@ -62,3 +61,2 @@ | ||
if (result.ref) { | ||
@@ -150,3 +148,3 @@ const targetAbsolutePath = ArrayPrototypeJoin.call(result.ref.absolute(state), '.'); | ||
return (core.assess.dataflow.propagation.joiInstrumentation.values = { | ||
return core.assess.dataflow.propagation.joiInstrumentation.values = { | ||
install() { | ||
@@ -158,4 +156,4 @@ depHooks.resolve( | ||
}, | ||
}); | ||
}; | ||
}; | ||
@@ -17,3 +17,3 @@ /* | ||
const { StringPrototypeTrim } = require('@contrast/common'); | ||
const { primordials: { StringPrototypeTrim } } = require('@contrast/common'); | ||
@@ -20,0 +20,0 @@ function isNumber(value) { |
@@ -19,2 +19,3 @@ /* | ||
const { isString } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createSubsetTags } = require('../../../tag-utils'); | ||
@@ -51,5 +52,5 @@ const { patchType } = require('../../common'); | ||
logger, | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -105,3 +106,3 @@ dataflow: { tracker }, | ||
pre(data) { | ||
if (!data.args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!data.args[0] || !getSourceContext(PROPAGATOR)) return; | ||
const [input, reviver] = data.args; | ||
@@ -108,0 +109,0 @@ |
@@ -126,3 +126,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -135,3 +135,3 @@ const trackedString = trackString('foo'); | ||
expect(tracker.getData(result.prop)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -138,0 +138,0 @@ |
@@ -20,9 +20,12 @@ /* | ||
isString, | ||
ArrayPrototypeSlice, | ||
StringPrototypeReplace, | ||
StringPrototypeMatch, | ||
StringPrototypeMatchAll, | ||
StringPrototypeSlice, | ||
primordials: { | ||
ArrayPrototypeSlice, | ||
StringPrototypeReplace, | ||
StringPrototypeMatch, | ||
StringPrototypeMatchAll, | ||
StringPrototypeSlice, | ||
} | ||
} = require('@contrast/common'); | ||
const crypto = require('crypto'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createMergedTags, getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
@@ -82,5 +85,5 @@ const { patchType } = require('../../common'); | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -97,4 +100,2 @@ dataflow: { tracker } | ||
} | ||
const props = tracker.getData(StringPrototypeSlice.call(space, 0, 10)); | ||
@@ -171,3 +172,3 @@ if (!props || !Object.keys(props.tags).length) { | ||
pre(data) { | ||
if (!sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!getSourceContext(PROPAGATOR)) return; | ||
@@ -229,3 +230,3 @@ const [input, , space] = data.args; | ||
post(data) { | ||
if (!sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!getSourceContext(PROPAGATOR)) return; | ||
let tags = {}; | ||
@@ -232,0 +233,0 @@ const vulnerableSources = []; |
@@ -6,3 +6,3 @@ 'use strict'; | ||
const { | ||
UtilInspect, | ||
primordials: { UtilInspect }, | ||
DataflowTag: { UNTRUSTED }, | ||
@@ -84,3 +84,3 @@ } = require('@contrast/common'); | ||
it('results in an untracked string when there is no Assess scope', function () { | ||
it('results in an untracked string when there is no Assess policy in request scope', function () { | ||
simulateRequestScope(() => { | ||
@@ -90,3 +90,3 @@ const ret = JSON.stringify(objWithTrackedStr); | ||
expect(tracker.getData(ret)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -93,0 +93,0 @@ |
@@ -16,5 +16,6 @@ /* | ||
'use strict'; | ||
const { traverseValues, DataflowTag, primordials: { StringPrototypeSubstring } } = require('@contrast/common'); | ||
const { patchType } = require('../../common'); | ||
const { userDefinedType } = require('./common'); | ||
const { traverseValues, DataflowTag, StringPrototypeSubstring } = require('@contrast/common'); | ||
@@ -24,6 +25,6 @@ module.exports = function (core) { | ||
config: { assess }, | ||
scopes: { sources }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -112,3 +113,3 @@ dataflow: { | ||
post: (data) => { | ||
if (!assess.trust_custom_validators || data.result || !sources.getStore()?.assess) return; | ||
if (!assess.trust_custom_validators || data.result || !getSourceContext()) return; | ||
@@ -131,3 +132,3 @@ mapInstrumentation(data, doValidateSyncName); | ||
typeof cb !== 'function' || | ||
!sources.getStore()?.assess | ||
!getSourceContext() | ||
) { | ||
@@ -134,0 +135,0 @@ return; |
@@ -110,3 +110,3 @@ 'use strict'; | ||
it('SchemaMap.doValidateSync skip instrumentation if there is no assess scope', function () { | ||
it('SchemaMap.doValidateSync skip instrumentation if there is no assess policy in request scope', function () { | ||
simulateRequestScope(function () { | ||
@@ -119,3 +119,3 @@ const str = trackString('error'); | ||
expect(strInfo).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -266,3 +266,3 @@ | ||
it('SchemaMap.doValidate skip instrumentation if there is no assess scope', function () { | ||
it('SchemaMap.doValidate skip instrumentation if there is no assess policy in request scope', function () { | ||
simulateRequestScope(function () { | ||
@@ -275,3 +275,3 @@ const str = trackString('foo'); | ||
expect(strInfo).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -278,0 +278,0 @@ |
@@ -16,5 +16,6 @@ /* | ||
'use strict'; | ||
const { traverseValues, DataflowTag, primordials: { StringPrototypeSubstring } } = require('@contrast/common'); | ||
const { patchType } = require('../../common'); | ||
const { userDefinedType } = require('./common'); | ||
const { traverseValues, DataflowTag, StringPrototypeSubstring } = require('@contrast/common'); | ||
@@ -24,6 +25,6 @@ module.exports = function (core) { | ||
config: { assess }, | ||
scopes: { sources }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -124,3 +125,3 @@ dataflow: { | ||
data.result || | ||
!sources.getStore()?.assess | ||
!getSourceContext() | ||
) { | ||
@@ -140,3 +141,3 @@ return; | ||
pre: (data) => { | ||
if (!assess.trust_custom_validators || !sources.getStore()?.assess) { | ||
if (!assess.trust_custom_validators || !getSourceContext()) { | ||
return; | ||
@@ -143,0 +144,0 @@ } |
@@ -113,3 +113,3 @@ 'use strict'; | ||
it('SchemaMixed.doValidateSync skip instrumentation if there is no assess scope', function () { | ||
it('SchemaMixed.doValidateSync skip instrumentation if there is no assess policy in request scope', function () { | ||
simulateRequestScope(function () { | ||
@@ -122,3 +122,3 @@ const str = trackString('error'); | ||
expect(strInfo).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -152,3 +152,2 @@ | ||
value: 'foo', | ||
}); | ||
@@ -361,3 +360,3 @@ }); | ||
it('SchemaMixed.doValidate skip instrumentation if there is no assess scope', function () { | ||
it('SchemaMixed.doValidate skip instrumentation if there is no assess policy in request scope', function () { | ||
simulateRequestScope(function () { | ||
@@ -370,3 +369,3 @@ const str = trackString('foo'); | ||
expect(strInfo).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -373,0 +372,0 @@ |
@@ -18,3 +18,3 @@ /* | ||
const { DataflowTag, StringPrototypeSubstring } = require('@contrast/common'); | ||
const { DataflowTag, primordials: { StringPrototypeSubstring } } = require('@contrast/common'); | ||
const { patchType } = require('../../common'); | ||
@@ -32,2 +32,3 @@ const { userDefinedType } = require('./common'); | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -75,5 +76,3 @@ dataflow: { tracker }, | ||
const [value, cb] = data.args; | ||
if (!value || typeof cb !== 'function' || !sources.getStore()?.assess) { | ||
return; | ||
} | ||
if (!value || typeof cb !== 'function' || !getSourceContext()) return; | ||
@@ -80,0 +79,0 @@ const hasCustomValidator = data.obj.validators.some( |
@@ -18,8 +18,5 @@ /* | ||
const { | ||
DataflowTag: { HTML_ENCODED } | ||
} = require('@contrast/common'); | ||
const { | ||
createEscapeTagRanges | ||
} = require('../../tag-utils'); | ||
const { DataflowTag: { HTML_ENCODED } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createEscapeTagRanges } = require('../../tag-utils'); | ||
const { patchType } = require('../common'); | ||
@@ -29,6 +26,6 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -49,3 +46,3 @@ dataflow: { tracker } | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -52,0 +49,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -30,3 +30,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -36,3 +36,3 @@ const value = trackString('<script>alert("hello");</script>'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -39,0 +39,0 @@ |
@@ -18,8 +18,5 @@ /* | ||
const { | ||
DataflowTag: { SQL_ENCODED } | ||
} = require('@contrast/common'); | ||
const { | ||
createFullLengthCopyTags | ||
} = require('../../tag-utils'); | ||
const { DataflowTag: { SQL_ENCODED } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createFullLengthCopyTags } = require('../../tag-utils'); | ||
const { patchType, createModuleLabel } = require('../common'); | ||
@@ -29,6 +26,6 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -42,3 +39,3 @@ dataflow: { tracker } | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -45,0 +42,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -55,3 +55,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -62,3 +62,3 @@ const value = trackString('foo'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -65,0 +65,0 @@ |
@@ -19,2 +19,3 @@ /* | ||
const { isString } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { patchType } = require('../common'); | ||
@@ -25,5 +26,5 @@ | ||
logger, | ||
scopes: { instrumentation, sources }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
dataflow: { tracker } | ||
@@ -46,4 +47,3 @@ } | ||
!isString(value) || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() || | ||
!getSourceContext(PROPAGATOR) || | ||
!tracker.getData(value) | ||
@@ -50,0 +50,0 @@ ) return; |
@@ -17,8 +17,7 @@ /* | ||
'use strict'; | ||
const { isString, ArrayPrototypeJoin } = require('@contrast/common'); | ||
const { isString, primordials: { ArrayPrototypeJoin } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
const { | ||
excludeExtensionDotFromTags, | ||
createBasenameTagsInResult, | ||
} = require('./common'); | ||
const { excludeExtensionDotFromTags, createBasenameTagsInResult } = require('./common'); | ||
@@ -29,4 +28,4 @@ module.exports = function(core) { | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -48,9 +47,5 @@ dataflow: { tracker }, | ||
const { args: origArgs, result, name, hooked, orig } = data; | ||
if ( | ||
!result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
const [pathStr, suffixStr] = origArgs; | ||
@@ -57,0 +52,0 @@ |
@@ -47,3 +47,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -54,3 +54,3 @@ const myPath = trackString('/script.sh'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -57,0 +57,0 @@ |
@@ -18,3 +18,3 @@ /* | ||
const { StringPrototypeMatchAll, StringPrototypeSubstring, StringPrototypeReplace } = require('@contrast/common'); | ||
const { primordials: { StringPrototypeMatchAll, StringPrototypeSubstring, StringPrototypeReplace } } = require('@contrast/common'); | ||
const { | ||
@@ -90,3 +90,3 @@ createSubsetTags, | ||
['.', '..'].includes(segment) && | ||
result.substring(lastIndex - segment.length, lastIndex + 1) !== segment | ||
StringPrototypeSubstring.call(result, lastIndex - segment.length, lastIndex + 1) !== segment | ||
) | ||
@@ -93,0 +93,0 @@ continue; |
@@ -18,6 +18,5 @@ /* | ||
const { isString } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
const { | ||
createArgTagsInResult | ||
} = require('./common'); | ||
const { createArgTagsInResult } = require('./common'); | ||
@@ -28,4 +27,4 @@ module.exports = function(core) { | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -47,9 +46,5 @@ dataflow: { tracker }, | ||
const { args, result, name, hooked, orig } = data; | ||
if ( | ||
!result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
const pathStr = args[0]; | ||
@@ -56,0 +51,0 @@ |
@@ -44,3 +44,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -52,3 +52,3 @@ const myPath = trackString('/path'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -55,0 +55,0 @@ |
@@ -17,8 +17,8 @@ /* | ||
'use strict'; | ||
const { patchType } = require('../../common'); | ||
const { isString } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createSubsetTags } = require('../../../tag-utils'); | ||
const { | ||
excludeExtensionDotFromTags | ||
} = require('./common'); | ||
const { patchType } = require('../../common'); | ||
const { excludeExtensionDotFromTags } = require('./common'); | ||
@@ -29,4 +29,4 @@ module.exports = function(core) { | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -48,8 +48,3 @@ dataflow: { tracker }, | ||
const { args, result, name, hooked, orig } = data; | ||
if ( | ||
!result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
@@ -56,0 +51,0 @@ const pathStr = args[0]; |
@@ -39,3 +39,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -47,3 +47,3 @@ const myPath = trackString('/path/to/file.txt'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -50,0 +50,0 @@ |
@@ -17,9 +17,8 @@ /* | ||
'use strict'; | ||
const { ArrayPrototypeJoin, isString } = require('@contrast/common'); | ||
const { primordials: { ArrayPrototypeJoin }, isString } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createMergedTags, getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
const { patchType } = require('../../common'); | ||
const { createMergedTags, getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
const { | ||
createArgTagsInResult, | ||
excludeExtensionDotFromTags | ||
} = require('./common'); | ||
const { createArgTagsInResult, excludeExtensionDotFromTags } = require('./common'); | ||
@@ -30,4 +29,4 @@ module.exports = function(core) { | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -49,8 +48,3 @@ dataflow: { tracker }, | ||
const { args, result, name: patchName, hooked, orig } = data; | ||
if ( | ||
!result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
@@ -57,0 +51,0 @@ const pathProps = []; |
@@ -42,3 +42,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -53,3 +53,3 @@ const dir = trackString('/path/to'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -56,0 +56,0 @@ |
@@ -17,9 +17,8 @@ /* | ||
'use strict'; | ||
const { isString, ArrayPrototypeJoin } = require('@contrast/common'); | ||
const { isString, primordials: { ArrayPrototypeJoin } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createMergedTags } = require('../../../tag-utils'); | ||
const { patchType } = require('../../common'); | ||
const { | ||
createArgTagsInResult, | ||
excludeExtensionDotFromTags, | ||
} = require('./common'); | ||
const { createArgTagsInResult, excludeExtensionDotFromTags } = require('./common'); | ||
@@ -30,4 +29,4 @@ module.exports = function(core) { | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -51,9 +50,5 @@ dataflow: { tracker }, | ||
const { args: origArgs, result, hooked, orig } = data; | ||
if ( | ||
!result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
const pathSegments = [...origArgs].reverse(); | ||
@@ -60,0 +55,0 @@ const args = []; |
@@ -48,3 +48,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -58,3 +58,3 @@ const seg1 = trackString('/path'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -61,0 +61,0 @@ |
@@ -18,7 +18,5 @@ /* | ||
const { isString } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
const { | ||
createArgTagsInResult, | ||
excludeExtensionDotFromTags, | ||
} = require('./common'); | ||
const { createArgTagsInResult, excludeExtensionDotFromTags, } = require('./common'); | ||
@@ -29,4 +27,4 @@ module.exports = function(core) { | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -48,8 +46,3 @@ dataflow: { tracker }, | ||
const { args, result, name, hooked, orig } = data; | ||
if ( | ||
!result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
@@ -56,0 +49,0 @@ const pathStr = args[0]; |
@@ -45,3 +45,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -53,3 +53,3 @@ const myPath = trackString('/path'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -56,0 +56,0 @@ |
@@ -18,2 +18,3 @@ /* | ||
const { isString } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createSubsetTags } = require('../../../tag-utils'); | ||
@@ -27,4 +28,4 @@ const { patchType } = require('../../common'); | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -47,11 +48,5 @@ eventFactory: { createPropagationEvent }, | ||
const { args, result, name: patchName, hooked, orig } = data; | ||
if ( | ||
!result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
const [path] = args; | ||
if (!path || !isString(path)) return; | ||
@@ -58,0 +53,0 @@ |
@@ -43,3 +43,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -52,3 +52,3 @@ const str = trackString('/path/to/file.txt'); | ||
}); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -55,0 +55,0 @@ |
@@ -17,8 +17,7 @@ /* | ||
'use strict'; | ||
const { isString } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
const { | ||
createArgTagsInResult, | ||
excludeExtensionDotFromTags, | ||
} = require('./common'); | ||
const { createArgTagsInResult, excludeExtensionDotFromTags, } = require('./common'); | ||
@@ -29,4 +28,4 @@ module.exports = function(core) { | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -48,8 +47,3 @@ dataflow: { tracker }, | ||
const { args, result, name, hooked, orig } = data; | ||
if ( | ||
!result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
@@ -56,0 +50,0 @@ const [fromStr, toStr] = args; |
@@ -44,3 +44,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -52,3 +52,3 @@ const myPath = trackString('/path'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -55,0 +55,0 @@ |
@@ -17,8 +17,7 @@ /* | ||
'use strict'; | ||
const { isString } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
const { | ||
createArgTagsInResult, | ||
excludeExtensionDotFromTags | ||
} = require('./common'); | ||
const { createArgTagsInResult, excludeExtensionDotFromTags } = require('./common'); | ||
@@ -29,4 +28,4 @@ module.exports = function(core) { | ||
patcher, | ||
scopes: { sources, instrumentation }, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -47,8 +46,3 @@ dataflow: { tracker }, | ||
const { args, result, name, hooked, orig } = data; | ||
if ( | ||
!result || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
@@ -55,0 +49,0 @@ const pathStr = args[0]; |
@@ -38,3 +38,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -46,3 +46,3 @@ const myPath = trackString('C:\\path\\to\\file.txt'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -49,0 +49,0 @@ |
@@ -18,8 +18,5 @@ /* | ||
const { | ||
DataflowTag: { WEAK_URL_ENCODED } | ||
} = require('@contrast/common'); | ||
const { | ||
createFullLengthCopyTags | ||
} = require('../../tag-utils'); | ||
const { DataflowTag: { WEAK_URL_ENCODED } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createFullLengthCopyTags } = require('../../tag-utils'); | ||
const { patchType, createModuleLabel } = require('../common'); | ||
@@ -29,6 +26,6 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -49,3 +46,3 @@ dataflow: { tracker } | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -52,0 +49,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -57,3 +57,3 @@ 'use strict'; | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -60,0 +60,0 @@ |
@@ -17,2 +17,3 @@ /* | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
@@ -26,4 +27,8 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, logger, rewriter, depHooks, | ||
patcher, | ||
logger, | ||
rewriter, | ||
depHooks, | ||
scopes: { instrumentation }, | ||
assess: { getSourceContext }, | ||
} = core; | ||
@@ -39,3 +44,3 @@ | ||
pre(data) { | ||
if (!sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!getSourceContext(PROPAGATOR)) return; | ||
@@ -42,0 +47,0 @@ const opts = data.args[1] || {}; |
@@ -18,2 +18,3 @@ /* | ||
const { DataflowTag: { URL_ENCODED } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createFullLengthCopyTags } = require('../../../tag-utils'); | ||
@@ -25,2 +26,3 @@ const { patchType } = require('../../common'); | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -32,3 +34,2 @@ eventFactory: { createPropagationEvent }, | ||
patcher, | ||
scopes, | ||
} = core; | ||
@@ -49,4 +50,3 @@ | ||
const sourceContext = scopes.sources.getStore()?.assess; | ||
if (!sourceContext) return; | ||
if (!getSourceContext(PROPAGATOR)) return; | ||
@@ -53,0 +53,0 @@ let tags; |
@@ -21,4 +21,5 @@ /* | ||
DataflowTag: { URL_ENCODED }, | ||
ArrayPrototypeJoin, | ||
primordials: { ArrayPrototypeJoin }, | ||
} = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createSubsetTags, createAppendTags, getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
@@ -29,6 +30,6 @@ const { patchType } = require('../../common'); | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -110,12 +111,7 @@ dataflow: { tracker } | ||
pre(data) { | ||
if (!sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
const input = data.args[0]; | ||
if (!input) { | ||
return; | ||
} | ||
const trackingData = tracker.getData(input); | ||
if (!trackingData) { | ||
return; | ||
} | ||
if (!data.args[0] || !getSourceContext(PROPAGATOR)) return; | ||
const trackingData = tracker.getData(data.args[0]); | ||
if (!trackingData) return; | ||
data.idx = 0; | ||
@@ -122,0 +118,0 @@ data.origArgs = [...data.args]; |
@@ -19,2 +19,3 @@ /* | ||
const { isString } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const utils = require('../../../tag-utils'); | ||
@@ -28,2 +29,3 @@ const { patchType } = require('../../common'); | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -35,3 +37,2 @@ dataflow: { tracker }, | ||
patcher, | ||
scopes, | ||
} = core; | ||
@@ -43,4 +44,3 @@ | ||
function pre(data) { | ||
const sourceContext = scopes.sources.getStore()?.assess; | ||
if (!sourceContext) return; | ||
if (!getSourceContext(PROPAGATOR)) return; | ||
@@ -47,0 +47,0 @@ const [input] = data.args; |
@@ -17,2 +17,4 @@ /* | ||
'use strict'; | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createSubsetTags, getAdjustedUntrackedValue } = require('../../tag-utils'); | ||
@@ -23,5 +25,5 @@ const { patchType } = require('../common'); | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -88,4 +90,3 @@ dataflow: { tracker }, | ||
!result?.length || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
!getSourceContext(PROPAGATOR) | ||
) | ||
@@ -92,0 +93,0 @@ return; |
@@ -107,3 +107,3 @@ 'use strict'; | ||
const re = /^\/?$/i; | ||
// 0123456789*1234567 | ||
// eslint-disable-next-line | ||
const extern = trackString(''); | ||
@@ -113,2 +113,3 @@ | ||
while ((ret = re.exec(''))) { | ||
// eslint-disable-next-line | ||
const matchInfo = tracker.getData(ret[0]); | ||
@@ -158,2 +159,4 @@ // console.log(re.lastIndex, ret.index, ret.indices); | ||
simulateRequestScope(() => { | ||
core.scopes.sources.getStore().assess.propagationEventsCount = 498; | ||
const re = /foo(?<bar>bar)/; | ||
@@ -179,3 +182,3 @@ const extern = trackString('foobar'); | ||
expect(barGroupInfo).to.be.null; | ||
}, { assess: { propagationEventsCount: 498 } }); | ||
}); | ||
}); | ||
@@ -258,3 +261,2 @@ | ||
expect(ret).to.deep.equal([ | ||
@@ -261,0 +263,0 @@ 'Quick Brown Fox Jumps Over The Lazy Black', |
@@ -18,9 +18,9 @@ /* | ||
const { patchType } = require('../common'); | ||
const { StringPrototypeSlice } = require('@contrast/common'); | ||
const { primordials: { StringPrototypeSlice } } = require('@contrast/common'); | ||
module.exports = function (core) { | ||
const { | ||
scopes: { sources, instrumentation }, | ||
depHooks, | ||
patcher | ||
patcher, | ||
assess: { getSourceContext } | ||
} = core; | ||
@@ -41,7 +41,4 @@ | ||
const { args } = data; | ||
if (!getSourceContext()) return; | ||
if (!sources.getStore()?.assess || instrumentation.isLocked()) { | ||
return; | ||
} | ||
const untrackedPath = StringPrototypeSlice.call(` ${args[0]}`, 1); | ||
@@ -56,5 +53,3 @@ args[0] = untrackedPath; | ||
send.install = function () { | ||
depHooks.resolve({ name: 'send' }, (sendModule) => | ||
patchSendModule(sendModule) | ||
); | ||
depHooks.resolve({ name: 'send' }, patchSendModule); | ||
}; | ||
@@ -61,0 +56,0 @@ |
@@ -17,5 +17,3 @@ /* | ||
const { | ||
DataflowTag: { SQL_ENCODED } | ||
} = require('@contrast/common'); | ||
const { DataflowTag: { SQL_ENCODED } } = require('@contrast/common'); | ||
const { patchType } = require('../../common'); | ||
@@ -37,2 +35,3 @@ | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -58,3 +57,3 @@ dataflow: { tracker } | ||
const strInfo = tracker.getData(data.result); | ||
if (!strInfo) return; | ||
if (!strInfo || !getSourceContext()) return; | ||
@@ -61,0 +60,0 @@ const { value } = strInfo; |
@@ -20,2 +20,3 @@ /* | ||
isString, | ||
primordials: { StringPrototypeMatchAll }, | ||
DataflowTag: { SQL_ENCODED }, | ||
@@ -27,6 +28,6 @@ } = require('@contrast/common'); | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -50,3 +51,3 @@ dataflow: { tracker }, | ||
const regex = /:(\w+)(?=[\s,;)]|$)/g; | ||
const matches = str.matchAll(regex); | ||
const matches = StringPrototypeMatchAll.call(str, regex); | ||
@@ -74,4 +75,3 @@ return Array.from(matches, (match) => ({ [match[1]]: match.index })); | ||
!isString(args[0]) || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
!getSourceContext() | ||
) return; | ||
@@ -130,6 +130,4 @@ | ||
!isString(args[0]) || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
!getSourceContext() | ||
) return; | ||
@@ -225,6 +223,4 @@ const resultInfo = tracker.getData(result); | ||
!isString(args[0]) || | ||
!sources.getStore()?.assess || | ||
instrumentation.isLocked() | ||
) | ||
return; | ||
!getSourceContext() | ||
) return; | ||
@@ -231,0 +227,0 @@ const resultInfo = tracker.getData(result); |
@@ -43,3 +43,2 @@ 'use strict'; | ||
afterEach(function () { | ||
@@ -100,3 +99,2 @@ core.assess.dataflow.propagation.stringInstrumentation.uninstall(); | ||
simulateRequestScope(function () { | ||
const notTrackedResult = mockSequelizeSqlString[method](...notTrackedArgs); | ||
@@ -114,17 +112,8 @@ const notTrackedStrInfo = tracker.getData(notTrackedResult); | ||
if (!onlySanitizeCheck) { | ||
it('will not sanitize if there is no assess context', function () { | ||
it('will not sanitize if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
const result = mockSequelizeSqlString[method](...args.map(a => a())); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
it('will not sanitize if there instrumentation is locked', function () { | ||
simulateRequestScope(function () { | ||
core.scopes.instrumentation.run({ lock: true }, function () { | ||
const result = mockSequelizeSqlString[method](...args.map(a => a())); | ||
expect(tracker.getData(result)?.tags || {}).to.not.haveOwnProperty(SQL_ENCODED); | ||
}); | ||
}); | ||
}); | ||
} | ||
@@ -131,0 +120,0 @@ }); |
@@ -18,5 +18,3 @@ /* | ||
const { | ||
DataflowTag: { SQL_ENCODED } | ||
} = require('@contrast/common'); | ||
const { DataflowTag: { SQL_ENCODED } } = require('@contrast/common'); | ||
const { patchType, createModuleLabel } = require('../common'); | ||
@@ -26,6 +24,6 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -46,3 +44,3 @@ dataflow: { tracker } | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext()) return; | ||
@@ -49,0 +47,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -83,3 +83,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -89,3 +89,3 @@ const value = trackString('foo'); | ||
expect(tracker.getData(result.strings.toString())).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -92,0 +92,0 @@ |
@@ -18,3 +18,3 @@ /* | ||
const { ArrayPrototypeJoin } = require('@contrast/common'); | ||
const { primordials: { ArrayPrototypeJoin } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
@@ -41,2 +41,3 @@ const { createAppendTags, getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
patchType, | ||
usePerf: true, | ||
post(data) { | ||
@@ -43,0 +44,0 @@ const { obj, result, hooked, orig } = data; |
@@ -9,2 +9,3 @@ 'use strict'; | ||
let core, trackString, simulateRequestScope, tracker; | ||
const allPatcher = new Map(); | ||
@@ -27,2 +28,14 @@ beforeEach(function () { | ||
// eslint-disable-next-line mocha/no-sibling-hooks | ||
afterEach(function() { | ||
core.Perf.fromAllToMap('patcher', allPatcher); | ||
}); | ||
after(function() { | ||
const stats = core.Perf.getStats(allPatcher); | ||
for (const [key, { n, totalMicros, mean }] of stats.entries()) { | ||
console.log(key, n, totalMicros, 'nsec', mean, 'mean'); | ||
} | ||
}); | ||
[ | ||
@@ -117,3 +130,3 @@ { | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -123,3 +136,3 @@ const value = trackString('foo'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -126,0 +139,0 @@ |
@@ -18,2 +18,3 @@ /* | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
@@ -23,5 +24,5 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -40,5 +41,6 @@ dataflow: { tracker } | ||
patchType, | ||
usePerf: true, | ||
post(data) { | ||
const { obj, result, hooked, orig } = data; | ||
if (!result || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !getSourceContext(PROPAGATOR)) return; | ||
@@ -45,0 +47,0 @@ const objInfo = tracker.getData(obj); |
@@ -9,2 +9,3 @@ 'use strict'; | ||
let core, trackString, simulateRequestScope, tracker; | ||
const allPatcher = new Map(); | ||
@@ -27,2 +28,14 @@ beforeEach(function () { | ||
// eslint-disable-next-line mocha/no-sibling-hooks | ||
afterEach(function() { | ||
core.Perf.fromAllToMap('patcher', allPatcher); | ||
}); | ||
after(function() { | ||
const stats = core.Perf.getStats(allPatcher); | ||
for (const [key, { n, totalMicros, mean }] of stats.entries()) { | ||
console.log(key, n, totalMicros, 'nsec', mean, 'mean'); | ||
} | ||
}); | ||
['toLowerCase', 'toUpperCase', 'toLocaleLowerCase', 'toLocaleUpperCase'].forEach((method) => { | ||
@@ -46,3 +59,3 @@ it(method, function () { | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -52,3 +65,3 @@ const value = trackString('foo'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -55,0 +68,0 @@ |
@@ -17,3 +17,2 @@ /* | ||
'use strict'; | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
@@ -66,2 +65,3 @@ const { createAppendTags } = require('../../../tag-utils'); | ||
patchType, | ||
usePost: true, | ||
post(data) { | ||
@@ -68,0 +68,0 @@ const { args, obj, result, hooked, orig } = data; |
@@ -9,2 +9,3 @@ 'use strict'; | ||
let core, trackString, simulateRequestScope, tracker; | ||
const allPatcher = new Map(); | ||
@@ -27,2 +28,14 @@ beforeEach(function () { | ||
// eslint-disable-next-line mocha/no-sibling-hooks | ||
afterEach(function() { | ||
core.Perf.fromAllToMap('patcher', allPatcher); | ||
}); | ||
after(function() { | ||
const stats = core.Perf.getStats(allPatcher); | ||
for (const [key, { n, totalMicros, mean }] of stats.entries()) { | ||
console.log(key, n, totalMicros, 'nsec', mean, 'mean'); | ||
} | ||
}); | ||
[ | ||
@@ -149,3 +162,3 @@ { | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -155,3 +168,3 @@ const value = trackString('foo'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -158,0 +171,0 @@ |
@@ -18,4 +18,3 @@ /* | ||
const { callChildComponentMethodsSync } = require('@contrast/common'); | ||
const { StringPrototypeSplit } = require('@contrast/common'); | ||
const { callChildComponentMethodsSync, primordials: { StringPrototypeSplit } } = require('@contrast/common'); | ||
const { getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
@@ -50,2 +49,3 @@ | ||
patchType, | ||
usePerf: true, | ||
pre(data) { | ||
@@ -52,0 +52,0 @@ const { args: origArgs, hooked, orig } = data; |
@@ -39,3 +39,3 @@ /* | ||
match, | ||
untrackedResult, | ||
//untrackedResult, | ||
metadata, | ||
@@ -79,2 +79,3 @@ }) { | ||
patchType, | ||
usePerf: true, | ||
around(origFn, data) { | ||
@@ -81,0 +82,0 @@ const { args, obj, hooked, orig } = data; |
@@ -20,2 +20,3 @@ 'use strict'; | ||
let core, simulateRequestScope, trackString, tracker; | ||
const allPatcher = new Map(); | ||
@@ -42,2 +43,14 @@ beforeEach(function () { | ||
// eslint-disable-next-line mocha/no-sibling-hooks | ||
afterEach(function() { | ||
core.Perf.fromAllToMap('patcher', allPatcher); | ||
}); | ||
after(function() { | ||
const stats = core.Perf.getStats(allPatcher); | ||
for (const [key, { n, totalMicros, mean }] of stats.entries()) { | ||
console.log(key, n, totalMicros, 'nsec', mean, 'mean'); | ||
} | ||
}); | ||
describe('base cases', function () { | ||
@@ -44,0 +57,0 @@ [ |
@@ -17,11 +17,14 @@ /* | ||
'use strict'; | ||
const { ArrayPrototypeJoin } = require('@contrast/common'); | ||
const { primordials: { ArrayPrototypeJoin } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createSubsetTags, getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
const { patchType } = require('../../common'); | ||
const { createSubsetTags, getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
module.exports = function(core) { | ||
const { | ||
scopes: { sources, instrumentation }, | ||
scopes, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -80,2 +83,3 @@ dataflow: { | ||
patchType, | ||
usePerf: true, | ||
around(origFn, data) { | ||
@@ -86,9 +90,6 @@ const { args, obj } = data; | ||
!args.length || | ||
!sources.getStore()?.assess || | ||
typeof obj !== 'string' || | ||
instrumentation.isLocked() || | ||
(args.length === 1 && !args[0]) | ||
) | ||
return origFn(); | ||
(args.length === 1 && !args[0]) || | ||
!getSourceContext(PROPAGATOR) | ||
) return origFn(); | ||
const objInfo = tracker.getData(obj); | ||
@@ -114,3 +115,3 @@ | ||
const result = (data.result = core.scopes.instrumentation.run( | ||
const result = (data.result = scopes.instrumentation.run( | ||
{ lock: true }, | ||
@@ -117,0 +118,0 @@ () => origFn() |
@@ -10,2 +10,3 @@ 'use strict'; | ||
let core, simulateRequestScope, trackString, tracker; | ||
const allPatcher = new Map(); | ||
@@ -32,2 +33,14 @@ beforeEach(function () { | ||
// eslint-disable-next-line mocha/no-sibling-hooks | ||
afterEach(function() { | ||
core.Perf.fromAllToMap('patcher', allPatcher); | ||
}); | ||
after(function() { | ||
const stats = core.Perf.getStats(allPatcher); | ||
for (const [key, { n, totalMicros, mean }] of stats.entries()) { | ||
console.log(key, n, totalMicros, 'nsec', mean, 'mean'); | ||
} | ||
}); | ||
describe('base cases', function () { | ||
@@ -34,0 +47,0 @@ [ |
@@ -20,5 +20,9 @@ /* | ||
DataflowTag: { UNTRUSTED }, | ||
StringPrototypeMatch, | ||
ArrayPrototypeJoin, | ||
StringPrototypeSubstring, | ||
primordials: { | ||
StringPrototypeMatch, | ||
ArrayPrototypeJoin, | ||
ArrayPrototypeSlice, | ||
StringPrototypeSubstring, | ||
StringPrototypeReplace | ||
} | ||
} = require('@contrast/common'); | ||
@@ -49,3 +53,3 @@ const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const hasNamedGroup = typeof lastEl === 'object'; | ||
const captureGroups = args.slice(1, hasNamedGroup ? -3 : -2); | ||
const captureGroups = ArrayPrototypeSlice.call(args, 1, hasNamedGroup ? -3 : -2); | ||
const matchIdx = args[hasNamedGroup ? len - 3 : len - 2]; | ||
@@ -57,4 +61,5 @@ const str = hasNamedGroup ? args[len - 2] : lastEl; | ||
// these functions specifically use the patched versions of Substring so that | ||
// the tags are propagated. | ||
function replaceSpecialCharacters(replacement, { captureGroups, match, str, namedGroups }, replacementType) { | ||
const origReplace = patcher.unwrap(String.prototype.replace); | ||
let ret = replacement; | ||
@@ -85,3 +90,3 @@ [ | ||
} else { | ||
ret = origReplace.call(ret, regex, replace); | ||
ret = StringPrototypeReplace.call(ret, regex, replace); | ||
} | ||
@@ -91,7 +96,7 @@ } | ||
const numberedGroupMatches = replacementType !== 'function' && replacement.match(/\$[1-9][0-9]|\$[1-9]/g); | ||
const numberedGroupMatches = replacementType !== 'function' && StringPrototypeMatch.call(replacement, /\$[1-9][0-9]|\$[1-9]/g); | ||
if (numberedGroupMatches) { | ||
numberedGroupMatches.forEach((numberedGroup) => { | ||
const group = Number(StringPrototypeSubstring.call(numberedGroup, 1)); | ||
ret = origReplace.call(ret, numberedGroup, captureGroups[group - 1] || ''); | ||
ret = StringPrototypeReplace.call(ret, numberedGroup, captureGroups[group - 1] || ''); | ||
}); | ||
@@ -102,3 +107,3 @@ } | ||
for (const name in namedGroups) { | ||
ret = origReplace.call(ret, `$${name}`, namedGroups[name]); | ||
ret = StringPrototypeReplace.call(ret, `$${name}`, namedGroups[name]); | ||
} | ||
@@ -154,2 +159,3 @@ } | ||
patchType, | ||
usePerf: true, | ||
pre(data) { | ||
@@ -156,0 +162,0 @@ if (!getSourceContext(PROPAGATOR)) return; |
@@ -9,2 +9,3 @@ 'use strict'; | ||
let core, simulateRequestScope, trackString, tracker; | ||
const allPatcher = new Map(); | ||
@@ -28,2 +29,14 @@ beforeEach(function () { | ||
// eslint-disable-next-line mocha/no-sibling-hooks | ||
afterEach(function() { | ||
core.Perf.fromAllToMap('patcher', allPatcher); | ||
}); | ||
after(function() { | ||
const stats = core.Perf.getStats(allPatcher); | ||
for (const [key, { n, totalMicros, mean }] of stats.entries()) { | ||
console.log(key, n, totalMicros, 'nsec', mean, 'mean'); | ||
} | ||
}); | ||
['string', 'function'].forEach((replacerType) => { | ||
@@ -30,0 +43,0 @@ function getReplacement(replacerType, replacement) { |
@@ -16,3 +16,3 @@ /* | ||
'use strict'; | ||
const { ArrayPrototypeJoin } = require('@contrast/common'); | ||
const { primordials: { ArrayPrototypeJoin } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
@@ -58,2 +58,3 @@ const { createSubsetTags, getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
patchType, | ||
usePerf: true, | ||
post(data) { | ||
@@ -60,0 +61,0 @@ const { name, args: origArgs, obj, result, hooked, orig } = data; |
@@ -9,2 +9,3 @@ 'use strict'; | ||
let core, tracker, trackString, simulateRequestScope; | ||
const allPatcher = new Map(); | ||
@@ -27,2 +28,14 @@ beforeEach(function () { | ||
// eslint-disable-next-line mocha/no-sibling-hooks | ||
afterEach(function() { | ||
core.Perf.fromAllToMap('patcher', allPatcher); | ||
}); | ||
after(function() { | ||
const stats = core.Perf.getStats(allPatcher); | ||
for (const [key, { n, totalMicros, mean }] of stats.entries()) { | ||
console.log(key, n, totalMicros, 'nsec', mean, 'mean'); | ||
} | ||
}); | ||
[ | ||
@@ -29,0 +42,0 @@ { |
@@ -18,3 +18,3 @@ /* | ||
const { ArrayPrototypeJoin } = require('@contrast/common'); | ||
const { primordials: { ArrayPrototypeJoin } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
@@ -41,2 +41,3 @@ const { createSubsetTags, getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
patchType, | ||
usePerf: true, | ||
post(data) { | ||
@@ -43,0 +44,0 @@ const { name, args: origArgs, obj, result, hooked, orig } = data; |
@@ -9,2 +9,3 @@ 'use strict'; | ||
let core, simulateRequestScope, trackString, tracker; | ||
const allPatcher = new Map(); | ||
@@ -31,2 +32,14 @@ beforeEach(function () { | ||
// eslint-disable-next-line mocha/no-sibling-hooks | ||
afterEach(function() { | ||
core.Perf.fromAllToMap('patcher', allPatcher); | ||
}); | ||
after(function() { | ||
const stats = core.Perf.getStats(allPatcher); | ||
for (const [key, { n, totalMicros, mean }] of stats.entries()) { | ||
console.log(key, n, totalMicros, 'nsec', mean, 'mean'); | ||
} | ||
}); | ||
describe('base cases', function () { | ||
@@ -33,0 +46,0 @@ it('normal split on non-tracked string', function () { |
@@ -18,3 +18,3 @@ /* | ||
const { ArrayPrototypeJoin } = require('@contrast/common'); | ||
const { primordials: { ArrayPrototypeJoin } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
@@ -66,2 +66,3 @@ const { createSubsetTags, getAdjustedUntrackedValue } = require('../../../tag-utils'); | ||
patchType, | ||
usePerf: true, | ||
post(data) { | ||
@@ -68,0 +69,0 @@ const { obj, args: origArgs, result, name, hooked, orig } = data; |
@@ -9,2 +9,3 @@ 'use strict'; | ||
let core, tracker, trackString, simulateRequestScope; | ||
const allPatcher = new Map(); | ||
@@ -27,2 +28,14 @@ beforeEach(function () { | ||
// eslint-disable-next-line mocha/no-sibling-hooks | ||
afterEach(function() { | ||
core.Perf.fromAllToMap('patcher', allPatcher); | ||
}); | ||
after(function() { | ||
const stats = core.Perf.getStats(allPatcher); | ||
for (const [key, { n, totalMicros, mean }] of stats.entries()) { | ||
console.log(key, n, totalMicros, 'nsec', mean, 'mean'); | ||
} | ||
}); | ||
[ | ||
@@ -29,0 +42,0 @@ { |
@@ -95,2 +95,3 @@ /* | ||
post: createPostHook('trim'), | ||
usePerf: true, | ||
}); | ||
@@ -101,3 +102,4 @@ | ||
patchType, | ||
post: createPostHook('trimStart') | ||
post: createPostHook('trimStart'), | ||
usePerf: true, | ||
}); | ||
@@ -109,2 +111,3 @@ | ||
post: createPostHook('trimEnd', 0), | ||
usePerf: true, | ||
}); | ||
@@ -111,0 +114,0 @@ }, |
@@ -9,2 +9,3 @@ 'use strict'; | ||
let core, tracker, trackString, simulateRequestScope; | ||
const allPatcher = new Map(); | ||
@@ -27,2 +28,14 @@ beforeEach(function () { | ||
// eslint-disable-next-line mocha/no-sibling-hooks | ||
afterEach(function() { | ||
core.Perf.fromAllToMap('patcher', allPatcher); | ||
}); | ||
after(function() { | ||
const stats = core.Perf.getStats(allPatcher); | ||
for (const [key, { n, totalMicros, mean }] of stats.entries()) { | ||
console.log(key, n, totalMicros, 'nsec', mean, 'mean'); | ||
} | ||
}); | ||
[ | ||
@@ -29,0 +42,0 @@ { |
@@ -18,8 +18,5 @@ /* | ||
const { | ||
DataflowTag: { WEAK_URL_ENCODED } | ||
} = require('@contrast/common'); | ||
const { | ||
createFullLengthCopyTags | ||
} = require('../../tag-utils'); | ||
const { DataflowTag: { WEAK_URL_ENCODED } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createFullLengthCopyTags } = require('../../tag-utils'); | ||
const { patchType, createObjectLabel } = require('../common'); | ||
@@ -29,5 +26,5 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -47,3 +44,3 @@ dataflow: { tracker } | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -50,0 +47,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -61,3 +61,3 @@ | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -67,3 +67,3 @@ const value = trackString('%3Ftest%3Dstr'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -70,0 +70,0 @@ |
@@ -18,5 +18,4 @@ /* | ||
const { | ||
createFullLengthCopyTags | ||
} = require('../../../tag-utils'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createFullLengthCopyTags } = require('../../../tag-utils'); | ||
const { patchType, createModuleLabel } = require('../../common'); | ||
@@ -26,6 +25,6 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -47,3 +46,3 @@ dataflow: { tracker } | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -50,0 +49,0 @@ const argInfo = tracker.getData(args[0]); |
@@ -46,3 +46,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess store in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -52,3 +52,3 @@ const value = trackString('foo'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -55,0 +55,0 @@ |
@@ -18,2 +18,3 @@ /* | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
@@ -23,6 +24,6 @@ | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -93,3 +94,3 @@ eventFactory: { createPropagationEvent }, | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -96,0 +97,0 @@ const [url, parseQueryString] = args; |
@@ -70,3 +70,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -78,3 +78,3 @@ const value = trackString('foo'); | ||
}); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -81,0 +81,0 @@ |
@@ -18,9 +18,9 @@ /* | ||
const { isString, primordials: { StringPrototypeConcat, StringPrototypeReplaceAll } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { createAppendTags } = require('../../../tag-utils'); | ||
const { patchType } = require('../../common'); | ||
const { isString, StringPrototypeConcat, StringPrototypeReplaceAll } = require('@contrast/common'); | ||
const { createAppendTags } = require('../../../tag-utils'); | ||
module.exports = function(core) { | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
@@ -30,2 +30,3 @@ depHooks, | ||
inspect, // todo: remove | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -65,3 +66,2 @@ dataflow: { tracker } | ||
depHooks.resolve({ name: 'url' }, (url) => { | ||
const name = 'url.URLSearchParams'; | ||
@@ -74,3 +74,3 @@ | ||
const { args, obj, result } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -77,0 +77,0 @@ const [params] = args; |
@@ -43,3 +43,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -51,3 +51,3 @@ const value = trackString('foo'); | ||
expect(tracker.getData(input)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -54,0 +54,0 @@ |
@@ -18,10 +18,13 @@ /* | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
const { primordials: { StringPrototypeSplit } } = require('@contrast/common'); | ||
module.exports = function(core) { | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
inspect, // todo: remove | ||
@@ -95,3 +98,3 @@ eventFactory: { createPropagationEvent }, | ||
const { args, result } = data; | ||
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return; | ||
@@ -148,3 +151,3 @@ const [input, basename] = args; | ||
if (key === 'origin') { | ||
const [protocol, originWithoutProtocol] = part.split(new RegExp('(?<=//)')); | ||
const [protocol, originWithoutProtocol] = StringPrototypeSplit.call(part, new RegExp('(?<=//)')); | ||
const idx1 = href.indexOf(protocol); | ||
@@ -151,0 +154,0 @@ const idx2 = href.indexOf(originWithoutProtocol, idx - 1); |
@@ -70,3 +70,3 @@ 'use strict'; | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -78,3 +78,3 @@ const value = trackString('foo'); | ||
}); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -81,0 +81,0 @@ |
@@ -18,12 +18,13 @@ /* | ||
const { isString, primordials: { StringPrototypeMatch, StringPrototypeToLowerCase } } = require('@contrast/common'); | ||
const { InstrumentationType: { PROPAGATOR } } = require('../../../constants'); | ||
const { createAppendTags } = require('../../tag-utils'); | ||
const { patchType } = require('../common'); | ||
const { isString } = require('@contrast/common'); | ||
const { createAppendTags } = require('../../tag-utils'); | ||
module.exports = function(core) { | ||
const { | ||
scopes: { sources, instrumentation }, | ||
patcher, | ||
depHooks, | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -44,3 +45,3 @@ dataflow: { tracker } | ||
const { args, result, hooked, orig } = data; | ||
if (!result || !args[0] || !isString(args[0]) || !sources.getStore()?.assess || instrumentation.isLocked()) return; | ||
if (!result || !args[0] || !isString(args[0]) || !getSourceContext(PROPAGATOR)) return; | ||
@@ -51,3 +52,3 @@ let idx = 0; | ||
const eventArgs = []; | ||
const formatChars = args[0].includes('%') ? args[0].match(/[^%]+/g).map((x) => x[0]) : []; | ||
const formatChars = args[0].includes('%') ? StringPrototypeMatch.call(args[0], /[^%]+/g).map((x) => x[0]) : []; | ||
let i = 0; | ||
@@ -67,3 +68,3 @@ | ||
arg = JSON.stringify(arg); | ||
} else if (formatChar.toLowerCase() === 'o') { | ||
} else if (StringPrototypeToLowerCase.call(formatChar) === 'o') { | ||
// TO-DO: NODE-3235 | ||
@@ -70,0 +71,0 @@ } |
@@ -28,3 +28,3 @@ | ||
it('will not propagate if there is no assess context', function () { | ||
it('will not propagate if there is no assess policy in request context', function () { | ||
simulateRequestScope(function () { | ||
@@ -34,3 +34,3 @@ const value = trackString('foo'); | ||
expect(tracker.getData(result)).to.be.null; | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -37,0 +37,0 @@ |
@@ -29,2 +29,3 @@ /* | ||
assess: { | ||
getSourceContext, | ||
eventFactory: { createPropagationEvent }, | ||
@@ -77,3 +78,4 @@ dataflow: { tracker } | ||
data.result && | ||
(!matches || (matches && core.config.assess.trust_custom_validators)) | ||
(!matches || (matches && core.config.assess.trust_custom_validators)) && | ||
getSourceContext() | ||
) { | ||
@@ -109,3 +111,3 @@ const trackingData = tracker.getData(data.args[0]); | ||
post(data) { | ||
if (data.result) { | ||
if (data.result && getSourceContext()) { | ||
const trackingData = tracker.getData(data.args[0]); | ||
@@ -127,2 +129,3 @@ if (trackingData) { | ||
post(data) { | ||
if (!getSourceContext()) return; | ||
const trackingData = tracker.getData(data.args[0]); | ||
@@ -160,2 +163,4 @@ if (trackingData) { | ||
post(data) { | ||
if (!getSourceContext()) return; | ||
const options = data.args[1]; | ||
@@ -162,0 +167,0 @@ const trackingData = tracker.getData(data.args[0]); |
@@ -19,3 +19,3 @@ /* | ||
DataflowTag: { UNTRUSTED }, | ||
ArrayPrototypeJoin, | ||
primordials: { ArrayPrototypeJoin }, | ||
Rule: { CMD_INJECTION: ruleId }, | ||
@@ -22,0 +22,0 @@ isString, |
@@ -9,3 +9,3 @@ 'use strict'; | ||
const { initAssessFixture } = require('@contrast/test/fixtures'); | ||
const { UtilInspect } = require('@contrast/common'); | ||
const { primordials: { UtilInspect } } = require('@contrast/common'); | ||
@@ -12,0 +12,0 @@ describe('assess dataflow sinks child_process', function () { |
@@ -29,3 +29,3 @@ /* | ||
isString, | ||
ArrayPrototypeJoin, | ||
primordials: { ArrayPrototypeJoin }, | ||
} = require('@contrast/common'); | ||
@@ -32,0 +32,0 @@ const { InstrumentationType: { RULE } } = require('../../../constants'); |
@@ -5,3 +5,3 @@ 'use strict'; | ||
const { expect } = require('chai'); | ||
const { FS_METHODS, ArrayPrototypeJoin, UtilInspect } = require('@contrast/common'); | ||
const { FS_METHODS, primordials: { ArrayPrototypeJoin, UtilInspect } } = require('@contrast/common'); | ||
const { initAssessFixture } = require('@contrast/test/fixtures'); | ||
@@ -8,0 +8,0 @@ |
@@ -20,3 +20,3 @@ /* | ||
isString, | ||
ArrayPrototypeJoin, | ||
primordials: { ArrayPrototypeJoin }, | ||
DataflowTag: { | ||
@@ -23,0 +23,0 @@ UNTRUSTED, |
@@ -30,2 +30,3 @@ /* | ||
Rule: { SSRF: ruleId }, | ||
primordials: { RegExpPrototypeExec } | ||
} = require('@contrast/common'); | ||
@@ -88,3 +89,3 @@ const { InstrumentationType: { RULE } } = require('../../../../constants'); | ||
for (const trusted of trustedLibs) { | ||
if (trusted.exec(file)) { | ||
if (RegExpPrototypeExec.call(trusted, file)) { | ||
return true; | ||
@@ -91,0 +92,0 @@ } |
@@ -10,3 +10,3 @@ 'use strict'; | ||
}, | ||
UtilInspect | ||
primordials: { UtilInspect } | ||
} = require('@contrast/common'); | ||
@@ -13,0 +13,0 @@ |
@@ -76,7 +76,5 @@ 'use strict'; | ||
it('skips instrumentation if the content-type is safe', function () { | ||
const store = { | ||
assess: { responseData: { contentType: 'application/json' } }, | ||
}; | ||
simulateRequestScope(function () { | ||
core.scopes.sources.getStore().assess.responseData.contentType = 'application/json'; | ||
simulateRequestScope(function () { | ||
const str = trackString('hello world'); | ||
@@ -87,3 +85,3 @@ const { extern } = tracker.getData(str); | ||
expect(reportFindings).to.not.have.been.called; | ||
}, store); | ||
}); | ||
}); | ||
@@ -90,0 +88,0 @@ |
@@ -29,3 +29,3 @@ /* | ||
isString, | ||
ArrayPrototypeJoin, | ||
primordials: { ArrayPrototypeJoin }, | ||
} = require('@contrast/common'); | ||
@@ -32,0 +32,0 @@ const { InstrumentationType: { RULE } } = require('../../../constants'); |
@@ -30,4 +30,6 @@ /* | ||
isString, | ||
ArrayPrototypeJoin, | ||
StringPrototypeSplit, | ||
primordials: { | ||
ArrayPrototypeJoin, | ||
StringPrototypeSplit, | ||
}, | ||
traverseValues, | ||
@@ -34,0 +36,0 @@ } = require('@contrast/common'); |
@@ -8,3 +8,3 @@ 'use strict'; | ||
Rule: { UNSAFE_CODE_EXECUTION }, | ||
UtilInspect, | ||
primordials: { UtilInspect }, | ||
} = require('@contrast/common'); | ||
@@ -11,0 +11,0 @@ const { initAssessFixture } = require('@contrast/test/fixtures'); |
@@ -22,3 +22,6 @@ /* | ||
isString, | ||
ArrayPrototypeJoin, | ||
primordials: { | ||
ArrayPrototypeJoin, | ||
StringPrototypeToLowerCase | ||
} | ||
} = require('@contrast/common'); | ||
@@ -59,3 +62,3 @@ | ||
if (inputType === InputType.HEADER && fieldName.toLowerCase() === 'referer') { | ||
if (inputType === InputType.HEADER && StringPrototypeToLowerCase.call(fieldName) === 'referer') { | ||
tags[DataflowTag.HEADER] = [0, stop]; | ||
@@ -62,0 +65,0 @@ } |
@@ -108,3 +108,3 @@ 'use strict'; | ||
it('does not handle the request when not in context', function () { | ||
it('does not handle the request when there is no assess policy in request context', function () { | ||
const middleware = bodyParser('text'); | ||
@@ -120,3 +120,3 @@ | ||
); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -210,3 +210,3 @@ | ||
it('does not handle the request when not in context', function () { | ||
it('does not handle the request when there is in context', function () { | ||
simulateRequestScope(() => { | ||
@@ -220,3 +220,3 @@ middleware(req, res, next); | ||
); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -223,0 +223,0 @@ |
@@ -19,2 +19,3 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../constants'); | ||
const { patchType } = require('../common'); | ||
@@ -30,3 +31,8 @@ | ||
logger, | ||
assess: { dataflow: { sources } }, | ||
assess: { | ||
getSourceContext, | ||
dataflow: { | ||
sources, | ||
} | ||
}, | ||
} = core; | ||
@@ -37,6 +43,5 @@ | ||
const { orig, hooked, funcKey } = data; | ||
const sourceContext = core.scopes.sources.getStore()?.assess; | ||
const sourceContext = getSourceContext(SOURCE); | ||
if (!sourceContext) { | ||
logger.error({ inputType, funcKey }, 'unable to handle source. Missing `sourceContext`'); | ||
return; | ||
@@ -43,0 +48,0 @@ } |
@@ -113,3 +113,3 @@ 'use strict'; | ||
it('does not call `.handle` when not in context', function () { | ||
it('does not call `.handle` when there is no assess policy in request context', function () { | ||
simulateRequestScope(() => { | ||
@@ -119,3 +119,3 @@ emitMethodVersions[version]('field', 'field1', 'value1'); | ||
emitMethodVersions[version](finalEvent); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
@@ -122,0 +122,0 @@ expect(sources.handle).not.to.have.been.called; |
@@ -70,3 +70,3 @@ 'use strict'; | ||
it('does not handle the request when not in context', function () { | ||
it('does not handle when there is no assess policy in request context', function () { | ||
const middleware = cookieParser(); | ||
@@ -82,3 +82,3 @@ | ||
); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -85,0 +85,0 @@ |
@@ -19,6 +19,12 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
module.exports = function init(core) { | ||
const { depHooks, patcher, logger } = core; | ||
const { | ||
logger, | ||
patcher, | ||
depHooks, | ||
assess: { getSourceContext }, | ||
} = core; | ||
@@ -35,17 +41,14 @@ core.assess.dataflow.sources.expressInstrumentation.params = { | ||
post({ obj: layer, result, orig, hooked, funcKey }) { | ||
// we can exit early if | ||
// the layer doesn't match the request or | ||
// the layer doesn't recognize any parameters | ||
if (!result || !layer.keys || layer.keys.length === 0) { | ||
return; | ||
} | ||
if ( | ||
!result || | ||
!layer.keys || | ||
layer.keys.length === 0 | ||
) return; | ||
const sourceContext = core.scopes.sources.getStore()?.assess; | ||
const sourceContext = getSourceContext(SOURCE) | ||
if (!sourceContext) return; | ||
if (!sourceContext) { | ||
logger.error({ funcKey }, 'unable to handle source. Missing `sourceContext`'); | ||
return; | ||
} | ||
if (sourceContext.parsedParams) { | ||
@@ -52,0 +55,0 @@ logger.trace({ funcKey }, 'values already tracked'); |
@@ -68,3 +68,3 @@ 'use strict'; | ||
it('does not call `.handle` when not in context', function () { | ||
it('does not handle when there is no assess policy in request context', function () { | ||
simulateRequestScope(() => { | ||
@@ -74,7 +74,3 @@ Reflect.apply(Layer.prototype.match, layer, ['/bar']); | ||
expect(core.assess.dataflow.sources.handle).not.to.have.been.called; | ||
expect(core.logger.error).to.have.been.calledWith( | ||
{ funcKey: 'assess-dataflow-source:Layer.prototype.match' }, | ||
'unable to handle source. Missing `sourceContext`' | ||
); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -84,2 +80,4 @@ | ||
simulateRequestScope(() => { | ||
core.scopes.sources.getStore().assess.parsedParams = true; | ||
Reflect.apply(Layer.prototype.match, layer, ['/bar']); | ||
@@ -92,3 +90,3 @@ | ||
); | ||
}, { assess: { parsedParams: true } }); | ||
}); | ||
}); | ||
@@ -95,0 +93,0 @@ |
@@ -19,2 +19,3 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
@@ -25,2 +26,3 @@ | ||
assess: { | ||
getSourceContext, | ||
dataflow: { sources } | ||
@@ -30,3 +32,2 @@ }, | ||
patcher, | ||
scopes | ||
} = core; | ||
@@ -54,3 +55,3 @@ | ||
pre(data) { | ||
const sourceContext = scopes.sources.getStore()?.assess; | ||
const sourceContext = getSourceContext(SOURCE); | ||
if (!sourceContext) return; | ||
@@ -57,0 +58,0 @@ |
@@ -19,2 +19,3 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
@@ -27,3 +28,6 @@ | ||
patcher, | ||
assess: { dataflow: { sources } }, | ||
assess: { | ||
getSourceContext, | ||
dataflow: { sources } | ||
}, | ||
} = core; | ||
@@ -43,8 +47,5 @@ | ||
: InputType.BODY; | ||
const sourceContext = core.scopes.sources.getStore()?.assess; | ||
const sourceContext = getSourceContext(SOURCE); | ||
if (!sourceContext) { | ||
logger.error({ funcKey }, 'unable to handle source. Missing `sourceContext`'); | ||
return; | ||
} | ||
if (!sourceContext) return; | ||
@@ -51,0 +52,0 @@ [ |
@@ -149,6 +149,6 @@ 'use strict'; | ||
it('does not call `.handle` when not in context', function () { | ||
it('does not handle source when there is no assess policy in request context', function () { | ||
simulateRequestScope(() => { | ||
fastifyServerMock(); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
@@ -155,0 +155,0 @@ expect(sources.handle).not.to.have.been.called; |
@@ -19,2 +19,3 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../constants'); | ||
const { patchType } = require('../common'); | ||
@@ -29,3 +30,6 @@ | ||
logger, | ||
assess: { dataflow: { sources } }, | ||
assess: { | ||
getSourceContext, | ||
dataflow: { sources } | ||
}, | ||
} = core; | ||
@@ -43,8 +47,5 @@ | ||
const { funcKey } = data; | ||
const sourceContext = core.scopes.sources.getStore()?.assess; | ||
const sourceContext = getSourceContext(SOURCE); | ||
if (!sourceContext) { | ||
logger.error({ inputType, funcKey }, 'unable to handle source. Missing `sourceContext`'); | ||
return; | ||
} | ||
if (!sourceContext) return; | ||
@@ -51,0 +52,0 @@ if (sourceContext.parsedBody) { |
@@ -85,6 +85,6 @@ 'use strict'; | ||
it('does not call `.handle` when not in context', function () { | ||
it('does not call `.handle` when there is no assess policy in request context', function () { | ||
simulateRequestScope(() => { | ||
patchedParse(req, cbStub); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
@@ -91,0 +91,0 @@ expect(sources.handle).not.to.have.been.called; |
@@ -19,2 +19,3 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
@@ -27,3 +28,6 @@ | ||
patcher, | ||
assess: { dataflow: { sources } }, | ||
assess: { | ||
getSourceContext, | ||
dataflow: { sources } | ||
}, | ||
} = core; | ||
@@ -41,7 +45,4 @@ | ||
server.ext('onRequest', (req, h) => { | ||
const sourceContext = core.scopes.sources.getStore()?.assess; | ||
if (!sourceContext) { | ||
logger.error({ funcKey }, 'unable to handle source. Missing `sourceContext`'); | ||
return; | ||
} | ||
const sourceContext = getSourceContext(SOURCE); | ||
if (!sourceContext) return; | ||
@@ -78,6 +79,3 @@ [ | ||
const sourceContext = core.scopes.sources.getStore()?.assess; | ||
if (!sourceContext) { | ||
logger.error({ funcKey }, 'unable to handle source. Missing `sourceContext`'); | ||
return; | ||
} | ||
if (!sourceContext) return; | ||
@@ -84,0 +82,0 @@ [ |
@@ -9,3 +9,2 @@ 'use strict'; | ||
describe('assess dataflow sources hapi', function () { | ||
const hapi = { | ||
@@ -12,0 +11,0 @@ server(server) { |
@@ -17,4 +17,6 @@ /* | ||
'use strict'; | ||
const { primordials: { StringPrototypeToLowerCase }, InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../constants'); | ||
const { patchType } = require('../common'); | ||
const { StringPrototypeToLowerCase, InputType } = require('@contrast/common'); | ||
@@ -28,9 +30,11 @@ /** | ||
const { | ||
assess: { dataflow, makeSourceContext }, | ||
assess: { | ||
getSourceContext, | ||
dataflow, | ||
}, | ||
instrumentation: { instrument }, | ||
patcher, | ||
scopes, | ||
} = core; | ||
const logger = core.logger.child('contrast:assess'); | ||
const logger = core.logger.child({ name: 'contrast:assess' }); | ||
@@ -48,12 +52,8 @@ /** | ||
const [, req, res] = data.args; | ||
const store = scopes.sources.getStore(); | ||
const sourceContext = getSourceContext(SOURCE); | ||
if (!store) { | ||
// this would indicate that sources did not install correctly | ||
throw new Error('async request store not found'); | ||
if (!sourceContext?.policy) { | ||
return next(); | ||
} | ||
store.assess = makeSourceContext(req, res); | ||
if (!store.assess) return; | ||
patcher.patch(res, 'writeHead', { | ||
@@ -72,3 +72,3 @@ name: 'write-head', | ||
if (StringPrototypeToLowerCase.call(key) === 'content-type') { | ||
store.assess.responseData.contentType = value; | ||
sourceContext.responseData.contentType = value; | ||
} | ||
@@ -79,3 +79,3 @@ } | ||
if (StringPrototypeToLowerCase.call(key) === 'content-type') { | ||
store.assess.responseData.contentType = value; | ||
sourceContext.responseData.contentType = value; | ||
} | ||
@@ -93,4 +93,8 @@ } | ||
const [name = '', value] = data.args; | ||
if (StringPrototypeToLowerCase.call(name) === 'content-type' && scopes.sources.getStore()?.assess && value) { | ||
store.assess.responseData.contentType = value; | ||
if ( | ||
value && | ||
StringPrototypeToLowerCase.call(name) === 'content-type' && | ||
getSourceContext(SOURCE) | ||
) { | ||
sourceContext.responseData.contentType = value; | ||
} | ||
@@ -108,3 +112,3 @@ } | ||
}, | ||
sourceContext: store.assess | ||
sourceContext, | ||
}; | ||
@@ -111,0 +115,0 @@ |
@@ -7,2 +7,3 @@ 'use strict'; | ||
const { initAssessFixture } = require('@contrast/test/fixtures'); | ||
const mocks = require('@contrast/test/mocks'); | ||
@@ -15,17 +16,5 @@ describe('assess dataflow sources http', function () { | ||
request = { | ||
url: 'http://host:8080/index.html?param=foo', | ||
httpVersion: 1, | ||
method: 'GET', | ||
socket: { | ||
remoteAddress: '127.0.0.1' | ||
}, | ||
rawHeaders: ['Content-Type', 'application/json'], | ||
headers: { | ||
'content-type': 'application/json' | ||
} | ||
}; | ||
response = new EventEmitter(); | ||
response.writeHead = function () { }; | ||
response.setHeader = function () { }; | ||
request = mocks.incomingMessage(); | ||
response = mocks.serverResponse(); | ||
class Server extends EventEmitter { } | ||
@@ -41,2 +30,3 @@ core.depHooks.resolve.withArgs({ name: 'http' }).yields({ Server }); | ||
simulateRequestScope(() => { | ||
core.scopes.sources.getStore().assess.req | ||
server.on('request', test); | ||
@@ -50,13 +40,18 @@ server.emit('request', request, response); | ||
expect(store).to.have.property('propagationEventsCount', 0); | ||
// 3: url, headers, rawHeaders | ||
expect(store).to.have.property('sourceEventsCount', 3); | ||
// url(1), headers(3), rawHeaders(3) | ||
expect(store).to.have.property('sourceEventsCount', 7); | ||
expect(store.policy.enabledRules).to.be.a('Set').and.length.greaterThan(5); | ||
// should match the mock | ||
expect(store.reqData).to.deep.equal({ | ||
ip: '127.0.0.1', | ||
httpVersion: 1, | ||
method: 'GET', | ||
headers: { 'content-type': 'application/json' }, | ||
uriPath: 'http://host:8080/index.html', | ||
queries: 'param=foo', | ||
contentType: 'application/json' | ||
httpVersion: '1.1', | ||
method: 'get', | ||
headers: { | ||
'content-type': 'text/html', | ||
language: 'en', | ||
referer: 'http://fake.url.foo' | ||
}, | ||
uriPath: '/index', | ||
queries: '_id=123', | ||
contentType: 'text/html' | ||
}); | ||
@@ -108,7 +103,2 @@ expect(store.responseData).to.deep.equal({}); | ||
const store = core.scopes.sources.getStore()?.assess; | ||
// logging | ||
expect(core.logger.error).to.have.been.calledWith( | ||
{ err: sinon.match.has('message', 'async request store not found'), funcKey: sinon.match.string }, | ||
'Error during Assess request handling' | ||
); | ||
// validate store | ||
@@ -143,8 +133,12 @@ expect(store).to.be.undefined; | ||
ip: '127.0.0.1', | ||
httpVersion: 1, | ||
method: 'GET', | ||
headers: { 'content-type': 'application/json' }, | ||
uriPath: 'http://host:8080/index.html', | ||
queries: 'param=foo', | ||
contentType: 'application/json' | ||
httpVersion: '1.1', | ||
method: 'get', | ||
headers: { | ||
'content-type': 'text/html', | ||
language: 'en', | ||
referer: 'http://fake.url.foo' | ||
}, | ||
uriPath: '/index', | ||
queries: '_id=123', | ||
contentType: 'text/html' | ||
}); | ||
@@ -151,0 +145,0 @@ expect(store.responseData).to.deep.equal({}); |
@@ -19,2 +19,3 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
@@ -27,3 +28,6 @@ | ||
logger, | ||
assess: { dataflow: { sources } }, | ||
assess: { | ||
getSourceContext, | ||
dataflow: { sources } | ||
}, | ||
} = core; | ||
@@ -43,9 +47,6 @@ | ||
const { funcKey } = data; | ||
const sourceContext = core.scopes.sources.getStore()?.assess; | ||
const [ctx, origNext] = data.args; | ||
const sourceContext = getSourceContext(SOURCE); | ||
if (!sourceContext) { | ||
logger.error({ funcKey }, 'unable to handle source. Missing `sourceContext`'); | ||
return; | ||
} | ||
if (!sourceContext) return; | ||
@@ -57,3 +58,2 @@ if (sourceContext.parsedBody) { | ||
data.args[1] = async function contrastNext(origErr) { | ||
@@ -60,0 +60,0 @@ const inputType = sourceContext.reqData.headers?.['content-type']?.includes('/json') |
@@ -115,7 +115,7 @@ 'use strict'; | ||
it('does not call `.handle` when not in context', function () { | ||
it('does not call `.handle` when there is no assess policy in request context', function () { | ||
simulateRequestScope(() => { | ||
const cParser = patchedKoaBodyparser(body); | ||
cParser({ request: {} }, nextStub); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
@@ -128,4 +128,3 @@ expect(sources.handle).not.to.have.been.called; | ||
simulateRequestScope(() => { | ||
const sourceContext = core.scopes.sources.getStore()?.assess; | ||
sourceContext.parsedBody = true; | ||
core.scopes.sources.getStore().assess.parsedBody = true; | ||
@@ -132,0 +131,0 @@ const cParser = patchedKoaBodyparser(body); |
@@ -17,4 +17,6 @@ /* | ||
'use strict'; | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
const { InputType } = require('@contrast/common'); | ||
@@ -26,8 +28,10 @@ module.exports = (core) => { | ||
patcher, | ||
scopes, | ||
assess: { dataflow: { sources } }, | ||
assess: { | ||
getSourceContext, | ||
dataflow: { sources } | ||
}, | ||
} = core; | ||
function handler(req, constructorOpt) { | ||
const sourceContext = scopes.sources.getStore()?.assess; | ||
const sourceContext = getSourceContext(SOURCE); | ||
if (!sourceContext) return; | ||
@@ -34,0 +38,0 @@ |
@@ -19,2 +19,3 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
@@ -27,3 +28,6 @@ | ||
logger, | ||
assess: { dataflow: { sources } }, | ||
assess: { | ||
getSourceContext, | ||
dataflow: { sources } | ||
}, | ||
} = core; | ||
@@ -41,9 +45,6 @@ | ||
post({ orig, hooked, result, name, funcKey }) { | ||
const sourceContext = core.scopes.sources.getStore()?.assess; | ||
const sourceContext = getSourceContext(SOURCE); | ||
const inputType = InputType.URL_PARAMETER; | ||
if (!sourceContext) { | ||
logger.error({ inputType, funcKey }, 'unable to handle source. Missing `sourceContext`'); | ||
return; | ||
} | ||
if (!sourceContext) return; | ||
@@ -50,0 +51,0 @@ if (sourceContext.parsedParams) { |
@@ -100,3 +100,3 @@ 'use strict'; | ||
it(`[${router}] does not call \`.handle\` when there is no context`, function () { | ||
it(`[${router}] does not call \`.handle\` when there is no assess policy in request context`, function () { | ||
const paramsFn = getParamsFn(router); | ||
@@ -106,3 +106,3 @@ | ||
paramsFn(params); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
@@ -109,0 +109,0 @@ expect(sources.handle).not.to.have.been.called; |
@@ -19,2 +19,4 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../../constants'); | ||
const { patchType } = require('../../common'); | ||
@@ -34,3 +36,6 @@ | ||
patcher, | ||
assess: { dataflow: { sources } }, | ||
assess: { | ||
getSourceContext, | ||
dataflow: { sources } | ||
}, | ||
} = core; | ||
@@ -45,6 +50,5 @@ | ||
const contrastStartMiddleware = function contrastStartMiddleware(ctx, next) { | ||
const sourceContext = core.scopes.sources.getStore()?.assess; | ||
const sourceContext = getSourceContext(SOURCE); | ||
if (!sourceContext) { | ||
logger.error({ inputType, funcKey }, 'unable to handle Koa source. Missing `sourceContext`'); | ||
return next(); | ||
@@ -51,0 +55,0 @@ } |
@@ -116,3 +116,3 @@ 'use strict'; | ||
contrastStartMiddleware({ query }, nextStub); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
@@ -119,0 +119,0 @@ expect(nextStub).to.have.been.calledOnce; |
@@ -19,2 +19,3 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../constants'); | ||
const { patchType } = require('../common'); | ||
@@ -27,3 +28,6 @@ | ||
logger, | ||
assess: { dataflow: { sources } }, | ||
assess: { | ||
getSourceContext, | ||
dataflow: { sources } | ||
}, | ||
scopes, | ||
@@ -33,3 +37,3 @@ } = core; | ||
function handler(req, constructorOpt) { | ||
const sourceContext = scopes.sources.getStore()?.assess; | ||
const sourceContext = getSourceContext(SOURCE); | ||
if (!sourceContext) return; | ||
@@ -36,0 +40,0 @@ |
@@ -19,4 +19,4 @@ /* | ||
const { InputType: { QUERYSTRING: inputType } } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../constants'); | ||
const { patchType } = require('../common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../constants'); | ||
@@ -23,0 +23,0 @@ module.exports = (core) => { |
@@ -19,4 +19,4 @@ /* | ||
const { InputType } = require('@contrast/common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../constants'); | ||
const { patchType } = require('../common'); | ||
const { InstrumentationType: { SOURCE } } = require('../../../constants'); | ||
@@ -23,0 +23,0 @@ module.exports = (core) => { |
@@ -49,6 +49,3 @@ /* | ||
if (!sourceContext) { | ||
logger.error({ funcKey }, 'unable to handle source. Missing `sourceContext`'); | ||
return next(...args); | ||
} | ||
if (!sourceContext) return next(...args); | ||
@@ -55,0 +52,0 @@ if (sourceContext.parsedBody) { |
@@ -32,3 +32,3 @@ 'use strict'; | ||
it('does not call `handle` when not in context', function () { | ||
it('does not call `handle` when there is no assess policy in request context', function () { | ||
simulateRequestScope(() => { | ||
@@ -38,11 +38,9 @@ middleware(req, res, next); | ||
expect(handle).not.to.have.been.called; | ||
expect(core.logger.error).to.have.been.calledWith( | ||
{ funcKey: 'assess-dataflow-source:restify.plugins.fieldedTextBodyParser.parseFieldedText' }, | ||
'unable to handle source. Missing `sourceContext`' | ||
); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
it('does not call `handle` when body is already tracked', function () { | ||
it('does not handle source when body is already tracked', function () { | ||
simulateRequestScope(() => { | ||
core.scopes.sources.getStore().assess.parsedBody = true; | ||
middleware(req, res, next); | ||
@@ -55,3 +53,3 @@ | ||
); | ||
}, { assess: { parsedBody: true } }); | ||
}); | ||
}); | ||
@@ -58,0 +56,0 @@ |
@@ -54,3 +54,2 @@ /* | ||
if (!sourceContext) { | ||
logger.error({ funcKey }, 'unable to handle source. Missing `sourceContext`'); | ||
return next(...args); | ||
@@ -57,0 +56,0 @@ } |
@@ -34,3 +34,3 @@ 'use strict'; | ||
it('does not call `handle` when not in context', function () { | ||
it('does not handle source when there is no assess policy in request context', function () { | ||
const [, middleware] = jsonBodyParserStub(); | ||
@@ -40,9 +40,4 @@ | ||
middleware(req, res, next); | ||
expect(handle).not.to.have.been.called; | ||
expect(core.logger.error).to.have.been.calledWith( | ||
{ funcKey: 'assess-dataflow-source:restify.plugins.jsonBodyParser.parseJson' }, | ||
'unable to handle source. Missing `sourceContext`' | ||
); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -54,2 +49,3 @@ | ||
simulateRequestScope(() => { | ||
core.scopes.sources.getStore().assess.parsedBody = true; | ||
middleware(req, res, next); | ||
@@ -62,3 +58,3 @@ | ||
); | ||
}, { assess: { parsedBody: true } }); | ||
}); | ||
}); | ||
@@ -65,0 +61,0 @@ |
@@ -26,3 +26,3 @@ 'use strict'; | ||
it('does not call `handle` when not in context', function () { | ||
it('does not call `handle` when there is no assess policy in request context', function () { | ||
simulateRequestScope(() => { | ||
@@ -36,3 +36,3 @@ Router.prototype.lookup(req); | ||
); | ||
}, {}); | ||
}, { assess: { policy: null } }); | ||
}); | ||
@@ -39,0 +39,0 @@ |
@@ -17,3 +17,3 @@ /* | ||
const { StringPrototypeSplit } = require('@contrast/common'); | ||
const { primordials: { StringPrototypeSplit } } = require('@contrast/common'); | ||
@@ -20,0 +20,0 @@ // |
@@ -19,3 +19,3 @@ /* | ||
const distringuish = require('@contrast/distringuish'); | ||
const { BufferPrototypeToString, BufferFrom, isString } = require('@contrast/common'); | ||
const { primordials: { BufferPrototypeToString, BufferFrom }, isString } = require('@contrast/common'); | ||
@@ -22,0 +22,0 @@ module.exports = function tracker(core) { |
@@ -16,3 +16,3 @@ /* | ||
'use strict'; | ||
const { primordials: { ArrayPrototypeJoin, RegExpPrototypeTest } } = require('@contrast/common'); | ||
const SAFE_XSS_CONTENT_TYPES = [ | ||
@@ -26,7 +26,8 @@ '/json', | ||
]; | ||
const SAFE_XSS_REGEX = new RegExp(ArrayPrototypeJoin.call(SAFE_XSS_CONTENT_TYPES, '|')); | ||
function isSafeContentType(contentType) { | ||
return new RegExp(SAFE_XSS_CONTENT_TYPES.join('|')).test(contentType); | ||
return RegExpPrototypeTest.call(SAFE_XSS_REGEX, contentType); | ||
} | ||
module.exports = { isSafeContentType, SAFE_XSS_CONTENT_TYPES }; |
@@ -18,3 +18,3 @@ /* | ||
const { InputType, StringPrototypeMatch } = require('@contrast/common'); | ||
const { InputType, primordials: { StringPrototypeMatch } } = require('@contrast/common'); | ||
const ANNOTATION_REGEX = /^(A|O|R|P|P\d+)$/; | ||
@@ -187,3 +187,3 @@ const SOURCE_EVENT_MSG = 'Source event not created: %s'; | ||
if ( | ||
(!source || !source.match(ANNOTATION_REGEX)) | ||
(!source || !StringPrototypeMatch.call(source, ANNOTATION_REGEX)) | ||
) { | ||
@@ -242,3 +242,3 @@ logger.debug({ name }, 'malformed or missing sink event source field'); | ||
if ( | ||
(!source || !source.match(ANNOTATION_REGEX)) | ||
(!source || !StringPrototypeMatch.call(source, ANNOTATION_REGEX)) | ||
) { | ||
@@ -305,3 +305,3 @@ logger.debug({ name }, 'malformed or missing sink event source field'); | ||
if (!source || !source.match(ANNOTATION_REGEX)) { | ||
if (!source || !StringPrototypeMatch.call(source, ANNOTATION_REGEX)) { | ||
logger.debug({ name }, 'malformed or missing sink event source field'); | ||
@@ -308,0 +308,0 @@ return null; |
@@ -25,3 +25,3 @@ /* | ||
SessionConfigurationRule, | ||
ArrayPrototypeJoin, | ||
primordials: { ArrayPrototypeJoin, RegExpPrototypeTest } | ||
} = require('@contrast/common'); | ||
@@ -327,3 +327,3 @@ | ||
if (!this._inputName && !this._inputNameRegex) return true; | ||
return this._inputNameRegex ? this._inputNameRegex.test(name) : this._inputName === name; | ||
return this._inputNameRegex ? RegExpPrototypeTest.call(this._inputNameRegex, name) : this._inputName === name; | ||
} | ||
@@ -330,0 +330,0 @@ } |
@@ -22,7 +22,11 @@ /* | ||
module.exports = function assess(core) { | ||
const { scopes: { instrumentation } } = core; | ||
const { | ||
config, | ||
sources, | ||
scopes: { instrumentation } | ||
} = core; | ||
const assess = core.assess = { | ||
install() { | ||
if (!core.config.getEffectiveValue('assess.enable')) { | ||
if (!config.getEffectiveValue('assess.enable')) { | ||
core.logger.debug('assess is disabled, skipping installation'); | ||
@@ -32,3 +36,5 @@ return; | ||
// configure rewriter | ||
core.rewriter.install('assess'); | ||
// dispatch subcomponent installation | ||
callChildComponentMethodsSync(core.assess, 'install'); | ||
@@ -48,17 +54,22 @@ }, | ||
require('./rule-scopes')(core); | ||
// ancillary tools used by different features | ||
require('./sampler')(core); | ||
require('./get-policy')(core); | ||
require('./make-source-context')(core); | ||
require('./rule-scopes')(core); | ||
require('./get-source-context')(core); | ||
require('./event-factory')(core); | ||
// various Assess features | ||
require('./dataflow')(core); | ||
require('./crypto-analysis')(core); | ||
require('./dataflow')(core); | ||
require('./response-scanning')(core); | ||
require('./session-configuration')(core); | ||
// todo | ||
// crypto rule implementations | ||
// static rule implementations in coordination with (CLI) rewriter | ||
// append async state to sources store when request-scope sources are created | ||
sources.addHook('onSource', (ctx) => { | ||
ctx.store.assess = assess.makeSourceContext(ctx); | ||
}); | ||
return assess; | ||
}; |
'use strict'; | ||
const { expect } = require('chai'); | ||
const sinon = require('sinon'); | ||
const proxyquire = require('proxyquire'); | ||
@@ -22,2 +23,5 @@ const mocks = require('@contrast/test/mocks'); | ||
core.config.assess.enable = true; | ||
core.sources = { | ||
addHook: sinon.stub(), | ||
}; | ||
@@ -24,0 +28,0 @@ assessModule = proxyquire('.', { |
@@ -18,4 +18,3 @@ /* | ||
const { StringPrototypeToLowerCase } = require('@contrast/common'); | ||
const { primordials: { StringPrototypeToLowerCase, StringPrototypeSlice } } = require('@contrast/common'); | ||
/** | ||
@@ -28,6 +27,3 @@ * @param {{ | ||
module.exports = function(core) { | ||
const { | ||
assess: { getPolicy }, | ||
logger, | ||
} = core; | ||
const { assess, logger } = core; | ||
@@ -37,10 +33,15 @@ /** | ||
*/ | ||
return core.assess.makeSourceContext = function (req, res) { | ||
let contentType, queries, uriPath; | ||
return core.assess.makeSourceContext = function (sourceData) { | ||
try { | ||
// todo: how to handle non-HTTP sources | ||
const { incomingMessage: req } = sourceData; | ||
try { | ||
const ix = req.url.indexOf('?'); | ||
if (ix >= 0) { | ||
uriPath = req.url.slice(0, ix); | ||
queries = req.url.slice(ix + 1); | ||
// minimally process the request data for sampling and exclusions. | ||
// more request fields will be appended in final result below. | ||
let uriPath; | ||
let queries; | ||
const idx = req.url.indexOf('?'); | ||
if (idx >= 0) { | ||
uriPath = StringPrototypeSlice.call(req.url, 0, idx); | ||
queries = StringPrototypeSlice.call(req.url, idx + 1); | ||
} else { | ||
@@ -51,21 +52,29 @@ uriPath = req.url; | ||
// copy to avoid storing tracked values | ||
const headers = { ...req.headers }; | ||
if (headers['content-type']) { | ||
contentType = StringPrototypeToLowerCase.call(headers['content-type']); | ||
} | ||
const ctx = sourceData.store.assess = { | ||
// default policy to `null` until it is set later below. this will cause | ||
// all instrumentation to short-circuit, see `./get-source-context.js`. | ||
policy: null, | ||
reqData: { uriPath, queries }, | ||
}; | ||
// check whether sampling allows processing | ||
ctx.sampleInfo = assess.sampler?.getSampleInfo?.(sourceData) ?? null; | ||
if (ctx.sampleInfo?.canSample === false) return ctx; | ||
// set policy - can be returned as `null` if request is url-excluded. | ||
ctx.policy = assess.getPolicy(ctx.reqData); | ||
if (!ctx.policy) return ctx; | ||
// build remaining reqData | ||
ctx.reqData.headers = { ...req.headers }; // copy to avoid storing tracked values | ||
ctx.reqData.ip = req.socket.remoteAddress; | ||
ctx.reqData.httpVersion = req.httpVersion; | ||
ctx.reqData.method = req.method; | ||
if (ctx.reqData.headers['content-type']) | ||
ctx.reqData.contentType = StringPrototypeToLowerCase.call(ctx.reqData.headers['content-type']); | ||
return { | ||
...ctx, | ||
propagationEventsCount: 0, | ||
sourceEventsCount: 0, | ||
policy: getPolicy({ uriPath }), | ||
reqData: { | ||
ip: req.socket.remoteAddress, | ||
httpVersion: req.httpVersion, | ||
method: req.method, | ||
headers, | ||
uriPath, | ||
queries, | ||
contentType, | ||
}, | ||
responseData: {}, | ||
@@ -72,0 +81,0 @@ ruleState: {}, |
@@ -8,3 +8,2 @@ 'use strict'; | ||
describe('assess makeSourceContext', function () { | ||
@@ -18,3 +17,3 @@ let core; | ||
it('will return `null` and log error when passed insufficient parameters', function() { | ||
const assessCtx = core.assess.makeSourceContext({}, {}); | ||
const assessCtx = core.assess.makeSourceContext({}); | ||
expect(assessCtx).to.be.null; | ||
@@ -27,9 +26,10 @@ expect(core.logger.error).to.have.been.calledWithMatch({ | ||
it('construct the store correctly given req and res', function() { | ||
const req = mocks.incomingMessage(); | ||
const res = {}; | ||
const assessCtx = core.assess.makeSourceContext(req, res); | ||
const mockSourceData = { | ||
store: {}, | ||
incomingMessage: mocks.incomingMessage() | ||
}; | ||
const assessCtx = core.assess.makeSourceContext(mockSourceData); | ||
expect(assessCtx).to.deep.include({ | ||
propagationEventsCount: 0, | ||
sampleInfo: null, | ||
sourceEventsCount: 0, | ||
@@ -36,0 +36,0 @@ reqData: { |
@@ -19,6 +19,8 @@ /* | ||
const { | ||
StringPrototypeToLowerCase, | ||
JSONStringify, | ||
StringPrototypeSubstring, | ||
ResponseScanningRule | ||
primordials: { | ||
StringPrototypeToLowerCase, | ||
JSONStringify, | ||
StringPrototypeSubstring, | ||
}, | ||
ResponseScanningRule, | ||
} = require('@contrast/common'); | ||
@@ -205,3 +207,3 @@ const { | ||
ruleId: ResponseScanningRule.CSP_HEADER_INSECURE, | ||
vulnerabilityMetadata: { data: JSON.stringify(vulnerabilityMetadata) } | ||
vulnerabilityMetadata: { data: JSONStringify(vulnerabilityMetadata) } | ||
}); | ||
@@ -208,0 +210,0 @@ } |
@@ -19,8 +19,11 @@ /* | ||
const { | ||
ArrayPrototypeJoin, | ||
StringPrototypeSubstring, | ||
StringPrototypeToLowerCase, | ||
StringPrototypeSplit, | ||
StringPrototypeTrim, | ||
StringPrototypeReplace | ||
primordials: { | ||
ArrayPrototypeJoin, | ||
StringPrototypeSubstring, | ||
StringPrototypeToLowerCase, | ||
StringPrototypeSplit, | ||
StringPrototypeTrim, | ||
StringPrototypeReplace, | ||
RegExpPrototypeTest | ||
} | ||
} = require('@contrast/common'); | ||
@@ -42,3 +45,3 @@ | ||
function escapeHtml(string) { | ||
return (string && reHasUnescapedHtml.test(string)) | ||
return (string && RegExpPrototypeTest.call(reHasUnescapedHtml, string)) | ||
? StringPrototypeReplace.call(string, reUnescapedHtml, (chr) => htmlEscapes[chr]) | ||
@@ -262,3 +265,3 @@ : (string || ''); | ||
sources.length > 0 && | ||
sources.every((source) => !!source && !/\*/.test(source)) | ||
sources.every((source) => !!source && !RegExpPrototypeTest.call(/\*/, source)) | ||
); | ||
@@ -265,0 +268,0 @@ } |
@@ -18,3 +18,3 @@ /* | ||
const { StringPrototypeSplit, StringPrototypeSubstring, StringPrototypeToLowerCase, StringPrototypeTrim } = require('@contrast/common'); | ||
const { primordials: { StringPrototypeSplit, StringPrototypeSubstring, StringPrototypeToLowerCase, StringPrototypeTrim } } = require('@contrast/common'); | ||
@@ -21,0 +21,0 @@ /** |
@@ -17,3 +17,3 @@ /* | ||
const { StringPrototypeToLowerCase } = require('@contrast/common'); | ||
const { primordials: { StringPrototypeToLowerCase } } = require('@contrast/common'); | ||
const { patchType } = require('../common'); | ||
@@ -20,0 +20,0 @@ |
@@ -17,3 +17,3 @@ /* | ||
const { StringPrototypeToLowerCase } = require('@contrast/common'); | ||
const { primordials: { StringPrototypeToLowerCase } } = require('@contrast/common'); | ||
const { patchType } = require('../common'); | ||
@@ -20,0 +20,0 @@ |
{ | ||
"name": "@contrast/assess", | ||
"version": "1.35.0", | ||
"version": "1.36.0", | ||
"description": "Contrast service providing framework-agnostic Assess support", | ||
@@ -20,14 +20,14 @@ "license": "SEE LICENSE IN LICENSE", | ||
"dependencies": { | ||
"@contrast/common": "1.25.0", | ||
"@contrast/config": "1.33.0", | ||
"@contrast/core": "1.37.0", | ||
"@contrast/dep-hooks": "1.5.0", | ||
"@contrast/common": "1.26.0", | ||
"@contrast/config": "1.34.0", | ||
"@contrast/core": "1.38.0", | ||
"@contrast/dep-hooks": "1.6.0", | ||
"@contrast/distringuish": "^5.1.0", | ||
"@contrast/instrumentation": "1.15.0", | ||
"@contrast/logger": "1.10.0", | ||
"@contrast/patcher": "1.9.0", | ||
"@contrast/rewriter": "1.13.0", | ||
"@contrast/scopes": "1.6.0", | ||
"@contrast/instrumentation": "1.16.0", | ||
"@contrast/logger": "1.11.0", | ||
"@contrast/patcher": "1.10.0", | ||
"@contrast/rewriter": "1.14.0", | ||
"@contrast/scopes": "1.7.0", | ||
"semver": "^7.6.0" | ||
} | ||
} |
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances 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
1458489
326
41178
7
+ Added@contrast/common@1.26.0(transitive)
+ Added@contrast/config@1.34.0(transitive)
+ Added@contrast/core@1.38.0(transitive)
+ Added@contrast/dep-hooks@1.6.0(transitive)
+ Added@contrast/instrumentation@1.16.0(transitive)
+ Added@contrast/logger@1.11.0(transitive)
+ Added@contrast/patcher@1.10.0(transitive)
+ Added@contrast/rewriter@1.14.0(transitive)
+ Added@contrast/scopes@1.7.0(transitive)
- Removed@contrast/common@1.25.0(transitive)
- Removed@contrast/config@1.33.0(transitive)
- Removed@contrast/core@1.37.0(transitive)
- Removed@contrast/dep-hooks@1.5.0(transitive)
- Removed@contrast/instrumentation@1.15.0(transitive)
- Removed@contrast/logger@1.10.0(transitive)
- Removed@contrast/patcher@1.9.0(transitive)
- Removed@contrast/rewriter@1.13.0(transitive)
- Removed@contrast/scopes@1.6.0(transitive)
Updated@contrast/common@1.26.0
Updated@contrast/config@1.34.0
Updated@contrast/core@1.38.0
Updated@contrast/dep-hooks@1.6.0
Updated@contrast/logger@1.11.0
Updated@contrast/patcher@1.10.0
Updated@contrast/rewriter@1.14.0
Updated@contrast/scopes@1.7.0