Skip to content

Commit

Permalink
Added span_id to the AppSec events (#7132)
Browse files Browse the repository at this point in the history
* Added spanId in reported AppSec events

* Fixed tests
  • Loading branch information
ValentinZakharov committed Jun 6, 2024
1 parent 505a089 commit 95319d2
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import datadog.trace.api.gateway.Flow;
import datadog.trace.api.telemetry.LogCollector;
import datadog.trace.api.telemetry.WafMetricCollector;
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
import io.sqreen.powerwaf.Additive;
import io.sqreen.powerwaf.Powerwaf;
import io.sqreen.powerwaf.PowerwafConfig;
Expand Down Expand Up @@ -580,6 +582,12 @@ private AppSecEvent buildEvent(PowerWAFResultData wafResult) {
ruleMatchList.add(ruleMatch);
}

Long spanId = null;
AgentSpan agentSpan = AgentTracer.get().activeSpan();
if (agentSpan != null) {
spanId = agentSpan.getSpanId();
}

return new AppSecEvent.Builder()
.withRule(
new Rule.Builder()
Expand All @@ -588,6 +596,7 @@ private AppSecEvent buildEvent(PowerWAFResultData wafResult) {
.withTags(wafResult.rule.tags)
.build())
.withRuleMatches(ruleMatchList)
.withSpanId(spanId)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class AppSecEvent {

Expand All @@ -11,18 +12,21 @@ public class AppSecEvent {
@com.squareup.moshi.Json(name = "rule_matches")
private List<RuleMatch> ruleMatches = new ArrayList<>();

@com.squareup.moshi.Json(name = "span_id")
private Long spanId;

public Rule getRule() {
return rule;
}

public void setRule(Rule rule) {
this.rule = rule;
}

public List<RuleMatch> getRuleMatches() {
return ruleMatches;
}

public Long getSpanId() {
return spanId;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Expand All @@ -38,6 +42,9 @@ public String toString() {
sb.append('=');
sb.append(((this.ruleMatches == null) ? "<null>" : this.ruleMatches));
sb.append(',');
sb.append("spanId");
sb.append('=');
sb.append(((this.spanId == null) ? "<null>" : this.spanId));
if (sb.charAt((sb.length() - 1)) == ',') {
sb.setCharAt((sb.length() - 1), ']');
} else {
Expand All @@ -51,6 +58,7 @@ public int hashCode() {
int result = 1;
result = ((result * 31) + ((this.rule == null) ? 0 : this.rule.hashCode()));
result = ((result * 31) + ((this.ruleMatches == null) ? 0 : this.ruleMatches.hashCode()));
result = ((result * 31) + ((this.spanId == null) ? 0 : this.spanId.hashCode()));
return result;
}

Expand All @@ -63,9 +71,9 @@ public boolean equals(Object other) {
return false;
}
AppSecEvent rhs = ((AppSecEvent) other);
return (((this.rule == rhs.rule) || ((this.rule != null) && this.rule.equals(rhs.rule)))
&& ((this.ruleMatches == rhs.ruleMatches)
|| ((this.ruleMatches != null) && this.ruleMatches.equals(rhs.ruleMatches))));
return ((Objects.equals(this.rule, rhs.rule))
&& (Objects.equals(this.ruleMatches, rhs.ruleMatches))
&& (Objects.equals(this.spanId, rhs.spanId)));
}

public static class Builder {
Expand All @@ -92,5 +100,10 @@ public Builder withRuleMatches(List<RuleMatch> ruleMatches) {
this.instance.ruleMatches = ruleMatches;
return this;
}

public Builder withSpanId(Long spanId) {
this.instance.spanId = spanId;
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ import datadog.trace.api.ConfigDefaults
import datadog.trace.api.internal.TraceSegment
import datadog.appsec.api.blocking.BlockingContentType
import datadog.trace.api.gateway.Flow
import datadog.trace.bootstrap.instrumentation.api.AgentSpan
import datadog.trace.bootstrap.instrumentation.api.AgentTracer
import datadog.trace.test.util.DDSpecification
import io.sqreen.powerwaf.Additive
import io.sqreen.powerwaf.Powerwaf
import io.sqreen.powerwaf.PowerwafContext
import io.sqreen.powerwaf.PowerwafMetrics
import spock.lang.Shared
import spock.lang.Unroll

import java.util.concurrent.CountDownLatch
Expand All @@ -35,9 +38,19 @@ import static datadog.trace.api.config.AppSecConfig.APPSEC_OBFUSCATION_PARAMETER
import static org.hamcrest.Matchers.hasSize

class PowerWAFModuleSpecification extends DDSpecification {
@Shared
protected static final AgentTracer.TracerAPI ORIGINAL_TRACER = AgentTracer.get()

private static final DataBundle ATTACK_BUNDLE = MapDataBundle.of(KnownAddresses.HEADERS_NO_COOKIES,
new CaseInsensitiveMap<List<String>>(['user-agent': 'Arachni/v0']))

protected AgentTracer.TracerAPI tracer = Mock(AgentTracer.TracerAPI) {
activeSpan() >> Mock(AgentSpan) {
getSpanId() >> 777
}
getSpanId() >> 777
}

AppSecRequestContext ctx = Spy()

StubAppSecConfigService service
Expand All @@ -47,7 +60,12 @@ class PowerWAFModuleSpecification extends DDSpecification {
Additive pwafAdditive
PowerwafMetrics metrics

void setup() {
AgentTracer.forceRegister(tracer)
}

void cleanup() {
AgentTracer.forceRegister(ORIGINAL_TRACER)
pwafAdditive?.close()
release pwafModule
}
Expand Down Expand Up @@ -185,6 +203,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getOrCreateAdditive(_ as PowerwafContext, true) >> {
pwafAdditive = it[0].openAdditive()
}
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.getWafMetrics()
1 * ctx.closeAdditive()
Expand Down Expand Up @@ -216,6 +235,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getOrCreateAdditive(_ as PowerwafContext, true) >> {
pwafAdditive = it[0].openAdditive()
}
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.getWafMetrics()
2 * ctx.closeAdditive()
Expand Down Expand Up @@ -255,6 +275,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getOrCreateAdditive(_ as PowerwafContext, true) >> {
pwafAdditive = it[0].openAdditive()
}
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.getWafMetrics()
1 * ctx.closeAdditive()
Expand All @@ -277,6 +298,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getOrCreateAdditive(_ as PowerwafContext, true) >> {
pwafAdditive = it[0].openAdditive()
}
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.getWafMetrics()
1 * ctx.closeAdditive()
Expand Down Expand Up @@ -331,6 +353,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getOrCreateAdditive(_ as PowerwafContext, true) >> {
pwafAdditive = it[0].openAdditive()
}
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.getWafMetrics()
1 * ctx.closeAdditive()
Expand Down Expand Up @@ -405,6 +428,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getOrCreateAdditive(_, true) >> {
pwafAdditive = it[0].openAdditive()
}
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.getWafMetrics()
1 * ctx.closeAdditive() >> { pwafAdditive.close() }
Expand Down Expand Up @@ -483,6 +507,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getOrCreateAdditive(_, true) >> {
pwafAdditive = it[0].openAdditive()
}
2 * tracer.activeSpan()
// we get two events: one for origin rule, and one for the custom one
1 * ctx.reportEvents(hasSize(2))
1 * ctx.getWafMetrics()
Expand Down Expand Up @@ -558,6 +583,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
rba.blockingContentType == BlockingContentType.AUTO
})
1 * ctx.getOrCreateAdditive(_, true) >> { it[0].openAdditive() }
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.getWafMetrics()
1 * ctx.closeAdditive()
Expand Down Expand Up @@ -757,6 +783,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
.withHighlight(['Arachni/v'])
.build()
]
event.spanId == 777
}

void 'redaction with default settings'() {
Expand Down Expand Up @@ -957,6 +984,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
then:
1 * reconf.reloadSubscriptions()
1 * ctx.getOrCreateAdditive(_, true) >> { pwafAdditive = it[0].openAdditive() }
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.getWafMetrics()
1 * flow.setAction({ it.blocking })
Expand Down Expand Up @@ -1055,6 +1083,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * reconf.reloadSubscriptions()
1 * ctx.getOrCreateAdditive(_, true) >> {
pwafAdditive = it[0].openAdditive() }
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.getWafMetrics()
1 * flow.setAction({ it.blocking })
Expand Down Expand Up @@ -1157,6 +1186,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getWafMetrics()
1 * flow.isBlocking()
1 * flow.setAction({ it.blocking })
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>)
1 * ctx.closeAdditive() >> {pwafAdditive.close()}
_ * ctx.increaseTimeouts()
Expand Down Expand Up @@ -1287,6 +1317,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
then:
1 * ctx.getOrCreateAdditive(_, true) >> {
pwafAdditive = it[0].openAdditive() }
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>) >> {
it[0].iterator().next().ruleMatches[0].parameters[0].value == '/cybercop'
}
Expand All @@ -1302,6 +1333,7 @@ class PowerWAFModuleSpecification extends DDSpecification {
1 * ctx.getOrCreateAdditive(_, true) >> {
pwafAdditive }
1 * flow.setAction({ it.blocking })
1 * tracer.activeSpan()
1 * ctx.reportEvents(_ as Collection<AppSecEvent>) >> {
it[0].iterator().next().ruleMatches[0].parameters[0].value == 'user-to-block-1'
}
Expand Down

0 comments on commit 95319d2

Please sign in to comment.