diff --git a/manifests/dotnet.yml b/manifests/dotnet.yml index e7832d640a..973b567455 100644 --- a/manifests/dotnet.yml +++ b/manifests/dotnet.yml @@ -225,6 +225,7 @@ tests/: test_fingerprinting.py: Test_Fingerprinting_Endpoint: missing_feature Test_Fingerprinting_Header_And_Network: missing_feature + Test_Fingerprinting_Session: missing_feature test_identify.py: Test_Basic: v2.7.0 test_ip_blocking_full_denylist.py: diff --git a/manifests/golang.yml b/manifests/golang.yml index d245b51b30..193be9b522 100644 --- a/manifests/golang.yml +++ b/manifests/golang.yml @@ -303,6 +303,7 @@ tests/: test_fingerprinting.py: Test_Fingerprinting_Endpoint: missing_feature Test_Fingerprinting_Header_And_Network: missing_feature + Test_Fingerprinting_Session: missing_feature test_identify.py: Test_Basic: v1.37.0 test_ip_blocking_full_denylist.py: diff --git a/manifests/java.yml b/manifests/java.yml index 7b7921f88d..7345e707c4 100644 --- a/manifests/java.yml +++ b/manifests/java.yml @@ -908,6 +908,7 @@ tests/: Test_Fingerprinting_Header_And_Network: '*': v1.39.0 spring-boot-3-native: irrelevant (GraalVM. Tracing support only) + Test_Fingerprinting_Session: missing_feature test_identify.py: Test_Basic: missing_feature test_ip_blocking_full_denylist.py: diff --git a/manifests/nodejs.yml b/manifests/nodejs.yml index 1c8304b2f1..fc20061c9c 100644 --- a/manifests/nodejs.yml +++ b/manifests/nodejs.yml @@ -356,6 +356,7 @@ tests/: test_fingerprinting.py: Test_Fingerprinting_Endpoint: missing_feature Test_Fingerprinting_Header_And_Network: missing_feature + Test_Fingerprinting_Session: missing_feature test_identify.py: Test_Basic: v2.4.0 test_ip_blocking_full_denylist.py: diff --git a/manifests/php.yml b/manifests/php.yml index 97f9d7dc5c..1657d32217 100644 --- a/manifests/php.yml +++ b/manifests/php.yml @@ -180,6 +180,7 @@ tests/: test_fingerprinting.py: Test_Fingerprinting_Endpoint: missing_feature Test_Fingerprinting_Header_And_Network: missing_feature + Test_Fingerprinting_Session: missing_feature test_identify.py: Test_Basic: v0.85.0 test_logs.py: diff --git a/manifests/python.yml b/manifests/python.yml index 9e26df4f5f..5d8c7c34be 100644 --- a/manifests/python.yml +++ b/manifests/python.yml @@ -457,6 +457,7 @@ tests/: test_fingerprinting.py: Test_Fingerprinting_Endpoint: v2.11.0.dev Test_Fingerprinting_Header_And_Network: v2.11.0.dev + Test_Fingerprinting_Session: missing_feature (missing endpoint) test_identify.py: Test_Basic: v1.5.0rc1.dev test_ip_blocking_full_denylist.py: diff --git a/manifests/ruby.yml b/manifests/ruby.yml index fdeb1348ce..5364d7b08f 100644 --- a/manifests/ruby.yml +++ b/manifests/ruby.yml @@ -213,6 +213,7 @@ tests/: test_fingerprinting.py: Test_Fingerprinting_Endpoint: missing_feature Test_Fingerprinting_Header_And_Network: missing_feature + Test_Fingerprinting_Session: missing_feature test_identify.py: Test_Basic: v1.0.0 test_ip_blocking_full_denylist.py: diff --git a/tests/appsec/test_fingerprinting.py b/tests/appsec/test_fingerprinting.py index 03a2d33d71..01f71a094b 100644 --- a/tests/appsec/test_fingerprinting.py +++ b/tests/appsec/test_fingerprinting.py @@ -1,3 +1,5 @@ +import requests + from utils import features from utils import interfaces from utils import rfc @@ -63,3 +65,17 @@ def test_fingerprinting_endpoint(self): assert self.n.status_code == 200 assert all("_dd.appsec.fp.http.endpoint" in m for m in get_span_meta(self.r)) assert all("_dd.appsec.fp.http.endpoint" not in m for m in get_span_meta(self.n)) + + +@rfc("https://docs.google.com/document/d/1DivOa9XsCggmZVzMI57vyxH2_EBJ0-qqIkRHm_sEvSs/edit#heading=h.88xvn2cvs9dt") +@features.fingerprinting +class Test_Fingerprinting_Session: + def setup_session(self): + self.r_create_session = weblog.get("session/new") + self.cookies = self.r_create_session.cookies + self.r_user = weblog.get("session/user?sdk_user=sdkUser", cookies=self.cookies,) + + def test_session(self): + assert self.r_create_session.status_code == 200 + assert self.r_user.status_code == 200 + assert all("_dd.appsec.fp.session" in m for m in get_span_meta(self.r_user)) diff --git a/utils/_weblog.py b/utils/_weblog.py index e7e0e4b6e6..76099979fb 100644 --- a/utils/_weblog.py +++ b/utils/_weblog.py @@ -64,6 +64,7 @@ def __init__(self, data): self.status_code = data["status_code"] self.headers = CaseInsensitiveDict(data.get("headers", {})) self.text = data["text"] + self.cookies = data["cookies"] def serialize(self) -> dict: return self._data | {"__class__": "HttpResponse"} @@ -141,6 +142,7 @@ def request( "status_code": None, "headers": {}, "text": None, + "cookies": None, } timeout = kwargs.pop("timeout", 5) @@ -150,10 +152,12 @@ def request( r.url = url logger.debug(f"Sending request {rid}: {method} {url}") - r = requests.Session().send(r, timeout=timeout, stream=stream, allow_redirects=allow_redirects) + s = requests.Session() + r = s.send(r, timeout=timeout, stream=stream, allow_redirects=allow_redirects) response_data["status_code"] = r.status_code response_data["headers"] = r.headers response_data["text"] = r.text + response_data["cookies"] = requests.utils.dict_from_cookiejar(s.cookies) except Exception as e: logger.error(f"Request {rid} raise an error: {e}") diff --git a/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/App.java b/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/App.java index e14c36ca85..1e4298fd1b 100644 --- a/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/App.java +++ b/utils/build/docker/java/spring-boot/src/main/java/com/datadoghq/system_tests/springboot/App.java @@ -20,6 +20,7 @@ import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import datadog.appsec.api.blocking.Blocking; +import datadog.trace.api.EventTracker; import datadog.trace.api.Trace; import datadog.trace.api.experimental.*; import datadog.trace.api.interceptor.MutableSpan; @@ -56,7 +57,9 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -64,6 +67,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.time.Instant; +import java.util.Collections; import java.util.Scanner; import java.util.LinkedHashMap; @@ -158,6 +162,19 @@ String postWafXml(@RequestBody XmlObject object) { return object.toString(); } + @GetMapping(value = "/session/new") + ResponseEntity newSession(final HttpServletRequest request) { + final HttpSession session = request.getSession(true); + return ResponseEntity.ok(session.getId()); + } + + @GetMapping(value = "/session/user") + ResponseEntity userSession(@RequestParam("sdk_user") final String sdkUser, final HttpServletRequest request) { + EventTracker tracker = datadog.trace.api.GlobalTracer.getEventTracker(); + tracker.trackLoginSuccessEvent(sdkUser, Collections.emptyMap()); + return ResponseEntity.ok(request.getRequestedSessionId()); + } + @RequestMapping("/status") ResponseEntity status(@RequestParam Integer code) { return new ResponseEntity<>(HttpStatus.valueOf(code));