Skip to content

Commit

Permalink
move standalone products, tracesource, prioritySampler, etc
Browse files Browse the repository at this point in the history
  • Loading branch information
iunanua committed Feb 4, 2025
1 parent c0550a0 commit 3116b76
Show file tree
Hide file tree
Showing 20 changed files with 304 additions and 181 deletions.
3 changes: 2 additions & 1 deletion packages/dd-trace/src/appsec/channels.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ module.exports = {
wafRunFinished: dc.channel('datadog:waf:run:finish'),
fsOperationStart: dc.channel('apm:fs:operation:start'),
expressMiddlewareError: dc.channel('apm:express:middleware:error'),
childProcessExecutionTracingChannel: dc.tracingChannel('datadog:child_process:execution')
childProcessExecutionTracingChannel: dc.tracingChannel('datadog:child_process:execution'),
prioritySamplerConfigure: dc.channel('datadog:priority-sampler:configure')
}
11 changes: 10 additions & 1 deletion packages/dd-trace/src/appsec/iast/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ const {
const { IAST_ENABLED_TAG_KEY } = require('./tags')
const iastTelemetry = require('./telemetry')
const { enable: enableFsPlugin, disable: disableFsPlugin, IAST_MODULE } = require('../rasp/fs-plugin')
const RateLimiter = require('../../rate_limiter')

// TODO Change to `apm:http:server:request:[start|close]` when the subscription
// order of the callbacks can be enforce
const requestStart = dc.channel('dd-trace:incomingHttpRequestStart')
const requestClose = dc.channel('dd-trace:incomingHttpRequestEnd')
const iastResponseEnd = dc.channel('datadog:iast:response-end')

const prioritySamplerConfigure = dc.channel('datadog:priority-sampler:configure')
let isEnabled = false

function enable (config, _tracer) {
Expand All @@ -33,6 +34,9 @@ function enable (config, _tracer) {
enableTaintTracking(config.iast, iastTelemetry.verbosity)
requestStart.subscribe(onIncomingHttpRequestStart)
requestClose.subscribe(onIncomingHttpRequestEnd)
if (!config.apmTracing.enabled) {
prioritySamplerConfigure.subscribe(onPrioritySamplerConfigure)
}
overheadController.configure(config.iast)
overheadController.startGlobalContext()
vulnerabilityReporter.start(config, _tracer)
Expand All @@ -52,6 +56,7 @@ function disable () {
overheadController.finishGlobalContext()
if (requestStart.hasSubscribers) requestStart.unsubscribe(onIncomingHttpRequestStart)
if (requestClose.hasSubscribers) requestClose.unsubscribe(onIncomingHttpRequestEnd)
if (prioritySamplerConfigure.hasSubscribers) prioritySamplerConfigure.unsubscribe(onPrioritySamplerConfigure)
vulnerabilityReporter.stop()
}

Expand Down Expand Up @@ -101,4 +106,8 @@ function onIncomingHttpRequestEnd (data) {
}
}

function onPrioritySamplerConfigure ({ prioritySampler }) {
prioritySampler._limiter = new RateLimiter(1, 'minute')
}

module.exports = { enable, disable, onIncomingHttpRequestEnd, onIncomingHttpRequestStart }
6 changes: 2 additions & 4 deletions packages/dd-trace/src/appsec/iast/vulnerability-reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
const LRU = require('lru-cache')
const vulnerabilitiesFormatter = require('./vulnerabilities-formatter')
const { IAST_ENABLED_TAG_KEY, IAST_JSON_TAG_KEY } = require('./tags')
const standalone = require('../standalone')
const { SAMPLING_MECHANISM_APPSEC } = require('../../constants')
const { keepTrace } = require('../../priority_sampler')
const { reportStackTrace, getCallsiteFrames, canReportStackTrace, STACK_TRACE_NAMESPACES } = require('../stack_trace')
const { getOriginalPathAndLineFromSourceMap } = require('./taint-tracking/rewriter')
const { ASM } = require('../../standalone/product')

const VULNERABILITIES_KEY = 'vulnerabilities'
const VULNERABILITY_HASHES_MAX_SIZE = 1000
Expand Down Expand Up @@ -51,8 +50,7 @@ function addVulnerability (iastContext, vulnerability, callSiteFrames) {

if (!span) return

keepTrace(span, SAMPLING_MECHANISM_APPSEC)
standalone.sample(span)
keepTrace(span, ASM)

if (stackTraceEnabled && canReportStackTrace(span, maxStackTraces, STACK_TRACE_NAMESPACES.IAST)) {
const originalCallSiteList = callSiteFrames.map(callsite => replaceCallSiteFromSourceMap(callsite))
Expand Down
13 changes: 12 additions & 1 deletion packages/dd-trace/src/appsec/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const {
responseBody,
responseWriteHead,
responseSetHeader,
routerParam
routerParam,
prioritySamplerConfigure
} = require('./channels')
const waf = require('./waf')
const addresses = require('./addresses')
Expand All @@ -32,6 +33,7 @@ const UserTracking = require('./user_tracking')
const { storage } = require('../../../datadog-core')
const graphql = require('./graphql')
const rasp = require('./rasp')
const RateLimiter = require('../rate_limiter')

const responseAnalyzedSet = new WeakSet()

Expand Down Expand Up @@ -76,6 +78,10 @@ function enable (_config) {
responseWriteHead.subscribe(onResponseWriteHead)
responseSetHeader.subscribe(onResponseSetHeader)

if (!_config.apmTracing.enabled) {
prioritySamplerConfigure.subscribe(onPrioritySamplerConfigure)
}

isEnabled = true
config = _config
} catch (err) {
Expand Down Expand Up @@ -289,6 +295,10 @@ function handleResults (actions, req, res, rootSpan, abortController) {
}
}

function onPrioritySamplerConfigure ({ prioritySampler }) {
prioritySampler._limiter = new RateLimiter(1, 'minute')
}

function disable () {
isEnabled = false
config = null
Expand Down Expand Up @@ -318,6 +328,7 @@ function disable () {
if (responseBody.hasSubscribers) responseBody.unsubscribe(onResponseBody)
if (responseWriteHead.hasSubscribers) responseWriteHead.unsubscribe(onResponseWriteHead)
if (responseSetHeader.hasSubscribers) responseSetHeader.unsubscribe(onResponseSetHeader)
if (prioritySamplerConfigure.hasSubscribers) prioritySamplerConfigure.unsubscribe(onPrioritySamplerConfigure)
}

module.exports = {
Expand Down
11 changes: 3 additions & 8 deletions packages/dd-trace/src/appsec/reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ const {
getRequestMetrics
} = require('./telemetry')
const zlib = require('zlib')
const standalone = require('./standalone')
const { SAMPLING_MECHANISM_APPSEC } = require('../constants')
const { keepTrace } = require('../priority_sampler')
const { ASM } = require('../standalone/product')

// default limiter, configurable with setRateLimit()
let limiter = new Limiter(100)
Expand Down Expand Up @@ -129,9 +128,7 @@ function reportAttack (attackData) {
}

if (limiter.isAllowed()) {
keepTrace(rootSpan, SAMPLING_MECHANISM_APPSEC)

standalone.sample(rootSpan)
keepTrace(rootSpan, ASM)
}

// TODO: maybe add this to format.js later (to take decision as late as possible)
Expand Down Expand Up @@ -186,9 +183,7 @@ function finishRequest (req, res) {
if (metricsQueue.size) {
rootSpan.addTags(Object.fromEntries(metricsQueue))

keepTrace(rootSpan, SAMPLING_MECHANISM_APPSEC)

standalone.sample(rootSpan)
keepTrace(rootSpan, ASM)

metricsQueue.clear()
}
Expand Down
6 changes: 2 additions & 4 deletions packages/dd-trace/src/appsec/sdk/track_event.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
const log = require('../../log')
const { getRootSpan } = require('./utils')
const { setUserTags } = require('./set_user')
const standalone = require('../standalone')
const waf = require('../waf')
const { SAMPLING_MECHANISM_APPSEC } = require('../../constants')
const { keepTrace } = require('../../priority_sampler')
const addresses = require('../addresses')
const { ASM } = require('../../standalone/product')

function trackUserLoginSuccessEvent (tracer, user, metadata) {
// TODO: better user check here and in _setUser() ?
Expand Down Expand Up @@ -79,8 +78,7 @@ function trackEvent (eventName, fields, sdkMethodName, rootSpan) {

rootSpan.addTags(tags)

keepTrace(rootSpan, SAMPLING_MECHANISM_APPSEC)
standalone.sample(rootSpan)
keepTrace(rootSpan, ASM)
}

function runWaf (eventName, user) {
Expand Down
130 changes: 0 additions & 130 deletions packages/dd-trace/src/appsec/standalone.js

This file was deleted.

6 changes: 2 additions & 4 deletions packages/dd-trace/src/appsec/user_tracking.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ const log = require('../log')
const telemetry = require('./telemetry')
const addresses = require('./addresses')
const { keepTrace } = require('../priority_sampler')
const { SAMPLING_MECHANISM_APPSEC } = require('../constants')
const standalone = require('./standalone')
const waf = require('./waf')
const { ASM } = require('../standalone/product')

// the RFC doesn't include '_id', but it's common in MongoDB
const USER_ID_FIELDS = ['id', '_id', 'email', 'username', 'login', 'user']
Expand Down Expand Up @@ -154,8 +153,7 @@ function trackLogin (framework, login, user, success, rootSpan) {
persistent[addresses.LOGIN_FAILURE] = null
}

keepTrace(rootSpan, SAMPLING_MECHANISM_APPSEC)
standalone.sample(rootSpan)
keepTrace(rootSpan, ASM)

rootSpan.addTags(newTags)

Expand Down
13 changes: 10 additions & 3 deletions packages/dd-trace/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ class Config {

const defaults = setHiddenProperty(this, '_defaults', {})

this._setBoolean(defaults, 'apmTracing.enabled', true)
this._setValue(defaults, 'appsec.apiSecurity.enabled', true)
this._setValue(defaults, 'appsec.apiSecurity.sampleDelay', 30)
this._setValue(defaults, 'appsec.blockedTemplateGraphql', undefined)
Expand All @@ -456,7 +457,6 @@ class Config {
this._setValue(defaults, 'appsec.rateLimit', 100)
this._setValue(defaults, 'appsec.rules', undefined)
this._setValue(defaults, 'appsec.sca.enabled', null)
this._setValue(defaults, 'appsec.standalone.enabled', undefined)
this._setValue(defaults, 'appsec.stackTrace.enabled', true)
this._setValue(defaults, 'appsec.stackTrace.maxDepth', 32)
this._setValue(defaults, 'appsec.stackTrace.maxStackTraces', 2)
Expand Down Expand Up @@ -578,6 +578,7 @@ class Config {
DD_AGENT_HOST,
DD_API_SECURITY_ENABLED,
DD_API_SECURITY_SAMPLE_DELAY,
DD_APM_TRACING_ENABLED,
DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE,
DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING,
DD_APPSEC_ENABLED,
Expand Down Expand Up @@ -711,6 +712,10 @@ class Config {
tagger.add(tags, DD_TRACE_TAGS)
tagger.add(tags, DD_TRACE_GLOBAL_TAGS)

this._setBoolean(env, 'apmTracing.enabled', coalesce(
DD_APM_TRACING_ENABLED && isTrue(DD_APM_TRACING_ENABLED),
DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED && isFalse(DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED)
))
this._setBoolean(env, 'appsec.apiSecurity.enabled', coalesce(
DD_API_SECURITY_ENABLED && isTrue(DD_API_SECURITY_ENABLED),
DD_EXPERIMENTAL_API_SECURITY_ENABLED && isTrue(DD_EXPERIMENTAL_API_SECURITY_ENABLED)
Expand All @@ -734,7 +739,6 @@ class Config {
this._setString(env, 'appsec.rules', DD_APPSEC_RULES)
// DD_APPSEC_SCA_ENABLED is never used locally, but only sent to the backend
this._setBoolean(env, 'appsec.sca.enabled', DD_APPSEC_SCA_ENABLED)
this._setBoolean(env, 'appsec.standalone.enabled', DD_EXPERIMENTAL_APPSEC_STANDALONE_ENABLED)
this._setBoolean(env, 'appsec.stackTrace.enabled', DD_APPSEC_STACK_TRACE_ENABLED)
this._setValue(env, 'appsec.stackTrace.maxDepth', maybeInt(DD_APPSEC_MAX_STACK_TRACE_DEPTH))
this._envUnprocessed['appsec.stackTrace.maxDepth'] = DD_APPSEC_MAX_STACK_TRACE_DEPTH
Expand Down Expand Up @@ -906,6 +910,10 @@ class Config {

tagger.add(tags, options.tags)

this._setBoolean(opts, 'apmTracing.enabled', coalesce(
options.apmTracing?.enabled,
options.experimental?.appsec?.standalone && !options.experimental.appsec.standalone.enabled
))
this._setBoolean(opts, 'appsec.apiSecurity.enabled', options.appsec.apiSecurity?.enabled)
this._setValue(opts, 'appsec.blockedTemplateGraphql', maybeFile(options.appsec.blockedTemplateGraphql))
this._setValue(opts, 'appsec.blockedTemplateHtml', maybeFile(options.appsec.blockedTemplateHtml))
Expand All @@ -920,7 +928,6 @@ class Config {
this._setValue(opts, 'appsec.rateLimit', maybeInt(options.appsec.rateLimit))
this._optsUnprocessed['appsec.rateLimit'] = options.appsec.rateLimit
this._setString(opts, 'appsec.rules', options.appsec.rules)
this._setBoolean(opts, 'appsec.standalone.enabled', options.experimental?.appsec?.standalone?.enabled)
this._setBoolean(opts, 'appsec.stackTrace.enabled', options.appsec.stackTrace?.enabled)
this._setValue(opts, 'appsec.stackTrace.maxDepth', maybeInt(options.appsec.stackTrace?.maxDepth))
this._optsUnprocessed['appsec.stackTrace.maxDepth'] = options.appsec.stackTrace?.maxDepth
Expand Down
Loading

0 comments on commit 3116b76

Please sign in to comment.