Skip to content

Commit

Permalink
first version without smoke test
Browse files Browse the repository at this point in the history
  • Loading branch information
jandro996 committed Feb 16, 2024
1 parent 85a5f5a commit ffada9c
Show file tree
Hide file tree
Showing 12 changed files with 183 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class IastRequestContext implements IastContext, HasMetricCollector {
@Nullable private volatile String xForwardedProto;
@Nullable private volatile String contentType;
@Nullable private volatile String authorization;
@Nullable private volatile String referrer;

/**
* Use {@link IastRequestContext#IastRequestContext(TaintedObjects)} instead as we require more
Expand Down Expand Up @@ -99,6 +100,15 @@ public void setAuthorization(final String authorization) {
this.authorization = authorization;
}

@Nullable
public String getReferrer() {
return referrer;
}

public void setReferrer(final String referrer) {
this.referrer = referrer;
}

public OverheadContext getOverheadContext() {
return overheadContext;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.datadog.iast.sink.NoSameSiteCookieModuleImpl;
import com.datadog.iast.sink.PathTraversalModuleImpl;
import com.datadog.iast.sink.ReflectionInjectionModuleImpl;
import com.datadog.iast.sink.SessionRewritingModuleImpl;
import com.datadog.iast.sink.SqlInjectionModuleImpl;
import com.datadog.iast.sink.SsrfModuleImpl;
import com.datadog.iast.sink.StacktraceLeakModuleImpl;
Expand Down Expand Up @@ -126,7 +127,8 @@ private static Stream<IastModule> iastModules(final Dependencies dependencies) {
new ApplicationModuleImpl(dependencies),
new HardcodedSecretModuleImpl(dependencies),
new InsecureAuthProtocolModuleImpl(dependencies),
new ReflectionInjectionModuleImpl(dependencies));
new ReflectionInjectionModuleImpl(dependencies),
new SessionRewritingModuleImpl(dependencies));
}

private static void registerRequestStartedCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ private HttpRequestEndModule[] requestEndModules() {
return new HttpRequestEndModule[] {
InstrumentationBridge.HSTS_MISSING_HEADER_MODULE,
InstrumentationBridge.X_CONTENT_TYPE_HEADER_MODULE,
InstrumentationBridge.INSECURE_AUTH_PROTOCOL
InstrumentationBridge.INSECURE_AUTH_PROTOCOL,
InstrumentationBridge.SESSION_REWRITING
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ public interface VulnerabilityType {
new InjectionTypeImpl(
VulnerabilityTypes.REFLECTION_INJECTION, VulnerabilityMarks.REFLECTION_INJECTION_MARK);

VulnerabilityType SESSION_REWRITING =
new VulnerabilityTypeImpl(VulnerabilityTypes.SESSION_REWRITING);

String name();

/** A bit flag to ignore tainted ranges for this vulnerability. Set to 0 if none. */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.datadog.iast.sink;

import com.datadog.iast.Dependencies;
import com.datadog.iast.IastRequestContext;
import com.datadog.iast.model.Evidence;
import com.datadog.iast.model.VulnerabilityType;
import com.datadog.iast.overhead.Operations;
import datadog.trace.api.gateway.IGSpanInfo;
import datadog.trace.api.iast.IastContext;
import datadog.trace.api.iast.sink.SessionRewritingModule;
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
import java.util.Map;
import javax.annotation.Nullable;

public class SessionRewritingModuleImpl extends SinkModuleBase implements SessionRewritingModule {

private static final String JSESSIONID = ";jsessionid";

public SessionRewritingModuleImpl(Dependencies dependencies) {
super(dependencies);
}

@Override
public void onRequestEnd(IastContext ctx, IGSpanInfo igSpanInfo) {
if (!(ctx instanceof IastRequestContext)) {
return;
}
final IastRequestContext iastRequestContext = (IastRequestContext) ctx;
Map<String, Object> tags = igSpanInfo.getTags();
String url = (String) tags.get("http.url");
if (url == null || !url.contains(JSESSIONID)) {
return;
}
if (isIgnorableResponseCode((Integer) tags.get("http.status_code"))) {
return;
}
final AgentSpan span = AgentTracer.activeSpan();
if (!overheadController.consumeQuota(Operations.REPORT_VULNERABILITY, span)) {
return;
}
String reason = "URL: " + url;
String referrer = iastRequestContext.getReferrer();
if (referrer != null && !referrer.isEmpty()) {
reason = reason + " Referrer: " + referrer;
}
final Evidence result = new Evidence(reason);
report(span, VulnerabilityType.SESSION_REWRITING, result);
}

@Override
public boolean isIgnorableResponseCode(@Nullable Integer httpStatus) {
return httpStatus != null && httpStatus >= 400;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ public void addToContext(final IastRequestContext ctx, final String value) {
ctx.setAuthorization(value);
}
},
REFERRER("Referrer") {
@Override
public void addToContext(final IastRequestContext ctx, final String value) {
ctx.setReferrer(value);
}
},
COOKIE("Cookie"),
SET_COOKIE("Set-Cookie"),
SET_COOKIE2("Set-Cookie2"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class IastSystemTest extends DDSpecification {
1 * iastContext.getxContentTypeOptions() >> 'nosniff'
1 * iastContext.getStrictTransportSecurity() >> 'max-age=35660'
1 * iastContext.getAuthorization()
1 * iastContext.getReferrer()
0 * _
noExceptionThrown()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.datadog.iast.sink

import com.datadog.iast.IastModuleImplTestBase
import com.datadog.iast.Reporter
import com.datadog.iast.RequestEndedHandler
import com.datadog.iast.model.Vulnerability
import com.datadog.iast.model.VulnerabilityType
import datadog.trace.api.gateway.Flow
import datadog.trace.api.iast.InstrumentationBridge
import datadog.trace.api.iast.sink.InsecureAuthProtocolModule
import datadog.trace.api.iast.sink.SessionRewritingModule
import datadog.trace.api.internal.TraceSegment

class SessionRewritingModuleTest extends IastModuleImplTestBase{

private static final REFERRER_URL = "https://localhost:8080/insecure/login.html"
private static final JSESSIONID_URL = REFERRER_URL + ";jsessionid=1A530637289A03B07199A44E8D531427"
private static final EVIDENCE = "URL: "+ JSESSIONID_URL
private static final REFERRER_EVIDENCE = EVIDENCE + " Referrer: " + REFERRER_URL

private SessionRewritingModule module

def setup() {
InstrumentationBridge.clearIastModules()
module = new SessionRewritingModuleImpl(dependencies)
InstrumentationBridge.registerIastModule(module)
}

@Override
protected Reporter buildReporter() {
return Mock(Reporter)
}

@Override
protected TraceSegment buildTraceSegment() {
return Mock(TraceSegment)
}

void 'check session rewriting'() {
given:
final handler = new RequestEndedHandler(dependencies)
span.getTags() >> [
'http.status_code': status_code,
'http.url' : url
]
if(referrer != null){
ctx.referrer = referrer
}


when:
def flow = handler.apply(reqCtx, span)

then:
flow.getAction() == Flow.Action.Noop.INSTANCE
flow.getResult() == null
1 * traceSegment.setTagTop("_dd.iast.enabled", 1)
if (expected != null) {
1 * reporter.report(_, _) >> { args -> assertEvidence(args[1] as Vulnerability, expected) }
} else {
0 * reporter.report(_, _)
}

where:
url | referrer | status_code | expected
JSESSIONID_URL | REFERRER_URL | 200 | REFERRER_EVIDENCE
JSESSIONID_URL | null | 200 | EVIDENCE
JSESSIONID_URL | null | 300 | EVIDENCE
JSESSIONID_URL | null | 400 | null
REFERRER_URL | REFERRER_URL | 200 | null
}

void 'ignore if context is null'(){
when:
module.onRequestEnd(null, null)

then:
0 * _
}


private static void assertVulnerability(final Vulnerability vuln) {
assert vuln != null
assert vuln.getType() == VulnerabilityType.SESSION_REWRITING
assert vuln.getLocation() != null
}

private static void assertEvidence(final Vulnerability vuln, final String expected) {
assertVulnerability(vuln)
final evidence = vuln.getEvidence()
assert evidence != null
assert evidence.value == expected
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import datadog.trace.api.iast.sink.NoSameSiteCookieModule;
import datadog.trace.api.iast.sink.PathTraversalModule;
import datadog.trace.api.iast.sink.ReflectionInjectionModule;
import datadog.trace.api.iast.sink.SessionRewritingModule;
import datadog.trace.api.iast.sink.SqlInjectionModule;
import datadog.trace.api.iast.sink.SsrfModule;
import datadog.trace.api.iast.sink.StacktraceLeakModule;
Expand Down Expand Up @@ -65,6 +66,7 @@ public abstract class InstrumentationBridge {
public static HardcodedSecretModule HARDCODED_SECRET;
public static InsecureAuthProtocolModule INSECURE_AUTH_PROTOCOL;
public static ReflectionInjectionModule REFLECTION_INJECTION;
public static SessionRewritingModule SESSION_REWRITING;

private static final Map<Class<? extends IastModule>, Field> MODULE_MAP = buildModuleMap();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ private VulnerabilityTypes() {}
public static final byte HARDCODED_SECRET = 25;
public static final byte INSECURE_AUTH_PROTOCOL = 26;
public static final byte REFLECTION_INJECTION = 27;
public static final byte SESSION_REWRITING = 28;

/**
* Use for telemetry only, this is a special vulnerability type that is not reported, reported
Expand Down Expand Up @@ -108,7 +109,8 @@ private VulnerabilityTypes() {}
"ADMIN_CONSOLE_ACTIVE",
"HARDCODED_SECRET",
"INSECURE_AUTH_PROTOCOL",
"REFLECTION_INJECTION"
"REFLECTION_INJECTION",
"SESSION_REWRITING"
};

public static String toString(final byte vulnerability) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package datadog.trace.api.iast.sink;

public interface SessionRewritingModule extends HttpRequestEndModule {}
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ class VulnerabilityTypesTest extends DDSpecification {
VulnerabilityTypes.HARDCODED_SECRET | 'HARDCODED_SECRET'
VulnerabilityTypes.INSECURE_AUTH_PROTOCOL | 'INSECURE_AUTH_PROTOCOL'
VulnerabilityTypes.REFLECTION_INJECTION | 'REFLECTION_INJECTION'
VulnerabilityTypes.SESSION_REWRITING | 'SESSION_REWRITING'
}
}

0 comments on commit ffada9c

Please sign in to comment.