@hclsoftware/secagent
Version:
IAST agent
94 lines (77 loc) • 4.38 kB
JavaScript
//IASTIGNORE
/*
* ****************************************************
* Licensed Materials - Property of HCL.
* (c) Copyright HCL Technologies Ltd. 2017, 2025.
* Note to U.S. Government Users *Restricted Rights.
* ****************************************************
*/
const SanitizeByReplaceTask = require('../Tasks/SanitizeByReplaceTask')
const SanitizeByReplaceAllTask = require('../Tasks/SanitizeByReplaceAllTask')
const ValidateByRegexTask = require('../Tasks/ValidateByMatchTask')
const TaintTracker = require('../TaintTracker')
const Logger = require('../Logger/IastLogger')
const taintedData = require('../Hooks/IastProperties').property.TAINTED_DATA
const Utils = require('../Utils/Utils')
const {IASTHashMap} = require('../Utils/IASTHashMap')
const verifiedMethods = new IASTHashMap()
module.exports.VerificationInfo = class VerificationInfo {
constructor (taskInfoHash, vulnerabilityType, contextInfo = null, tasksInfoReadable = null) {
this.taskInfoHash = taskInfoHash
this.vulnerabilityType = vulnerabilityType
this.contextInfo = contextInfo
// values are not changed once the class is created, no need to recalculate hashCode every time
const hash = Utils.createHashObject()
hash.update(this.taskInfoHash)
hash.update(this.vulnerabilityType)
if(contextInfo !== null)
hash.update(JSON.origStringify(this.contextInfo))
this.hashCode = hash.produce()
this.tasksInfoReadable = tasksInfoReadable
}
hashCode () {
return this.hashCode
}
equals (other) {
return this.vulnerabilityType === other.vulnerabilityType && this.hashCode === other.hashCode
}
}
module.exports.verifyReplaceSanitizationOn = function (source, old, replacement, parameters) {
// Sanitization always need to be checked as a group. As such, they are always added to the source tasks list to be validated later.
if (!TaintTracker.isObjectTainted(source)) return
const task = new SanitizeByReplaceTask(old, new global.origError(), parameters, replacement)
source[taintedData].addToTaskList(task)
}
module.exports.verifyReplaceAllSanitizationOn = function (source, old, replacement, parameters) {
// Sanitization always need to be checked as a group. As such, they are always added to the source tasks list to be validated later.
if (!TaintTracker.isObjectTainted(source)) return
const task = new SanitizeByReplaceAllTask(old, new global.origError(), parameters, replacement)
source[taintedData].addToTaskList(task)
}
module.exports.verifyValidationOn = function (ret, source, regex, parameters, validationMethod) {
if (!TaintTracker.isObjectTainted(source)) return
const task = new ValidateByRegexTask(ret, regex, new global.origError(), parameters, validationMethod)
source[taintedData].addToTaskList(task)
}
module.exports.getVerifiedState = function (taskInfoHash, vulnerability, vulnerabilityContext =null, tasksInfoReadable =null) {
return verifiedMethods.get(new module.exports.VerificationInfo(taskInfoHash, vulnerability, vulnerabilityContext, tasksInfoReadable))
}
module.exports.getSignature = function (taskInfoHash, vulnerability, vulnerabilityContext =null, tasksInfoReadable =null) {
let info = new module.exports.VerificationInfo(taskInfoHash, vulnerability, vulnerabilityContext)
return info.hashCode
}
module.exports.setSignatureAsVerified = function (taskInfoHash, vulnerability, state, sinkInfo, vulnerabilityContext =null, tasksInfoReadable =null) {
const info = new module.exports.VerificationInfo(taskInfoHash, vulnerability, vulnerabilityContext, tasksInfoReadable)
const signature = info.tasksInfoReadable == null ? info.hashCode : info.tasksInfoReadable
Logger.eventLog.info(`Signature ${signature} is validated for vulnerability ${info.vulnerabilityType}`)
// maybe it is possible that while the sink task was processing, another thread added the exact same key
const vData = verifiedMethods.get(info)
if (vData != null) {
if (vData.verifiedOk !== state) {
Logger.eventLog.error(`Validation cache already have validation value with different status for signature ${info.hashCode} and vulnerability ${info.vulnerabilityType}`)
}
return
}
verifiedMethods.set(info, { verifiedOk: state, sinkInfo: sinkInfo })
}