UNPKG

@hclsoftware/secagent

Version:

IAST agent

144 lines (118 loc) 4.38 kB
//IASTIGNORE /* * **************************************************** * Licensed Materials - Property of HCL. * (c) Copyright HCL Technologies Ltd. 2017, 2025. * Note to U.S. Government Users *Restricted Rights. * **************************************************** */ 'use strict' const Entity = require('./Entity') const TaskType = require('./Tasks/TaskType') const Utils = require('./Utils/Utils') const {keys} = require("./AdditionalInfo"); const lodash = require("lodash"); class TaintedObjectDataFlow { constructor(requestInfo, entityName, entityValue, entityType) { this.requestInfo = requestInfo this.sanitized = [] this.entity = new Entity.Entity(entityName, entityValue, entityType) this.stackInfoList = [] this.taskList = [] this.hasSanitationTask = false this.hasValidationTask = false this.reported = new Set() this.hashValue = null this.stackArray = null this.stackString = null this.sinkStackString = null this.additionalInfo = {} this.storedDataForTelemetryIssue = null } isTaintedForVulnerability(vulnerability) { return this.isTainted() && !this.sanitized.origArrayIncludes(vulnerability) } getCopy() { const copy = new TaintedObjectDataFlow(this.requestInfo, this.entity.name, this.entity.value, this.entity.type) copy.sanitized = [...this.sanitized] copy.stackInfoList = [...this.stackInfoList] copy.taskList = [...this.taskList] copy.hasSanitationTask = this.hasSanitationTask copy.hasValidationTask = this.hasValidationTask copy.additionalInfo = lodash.cloneDeep(this.additionalInfo); copy.storedDataForTelemetryIssue = this.storedDataForTelemetryIssue === null ? null : Object.assign({}, this.storedDataForTelemetryIssue); return copy } addToTaskList(task) { if (task.type === TaskType.VALIDATION) { this.hasValidationTask = true } else if (task.type === TaskType.SANITIZATION) { this.hasSanitationTask = true } this.taskList.push(task) } addToStackInfoList(stackInfo) { this.stackInfoList.push(stackInfo) } sanitize(vulnerability) { this.sanitized.push(vulnerability) } isReported(vulnerability) { return this.reported.has(vulnerability) } addToReported(vulnerability) { this.reported.add(vulnerability) } getHashValue() { return this.hashValue } getStackArray() { return this.stackArray } getStackString() { if (this.stackString == null) { this.stackString = JSON.origStringify(this.stackArray) } return this.stackString } updateEntity(entityName, entityValue, entityType) { this.entity = new Entity.Entity(entityName, entityValue, entityType) } updateStackAndHashForReporting(vulnerability) { let hash = Utils.createHashObject() const jsonOutput = [] if (this.requestInfo.routePath !== undefined) hash.update(this.requestInfo.routePath) else if (this.requestInfo.uri !== undefined) hash.update(this.requestInfo.uri) if (this.requestInfo.method !== undefined) { hash.update(this.requestInfo.method) } if (vulnerability != null) { hash.update(vulnerability) } if (this.entity.type !== undefined) { hash.update(this.entity.type) } if (this.entity.name !== undefined) { hash.update(this.entity.name) } for (const item of this.stackInfoList) { // must update stack before its hash: item.updateStack() jsonOutput.push(item) hash.update(item.updateHash(vulnerability)) } // update values in flow this.stackArray = jsonOutput this.hashValue = hash.produce() // The Hash object can not be used again after hash.digest() method has been called. Multiple calls will cause an error to be thrown } getSinkStackString() { return this.sinkStackString } setSinkStackString(sinkStackString) { this.sinkStackString = sinkStackString } addAdditionalInfo(info) { Object.assign(this.additionalInfo, info) } addAdditionalInfoElementToArray(info) { for (const property in info) { if (!this.additionalInfo.hasOwnProperty(property)) { this.additionalInfo[property] = [info[property]] } else { this.additionalInfo[property].push(info[property]) } } } isTainted() { return this.additionalInfo[keys.SANITIZED] === undefined } } module.exports = TaintedObjectDataFlow