@@ -533,6 +533,80 @@ class ReporterTest extends DDSpecification {
533533 batch. vulnerabilities. size() == 2
534534 }
535535
536+ void ' two cookie vulnerabilities that share location share stackId and only generate one stack' () {
537+ given :
538+ final Reporter reporter = new Reporter ()
539+ final traceSegment = Mock (TraceSegment )
540+ final ctx = new IastRequestContext (noOpTaintedObjects())
541+ final reqCtx = Mock (RequestContext )
542+ final spanId = 123456
543+ VulnerabilityBatch batch = null
544+ Map stackTraceBatch = new ConcurrentHashMap ()
545+
546+ final span = Stub (AgentSpan )
547+ span. getRequestContext() >> reqCtx
548+ span. getSpanId() >> spanId
549+
550+ final location = Location . forSpanAndStack(span, new StackTraceElement (" foo" , " foo" , " foo" , 1 ))
551+
552+ final v1 = new Vulnerability (
553+ VulnerabilityType . INSECURE_COOKIE ,
554+ location,
555+ new Evidence (" JSESSIONID" )
556+ )
557+ final v2 = new Vulnerability (
558+ VulnerabilityType . NO_SAMESITE_COOKIE ,
559+ location,
560+ new Evidence (" JSESSIONID" )
561+ )
562+
563+ when :
564+ reporter. report(span, v1)
565+ reporter. report(span, v2)
566+
567+ then :
568+ 1 * reqCtx. getData(RequestContextSlot . IAST ) >> ctx
569+ 2 * reqCtx. getTraceSegment() >> traceSegment
570+ // first vulnerability
571+ 1 * traceSegment. getDataTop(' iast' ) >> null
572+ 1 * traceSegment. setDataTop(' iast' , _) >> { batch = it[1 ] as VulnerabilityBatch }
573+ 1 * reqCtx. getOrCreateMetaStructTop(' _dd.stack' , _) >> { stackTraceBatch }
574+ // second vulnerability
575+ 1 * traceSegment. getDataTop(' iast' ) >> { return batch } // second vulnerability
576+ JSONAssert . assertEquals (''' {
577+ "vulnerabilities": [
578+ {
579+ "evidence": { "value":"JSESSIONID" },
580+ "hash":1156210466,
581+ "location": {
582+ "spanId":123456,
583+ "line":1,
584+ "path":"foo",
585+ "method": "foo",
586+ "stackId":"1"
587+ },
588+ "type":"INSECURE_COOKIE"
589+ },
590+ {
591+ "evidence": {"value":"JSESSIONID"},
592+ "hash":1090504969,
593+ "location": {
594+ "spanId":123456,
595+ "line":1,
596+ "path":"foo",
597+ "method": "foo",
598+ "stackId":"1"
599+ },
600+ "type":"NO_SAMESITE_COOKIE"
601+ }
602+ ]
603+ }''' , batch. toString(), true )
604+ 1 * traceSegment. setTagTop(' asm.keep' , true )
605+ 1 * traceSegment. setTagTop(' _dd.p.ts' , ProductTraceSource . ASM )
606+ assert stackTraceBatch. get(" vulnerability" ). size() == 1
607+ 0 * _
608+ }
609+
536610 private AgentSpan spanWithBatch (final VulnerabilityBatch batch ) {
537611 final traceSegment = Mock (TraceSegment ) {
538612 getDataTop(' iast' ) >> batch
0 commit comments