From 786db744a2b95bf18310d764b16e3636d385d578 Mon Sep 17 00:00:00 2001 From: Igor Unanua Date: Mon, 23 Sep 2024 15:09:00 +0200 Subject: [PATCH] Delay Appsec fs plugin subscription to fs:operations until the first req is received --- packages/dd-trace/src/appsec/rasp/lfi.js | 15 +++++++++++---- packages/dd-trace/test/appsec/rasp/lfi.spec.js | 17 +++++++++++++++-- .../test/appsec/response_blocking.spec.js | 4 ++-- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/packages/dd-trace/src/appsec/rasp/lfi.js b/packages/dd-trace/src/appsec/rasp/lfi.js index 9f5058585bb..3453fb1afee 100644 --- a/packages/dd-trace/src/appsec/rasp/lfi.js +++ b/packages/dd-trace/src/appsec/rasp/lfi.js @@ -1,6 +1,6 @@ 'use strict' -const { fsOperationStart } = require('../channels') +const { fsOperationStart, incomingHttpRequestStart } = require('../channels') const { storage } = require('../../../../datadog-core') const { enable: enableFsPlugin, disable: disableFsPlugin } = require('./fs-plugin') const { FS_OPERATION_PATH } = require('../addresses') @@ -13,17 +13,24 @@ let config function enable (_config) { config = _config - enableFsPlugin('rasp') - - fsOperationStart.subscribe(analyzeLfi) + incomingHttpRequestStart.subscribe(onFirstReceivedRequest) } function disable () { if (fsOperationStart.hasSubscribers) fsOperationStart.unsubscribe(analyzeLfi) + if (incomingHttpRequestStart.hasSubscribers) incomingHttpRequestStart.unsubscribe(onFirstReceivedRequest) disableFsPlugin('rasp') } +function onFirstReceivedRequest () { + incomingHttpRequestStart.unsubscribe(onFirstReceivedRequest) + + enableFsPlugin('rasp') + + fsOperationStart.subscribe(analyzeLfi) +} + function analyzeLfi (ctx) { const store = storage.getStore() if (!store) return diff --git a/packages/dd-trace/test/appsec/rasp/lfi.spec.js b/packages/dd-trace/test/appsec/rasp/lfi.spec.js index f0af3a14143..549f682338a 100644 --- a/packages/dd-trace/test/appsec/rasp/lfi.spec.js +++ b/packages/dd-trace/test/appsec/rasp/lfi.spec.js @@ -1,7 +1,7 @@ 'use strict' const proxyquire = require('proxyquire') -const { fsOperationStart } = require('../../../src/appsec/channels') +const { fsOperationStart, incomingHttpRequestStart } = require('../../../src/appsec/channels') const { FS_OPERATION_PATH } = require('../../../src/appsec/addresses') describe('RASP - lfi.js', () => { @@ -49,6 +49,9 @@ describe('RASP - lfi.js', () => { } } + sinon.spy(incomingHttpRequestStart, 'subscribe') + sinon.spy(incomingHttpRequestStart, 'unsubscribe') + lfi.enable(config) }) @@ -58,8 +61,14 @@ describe('RASP - lfi.js', () => { }) describe('enable', () => { - it('should enable AppsecFsPlugin', () => { + it('should subscribe to first http req', () => { + sinon.assert.calledOnce(incomingHttpRequestStart.subscribe) + }) + + it('should enable AppsecFsPlugin after the first request', () => { + incomingHttpRequestStart.publish({}) sinon.assert.calledOnceWithExactly(appsecFsPlugin.enable, 'rasp') + sinon.assert.calledOnce(incomingHttpRequestStart.unsubscribe) }) }) @@ -75,6 +84,10 @@ describe('RASP - lfi.js', () => { const ctx = { path } const req = {} + beforeEach(() => { + incomingHttpRequestStart.publish({}) + }) + it('should analyze lfi for root fs operations', () => { const fs = { root: true } datadogCore.storage.getStore.returns({ req, fs }) diff --git a/packages/dd-trace/test/appsec/response_blocking.spec.js b/packages/dd-trace/test/appsec/response_blocking.spec.js index c200967b138..3be218322fb 100644 --- a/packages/dd-trace/test/appsec/response_blocking.spec.js +++ b/packages/dd-trace/test/appsec/response_blocking.spec.js @@ -9,7 +9,7 @@ const path = require('path') const WafContext = require('../../src/appsec/waf/waf_context_wrapper') const blockingResponse = JSON.parse(require('../../src/appsec/blocked_templates').json) const fs = require('fs') -const { disable: disableFsPlugin } = require('../../src/appsec/rasp/fs-plugin') +const { disable: disableLfi } = require('../../src/appsec/rasp/lfi') describe('HTTP Response Blocking', () => { let server @@ -57,7 +57,7 @@ describe('HTTP Response Blocking', () => { } })) - disableFsPlugin('rasp') + disableLfi() }) beforeEach(() => {