Skip to content

Commit 005e6b3

Browse files
committed
fix(appsec): perform _after extractions on the blocking_response 
1 parent 9c93e47 commit 005e6b3

File tree

3 files changed

+55
-30
lines changed

3 files changed

+55
-30
lines changed

.vscode/settings.json

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
{
22
"python.pythonPath": "/usr/local/bin/python3",
33
"python.formatting.provider": "black",
4-
"python.testing.unittestArgs": ["-v", "-s", "./tests", "-p", "test*.py"],
5-
"python.testing.pytestEnabled": false,
6-
"python.testing.unittestEnabled": true
7-
}
4+
"python.testing.unittestArgs": [
5+
"-v",
6+
"-s",
7+
"./tests",
8+
"-p",
9+
"test*.py"
10+
],
11+
"python.testing.pytestEnabled": true,
12+
"python.testing.unittestEnabled": false
13+
}

datadog_lambda/wrapper.py

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,30 @@ def _before(self, event, context):
284284
def _after(self, event, context):
285285
try:
286286
status_code = extract_http_status_code_tag(self.trigger_tags, self.response)
287+
288+
if self.span:
289+
if config.appsec_enabled and not self.blocking_response:
290+
asm_start_response(
291+
self.span,
292+
status_code,
293+
self.event_source,
294+
response=self.response,
295+
)
296+
self.blocking_response = get_asm_blocked_response(self.event_source)
297+
298+
if self.blocking_response:
299+
status_code = self.blocking_response.get("statusCode")
300+
self.response = self.blocking_response
301+
302+
if config.capture_payload_enabled:
303+
tag_object(self.span, "function.request", event)
304+
tag_object(self.span, "function.response", self.response)
305+
306+
if status_code:
307+
self.span.set_tag("http.status_code", status_code)
308+
309+
self.span.finish()
310+
287311
if status_code:
288312
self.trigger_tags["http.status_code"] = status_code
289313
mark_trace_as_error_for_5xx_responses(context, status_code, self.span)
@@ -298,25 +322,6 @@ def _after(self, event, context):
298322
if should_trace_cold_start:
299323
trace_ctx = tracer.current_trace_context()
300324

301-
if self.span:
302-
if config.capture_payload_enabled:
303-
tag_object(self.span, "function.request", event)
304-
tag_object(self.span, "function.response", self.response)
305-
306-
if status_code:
307-
self.span.set_tag("http.status_code", status_code)
308-
309-
if config.appsec_enabled and not self.blocking_response:
310-
asm_start_response(
311-
self.span,
312-
status_code,
313-
self.event_source,
314-
response=self.response,
315-
)
316-
self.blocking_response = get_asm_blocked_response(self.event_source)
317-
318-
self.span.finish()
319-
320325
if self.inferred_span:
321326
if status_code:
322327
self.inferred_span.set_tag("http.status_code", status_code)

tests/test_wrapper.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,9 @@ def setUp(self):
690690
self.mock_get_asm_blocking_response = patcher.start()
691691
self.addCleanup(patcher.stop)
692692

693+
with open("tests/event_samples/api-gateway.json") as f:
694+
self.api_gateway_request = json.loads(f.read())
695+
693696
self.fake_blocking_response = {
694697
"statusCode": "403",
695698
"headers": {
@@ -706,7 +709,7 @@ def test_blocking_before(self):
706709

707710
lambda_handler = wrapper.datadog_lambda_wrapper(mock_handler)
708711

709-
response = lambda_handler({}, get_mock_context())
712+
response = lambda_handler(self.api_gateway_request, get_mock_context())
710713
self.assertEqual(response, self.fake_blocking_response)
711714

712715
mock_handler.assert_not_called()
@@ -715,27 +718,31 @@ def test_blocking_before(self):
715718
self.mock_asm_start_request.assert_called_once()
716719
self.mock_asm_start_response.assert_not_called()
717720

721+
assert lambda_handler.span.get_tag("http.status_code") == "403"
722+
718723
def test_blocking_during(self):
719724
self.mock_get_asm_blocking_response.return_value = None
720725

721-
@wrapper.datadog_lambda_wrapper
722726
def lambda_handler(event, context):
723727
self.mock_get_asm_blocking_response.return_value = (
724728
self.fake_blocking_response
725729
)
726730
raise wrapper.BlockingException()
727731

728-
response = lambda_handler({}, get_mock_context())
732+
lambda_handler = wrapper.datadog_lambda_wrapper(lambda_handler)
733+
734+
response = lambda_handler(self.api_gateway_request, get_mock_context())
729735
self.assertEqual(response, self.fake_blocking_response)
730736

731737
self.mock_asm_set_context.assert_called_once()
732738
self.mock_asm_start_request.assert_called_once()
733739
self.mock_asm_start_response.assert_not_called()
734740

741+
assert lambda_handler.span.get_tag("http.status_code") == "403"
742+
735743
def test_blocking_after(self):
736744
self.mock_get_asm_blocking_response.return_value = None
737745

738-
@wrapper.datadog_lambda_wrapper
739746
def lambda_handler(event, context):
740747
self.mock_get_asm_blocking_response.return_value = (
741748
self.fake_blocking_response
@@ -745,13 +752,17 @@ def lambda_handler(event, context):
745752
"body": "This should not be returned",
746753
}
747754

748-
response = lambda_handler({}, get_mock_context())
755+
lambda_handler = wrapper.datadog_lambda_wrapper(lambda_handler)
756+
757+
response = lambda_handler(self.api_gateway_request, get_mock_context())
749758
self.assertEqual(response, self.fake_blocking_response)
750759

751760
self.mock_asm_set_context.assert_called_once()
752761
self.mock_asm_start_request.assert_called_once()
753762
self.mock_asm_start_response.assert_called_once()
754763

764+
assert lambda_handler.span.get_tag("http.status_code") == "403"
765+
755766
def test_no_blocking_appsec_disabled(self):
756767
os.environ["DD_APPSEC_ENABLED"] = "false"
757768

@@ -764,14 +775,17 @@ def test_no_blocking_appsec_disabled(self):
764775
"body": "This should be returned",
765776
}
766777

767-
@wrapper.datadog_lambda_wrapper
768778
def lambda_handler(event, context):
769779
return expected_response
770780

771-
response = lambda_handler({}, get_mock_context())
781+
lambda_handler = wrapper.datadog_lambda_wrapper(lambda_handler)
782+
783+
response = lambda_handler(self.api_gateway_request, get_mock_context())
772784
self.assertEqual(response, expected_response)
773785

774786
self.mock_get_asm_blocking_response.assert_not_called()
775787
self.mock_asm_set_context.assert_not_called()
776788
self.mock_asm_start_request.assert_not_called()
777789
self.mock_asm_start_response.assert_not_called()
790+
791+
assert lambda_handler.span.get_tag("http.status_code") == "200"

0 commit comments

Comments
 (0)