Skip to content

Commit 2389ec3

Browse files
authored
fix(appsec): perform _after extractions on the blocking_response (#656)
1 parent b171bda commit 2389ec3

File tree

2 files changed

+49
-26
lines changed

2 files changed

+49
-26
lines changed

datadog_lambda/wrapper.py

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,34 @@ 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 = str(self.blocking_response.get("statusCode"))
300+
if config.capture_payload_enabled and self.response:
301+
tag_object(
302+
self.span, "function.blocked_response", self.response
303+
)
304+
self.response = self.blocking_response
305+
306+
if config.capture_payload_enabled:
307+
tag_object(self.span, "function.request", event)
308+
tag_object(self.span, "function.response", self.response)
309+
310+
if status_code:
311+
self.span.set_tag("http.status_code", status_code)
312+
313+
self.span.finish()
314+
287315
if status_code:
288316
self.trigger_tags["http.status_code"] = status_code
289317
mark_trace_as_error_for_5xx_responses(context, status_code, self.span)
@@ -298,25 +326,6 @@ def _after(self, event, context):
298326
if should_trace_cold_start:
299327
trace_ctx = tracer.current_trace_context()
300328

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-
320329
if self.inferred_span:
321330
if status_code:
322331
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)