Skip to content

Commit a2529a3

Browse files
feat(aap): add redirect request support for api10 on urllib
1 parent 2590370 commit a2529a3

File tree

5 files changed

+28
-9
lines changed

5 files changed

+28
-9
lines changed

.github/workflows/system-tests.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545
persist-credentials: false
4646
repository: 'DataDog/system-tests'
4747
# Automatically managed, use scripts/update-system-tests-version to update
48-
ref: '2eb26336ed43c2db1b7f90fff17ce4f5fc36a12b'
48+
ref: '6127593e1f1a6ce1b89bcba0ad83f51129974d6b'
4949

5050
- name: Download wheels to binaries directory
5151
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
@@ -90,7 +90,7 @@ jobs:
9090
persist-credentials: false
9191
repository: 'DataDog/system-tests'
9292
# Automatically managed, use scripts/update-system-tests-version to update
93-
ref: '2eb26336ed43c2db1b7f90fff17ce4f5fc36a12b'
93+
ref: '6127593e1f1a6ce1b89bcba0ad83f51129974d6b'
9494

9595
- name: Build runner
9696
uses: ./.github/actions/install_runner
@@ -275,7 +275,7 @@ jobs:
275275
persist-credentials: false
276276
repository: 'DataDog/system-tests'
277277
# Automatically managed, use scripts/update-system-tests-version to update
278-
ref: '2eb26336ed43c2db1b7f90fff17ce4f5fc36a12b'
278+
ref: '6127593e1f1a6ce1b89bcba0ad83f51129974d6b'
279279
- name: Download wheels to binaries directory
280280
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
281281
with:

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ variables:
1414
DD_VPA_TEMPLATE: "vpa-template-cpu-p70-10percent-2x-oom-min-cap"
1515
# CI_DEBUG_SERVICES: "true"
1616
# Automatically managed, use scripts/update-system-tests-version to update
17-
SYSTEM_TESTS_REF: "2eb26336ed43c2db1b7f90fff17ce4f5fc36a12b"
17+
SYSTEM_TESTS_REF: "6127593e1f1a6ce1b89bcba0ad83f51129974d6b"
1818

1919
default:
2020
interruptible: true

ddtrace/appsec/_asm_request_context.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,8 @@ class DownstreamRequests:
155155

156156

157157
def should_analyze_body_response(env) -> bool:
158-
"""Must be called only after should_analyze_downstream returned True."""
158+
"""Check if we should analyze body for API10."""
159159
DownstreamRequests.counter += 1
160-
env.downstream_requests += 1
161160
return (
162161
env.downstream_requests <= asm_config._dr_body_limit_per_request
163162
and (DownstreamRequests.counter * KNUTH_FACTOR) % UINT64_MAX <= DownstreamRequests.sampling_rate

ddtrace/appsec/_common_module_patches.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from wrapt import FunctionWrapper
1414
from wrapt import resolve_path
1515

16+
from ddtrace.appsec._asm_request_context import _get_asm_context
1617
from ddtrace.appsec._asm_request_context import get_blocked
1718
from ddtrace.appsec._constants import EXPLOIT_PREVENTION
1819
from ddtrace.appsec._constants import WAF_ACTIONS
@@ -52,6 +53,7 @@ def _(module):
5253
try_wrap_function_wrapper(
5354
"urllib3.connectionpool", "HTTPConnectionPool._make_request", wrapped_urllib3_make_request
5455
)
56+
try_wrap_function_wrapper("urllib3.connectionpool", "HTTPConnectionPool.urlopen", wrapped_urllib3_urlopen)
5557
try_wrap_function_wrapper("urllib3._request_methods", "RequestMethods.request", wrapped_request_D8CB81E472AF98A2)
5658
try_wrap_function_wrapper("urllib3.request", "RequestMethods.request", wrapped_request_D8CB81E472AF98A2)
5759
try_wrap_function_wrapper("builtins", "open", wrapped_open_CFDDB7ABBA9081B6)
@@ -163,7 +165,8 @@ def wrapped_request(original_request_callable, instance, args, kwargs):
163165
from ddtrace.appsec._asm_request_context import call_waf_callback
164166

165167
full_url = core.get_item("full_url")
166-
if full_url is not None:
168+
env = _get_asm_context()
169+
if _get_rasp_capability("ssrf") and full_url is not None and env is not None:
167170
use_body = core.get_item("use_body", False)
168171
method = args[0] if len(args) > 0 else kwargs.get("method", None)
169172
body = args[2] if len(args) > 2 else kwargs.get("body", None)
@@ -180,6 +183,8 @@ def wrapped_request(original_request_callable, instance, args, kwargs):
180183
crop_trace="wrapped_open_ED4CF71136E15EBF",
181184
rule_type=EXPLOIT_PREVENTION.TYPE.SSRF_REQ,
182185
)
186+
env.downstream_requests += 1
187+
core.discard_item("full_url")
183188
if res and _must_block(res.actions):
184189
raise BlockingException(get_blocked(), EXPLOIT_PREVENTION.BLOCKING, EXPLOIT_PREVENTION.TYPE.SSRF, full_url)
185190
return original_request_callable(*args, **kwargs)
@@ -204,7 +209,6 @@ def wrapped_open_ED4CF71136E15EBF(original_open_callable, instance, args, kwargs
204209
"""
205210
if _get_rasp_capability("ssrf"):
206211
try:
207-
from ddtrace.appsec._asm_request_context import _get_asm_context
208212
from ddtrace.appsec._asm_request_context import call_waf_callback
209213
from ddtrace.appsec._asm_request_context import should_analyze_body_response
210214
except ImportError:
@@ -266,7 +270,8 @@ def wrapped_urllib3_make_request(original_request_callable, instance, args, kwar
266270
from ddtrace.appsec._asm_request_context import call_waf_callback
267271

268272
full_url = core.get_item("full_url")
269-
if full_url is not None:
273+
env = _get_asm_context()
274+
if _get_rasp_capability("ssrf") and full_url is not None and env is not None:
270275
use_body = core.get_item("use_body", False)
271276
method = args[1] if len(args) > 1 else kwargs.get("method", None)
272277
body = args[3] if len(args) > 3 else kwargs.get("body", None)
@@ -283,12 +288,23 @@ def wrapped_urllib3_make_request(original_request_callable, instance, args, kwar
283288
crop_trace="wrapped_request_D8CB81E472AF98A2",
284289
rule_type=EXPLOIT_PREVENTION.TYPE.SSRF_REQ,
285290
)
291+
env.downstream_requests += 1
286292
core.discard_item("full_url")
287293
if res and _must_block(res.actions):
288294
raise BlockingException(get_blocked(), EXPLOIT_PREVENTION.BLOCKING, EXPLOIT_PREVENTION.TYPE.SSRF, full_url)
289295
return original_request_callable(*args, **kwargs)
290296

291297

298+
def wrapped_urllib3_urlopen(original_open_callable, instance, args, kwargs):
299+
full_url = args[2] if len(args) > 2 else kwargs.get("url", None)
300+
if core.get_item("full_url") is None:
301+
core.set_item("full_url", full_url)
302+
try:
303+
return original_open_callable(*args, **kwargs)
304+
finally:
305+
core.discard_item("full_url")
306+
307+
292308
def wrapped_request_D8CB81E472AF98A2(original_request_callable, instance, args, kwargs):
293309
"""
294310
wrapper for third party requests.request function
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
features:
3+
- |
4+
AAP: This introduces proper support for API10 for redirected requests on urllib3

0 commit comments

Comments
 (0)