Skip to content

Commit a5ff9ce

Browse files
committed
merge mess up
1 parent 319f187 commit a5ff9ce

File tree

1 file changed

+112
-19
lines changed

1 file changed

+112
-19
lines changed

dd-java-agent/appsec/src/test/groovy/com/datadog/appsec/ddwaf/WAFModuleSpecification.groovy

Lines changed: 112 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import spock.lang.Unroll
5353
import java.util.concurrent.CountDownLatch
5454
import java.util.concurrent.atomic.AtomicLong
5555

56+
import static datadog.trace.api.config.AppSecConfig.APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP
5657
import static datadog.trace.api.config.AppSecConfig.APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP
5758
import static org.hamcrest.Matchers.hasSize
5859

@@ -688,6 +689,31 @@ class WAFModuleSpecification extends DDSpecification {
688689
wafModule.name == 'ddwaf'
689690
}
690691

692+
void 'report waf stats on first span'() {
693+
TraceSegment segment = Mock()
694+
TraceSegmentPostProcessor pp
695+
initialRuleAdd()
696+
readyToHandle()
697+
698+
when:
699+
pp = service.traceSegmentPostProcessors.first()
700+
pp.processTraceSegment(segment, ctx, [])
701+
702+
then:
703+
1 * segment.setTagTop('_dd.appsec.waf.version', _ as String)
704+
1 * segment.setTagTop('_dd.appsec.event_rules.loaded', 117)
705+
1 * segment.setTagTop('_dd.appsec.event_rules.error_count', 1)
706+
1 * segment.setTagTop('_dd.appsec.event_rules.errors', { it =~ /\{"[^"]+":\["bad rule"\]\}/})
707+
1 * segment.setTagTop('asm.keep', true)
708+
0 * segment._(*_)
709+
710+
when:
711+
pp.processTraceSegment(segment, ctx, [])
712+
713+
then:
714+
0 * segment._(*_)
715+
}
716+
691717
void 'triggers a rule through the user agent header'() {
692718
initialRuleAdd()
693719
ChangeableFlow flow = new ChangeableFlow()
@@ -712,7 +738,6 @@ class WAFModuleSpecification extends DDSpecification {
712738
}
713739

714740
void 'no metrics are set if waf metrics are off'() {
715-
setup:
716741
metrics = null
717742
injectSysConfig('appsec.waf.metrics', 'false')
718743
wafModule = new WAFModule() // replace the one created too soon
@@ -736,6 +761,39 @@ class WAFModuleSpecification extends DDSpecification {
736761
metrics == null
737762
}
738763

764+
void 'reports waf metrics'() {
765+
setup:
766+
TraceSegment segment = Mock()
767+
TraceSegmentPostProcessor pp
768+
Flow flow = new ChangeableFlow()
769+
initialRuleAdd()
770+
readyToHandle()
771+
772+
when:
773+
pp = service.traceSegmentPostProcessors[1]
774+
dataListener.onDataAvailable(flow, ctx, ATTACK_BUNDLE, gwCtx)
775+
ctx.closeWafContext()
776+
pp.processTraceSegment(segment, ctx, [])
777+
778+
then:
779+
1 * ctx.getOrCreateWafContext(_, false)
780+
1 * ctx.closeWafContext()
781+
3 * ctx.getWafMetrics() >> {
782+
metrics.with {
783+
totalDdwafRunTimeNs = new AtomicLong(1000)
784+
totalRunTimeNs = new AtomicLong(2000)
785+
truncatedStringTooLongCount = new AtomicLong(0)
786+
truncatedListMapTooLargeCount = new AtomicLong(0)
787+
truncatedObjectTooDeepCount = new AtomicLong(0)
788+
it } }
789+
790+
1 * segment.setTagTop('_dd.appsec.waf.duration', 1)
791+
1 * segment.setTagTop('_dd.appsec.waf.duration_ext', 2)
792+
1 * segment.setTagTop('_dd.appsec.event_rules.version', '0.42.0')
793+
794+
0 * segment._(*_)
795+
}
796+
739797
void 'can trigger a nonwafContext waf run'() {
740798
initialRuleAdd()
741799
ChangeableFlow flow = new ChangeableFlow()
@@ -756,7 +814,6 @@ class WAFModuleSpecification extends DDSpecification {
756814
}
757815

758816
void 'reports events'() {
759-
setup:
760817
initialRuleAdd()
761818
AppSecEvent event
762819
StackTraceEvent stackTrace
@@ -816,6 +873,27 @@ class WAFModuleSpecification extends DDSpecification {
816873
event.ruleMatches[0].parameters[0].value == '<Redacted>'
817874
}
818875

876+
void 'disabling of key regex'() {
877+
injectSysConfig(APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP, '')
878+
initialRuleAdd()
879+
readyToHandle()
880+
AppSecEvent event
881+
882+
when:
883+
def bundle = MapDataBundle.of(KnownAddresses.HEADERS_NO_COOKIES,
884+
new CaseInsensitiveMap<List<String>>(['user-agent': [password: 'Arachni/v0']]))
885+
dataListener.onDataAvailable(Stub(ChangeableFlow), ctx, bundle, gwCtx)
886+
ctx.closeWafContext()
887+
888+
then:
889+
ctx.reportEvents(_ as Collection<AppSecEvent>) >> { event = it[0].iterator().next() }
890+
891+
event.ruleMatches[0].parameters[0].address == 'server.request.headers.no_cookies'
892+
event.ruleMatches[0].parameters[0].highlight == ['Arachni/v']
893+
event.ruleMatches[0].parameters[0].key_path == ['user-agent', 'password']
894+
event.ruleMatches[0].parameters[0].value == 'Arachni/v0'
895+
}
896+
819897
void 'redaction of values'() {
820898
injectSysConfig(APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP, 'Arachni')
821899

@@ -880,21 +958,43 @@ class WAFModuleSpecification extends DDSpecification {
880958
!flow.blocking
881959
}
882960

883-
void 'powerwaf exceptions do not propagate'() {
961+
void 'waf exceptions do not propagate'() {
884962
initialRuleAdd()
963+
readyToHandle()
885964
ChangeableFlow flow = new ChangeableFlow()
886965
DataBundle db = MapDataBundle.of(KnownAddresses.HEADERS_NO_COOKIES, [get: { null }] as List)
887966

888967
when:
968+
dataListener.onDataAvailable(flow, ctx, db, gwCtx)
969+
970+
then:
971+
1 * ctx.getOrCreateWafContext(_, false)
972+
2 * ctx.getWafMetrics()
973+
1 * ctx.setWafErrors()
974+
1 * wafMetricCollector.wafErrorCode(-127)
975+
2 * ctx.isWafContextClosed()
976+
assert !flow.blocking
977+
}
978+
979+
void 'timeout is honored (waf)'() {
980+
injectSysConfig('appsec.waf.timeout', '1')
981+
WAFModule.createLimitsObject()
982+
initialRuleAdd()
889983
readyToHandle()
984+
DataBundle db = MapDataBundle.of(KnownAddresses.HEADERS_NO_COOKIES,
985+
new CaseInsensitiveMap<List<String>>(['user-agent': 'Arachni/v' + ('a' * 4000)]))
986+
ChangeableFlow flow = new ChangeableFlow()
987+
988+
TraceSegment segment = Mock()
989+
TraceSegmentPostProcessor pp = service.traceSegmentPostProcessors.last()
990+
991+
when:
890992
dataListener.onDataAvailable(flow, ctx, db, gwCtx)
891993
892994
then:
893-
1 * ctx.getOrCreateWafContext(_, _)
894995
assert !flow.blocking
895996
1 * ctx.isWafContextClosed()
896-
1 * ctx.getOrCreateWafContext(_, true, false) >> {
897-
wafContext = it[0].openContext() }
997+
1 * ctx.getOrCreateWafContext(_, false)
898998
2 * ctx.getWafMetrics()
899999
1 * ctx.increaseWafTimeouts()
9001000
0 * _
@@ -912,12 +1012,12 @@ class WAFModuleSpecification extends DDSpecification {
9121012
}
9131013
9141014
void 'timeout is honored (rasp)'() {
915-
setup:
9161015
injectSysConfig('appsec.waf.timeout', '1')
9171016
WAFModule.createLimitsObject()
918-
setupWithStubConfigService()
1017+
initialRuleAdd()
1018+
readyToHandle()
9191019
DataBundle db = MapDataBundle.of(KnownAddresses.HEADERS_NO_COOKIES,
920-
new CaseInsensitiveMap<List<String>>(['user-agent': 'Arachni/v' + ('a' * 4000)]))
1020+
new CaseInsensitiveMap<List<String>>(['user-agent': 'Arachni/v' + ('a' * 4000)]))
9211021
ChangeableFlow flow = new ChangeableFlow()
9221022
9231023
TraceSegment segment = Mock()
@@ -929,12 +1029,9 @@ class WAFModuleSpecification extends DDSpecification {
9291029
dataListener.onDataAvailable(flow, ctx, db, gwCtx)
9301030
9311031
then:
932-
ctx.getOrCreateWafContext(_, true) >> {
933-
wafContext = it[0].openContext() }
9341032
assert !flow.blocking
9351033
1 * ctx.isWafContextClosed()
936-
1 * ctx.getOrCreateWafContext(_, true, true) >> {
937-
wafContext = it[0].openContext() }
1034+
1 * ctx.getOrCreateWafContext(_, true)
9381035
1 * ctx.getRaspMetrics()
9391036
1 * ctx.getRaspMetricsCounter()
9401037
1 * ctx.increaseRaspTimeouts()
@@ -1412,7 +1509,6 @@ class WAFModuleSpecification extends DDSpecification {
14121509
}
14131510

14141511
void 'honors appsec.trace.rate.limit'() {
1415-
setup:
14161512
injectSysConfig('dd.appsec.trace.rate.limit', '5')
14171513
def monitoring = Mock(Monitoring)
14181514

@@ -1579,7 +1675,6 @@ class WAFModuleSpecification extends DDSpecification {
15791675
}
15801676

15811677
void 'raspRuleSkipped if rasp available and WAF context is closed'() {
1582-
setup:
15831678
ChangeableFlow flow = Mock()
15841679
GatewayContext gwCtxMock = new GatewayContext(false, RuleType.SQL_INJECTION)
15851680

@@ -1603,7 +1698,6 @@ class WAFModuleSpecification extends DDSpecification {
16031698
}
16041699

16051700
void 'test raspErrorCode metric is increased when waf call throws #wafErrorCode '() {
1606-
setup:
16071701
ChangeableFlow flow = Mock()
16081702
GatewayContext gwCtxMock = new GatewayContext(false, RuleType.SQL_INJECTION)
16091703
WafContext wafContext = Mock()
@@ -1634,7 +1728,6 @@ class WAFModuleSpecification extends DDSpecification {
16341728
}
16351729

16361730
void 'test wafErrorCode metric is increased when waf call throws #wafErrorCode '() {
1637-
setup:
16381731
ChangeableFlow flow = Mock()
16391732
WafContext wafContext = Mock()
16401733

@@ -1672,11 +1765,11 @@ class WAFModuleSpecification extends DDSpecification {
16721765
}
16731766

16741767
void 'report waf stats on first span'() {
1675-
setup:
16761768
TraceSegment segment = Mock()
1769+
initialRuleAdd()
1770+
readyToHandle()
16771771

16781772
when:
1679-
initialRuleAdd()
16801773
service.traceSegmentPostProcessors.first().processTraceSegment(segment, ctx, [])
16811774

16821775
then:

0 commit comments

Comments
 (0)