@hclsoftware/secagent
Version:
IAST agent
85 lines (73 loc) • 3.85 kB
JavaScript
//IASTIGNORE
/*
* ****************************************************
* Licensed Materials - Property of HCL.
* (c) Copyright HCL Technologies Ltd. 2017, 2025.
* Note to U.S. Government Users *Restricted Rights.
* ****************************************************
*/
const BeforeRule = require("./BeforeRule");
const {keys} = require('../../AdditionalInfo')
const {getSenderTagsFromAdditionalInfoForItem} = require("../../TagsUtils");
const globals = require("../../Globals");
const TaintTracker = require("../../TaintTracker");
const {Vulnerability} = require("../../TaintTracker");
const StackInfo = require("../../StackInfo");
const K8sSinkTrigger = require("../Utils/K8sSinkUtils");
/**
* A BeforeRule that adds IAST_TAG header to the additional info of the flow before sending a message to RabbitMQServer.
* IAST_TAGis a unique identifier added to the message to track it. this has to be done before message is actually sent
* @class RabbitMQSenderRule
* @extends BeforeRule
* @see BeforeRule
*/
module.exports = class RabbitMQSenderRule extends BeforeRule {
doRule(hookValues) {
try {
if (!globals.IastK8sMode) {
return
}
// sender method signature: publish(exchange, routingKey, content, options)
// content is Buffer type
const param = hookValues.args[2]
if (TaintTracker.isItemTainted(param)) {
const parameters = StackInfo.getParamsStringArrayPostHook(hookValues.that, hookValues.simpleThat, hookValues.methodName, hookValues.simpleArgs, hookValues.simpleRet)
const entityName = param instanceof String || Buffer.isBuffer(param) ? "content" : ""
K8sSinkTrigger.sinkTrigger(param, [Vulnerability.PASSWORD_LEAKAGE_SENT_DATA], parameters, "message", entityName)
const updatedTagValues = getSenderTagsFromAdditionalInfoForItem(param)
this.setHeaderForSender(updatedTagValues, hookValues)
}
} catch (err) {
throw new Error("Unable to add IAST_TAG header to the publish in RabbitMQ Sender rule; Exception:" + err);
}
}
// sender method signature: publish(exchange, routingKey, content, options) {
setHeaderForSender(updatedTagValues, hookValues) {
// 3rd argument in the hookValues.args is a options object which has a header key and value, we need to add IAST_TAG header to it if it is there , if the key is not there we need to create it
let newArgs = hookValues.args;
let options = newArgs[3];
if (options === undefined) {
options = {}
newArgs[3] = options
}
if (options.headers === undefined) {
options.headers = {};
}
if (updatedTagValues !== null && updatedTagValues.size > 0) {
Object.assign(options.headers, {[keys.IAST_TAG.valueOf()]: Array.from(new Set(updatedTagValues)).join(", ")})
}
// update options argument with new header after updating additionalInfo
hookValues.updatedArgs = newArgs
}
}
// single header and single flow
// IssueAddInfo FlowAddInfo IssueAddInfo
// MsgHeaders MsgHeaders MsgHeaders MsgHeaders
// Sender|xxxx-0 -> xxxx-0|Receiver|xxxx-1|Sender|xxxx-1 -> xxxx-1|Receiver|xxxx-2
// |Receiver|xxxx-0|Sender|xxxx-0 -> xxxx-0|Receiver|xxxx-1
// multiple headers and multiple flows
// FlowAddInfo IssueAddInfo
// MsgHeaders MsgHeaders
// xxxx-0| |xxxx-1| |xxxx-1
// aaaa-1|Receiver|aaaa-2|Sender|aaaa-2
// bbbb-4| |bbbb-5| |bbbb-5