Skip to content

Commit 0de8b0e

Browse files
chore(asm): remove static cycles (#13154)
remove cycles with - _utils and _asm_request_context - _ddwaf and _metrics APPSEC-57233 ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)
1 parent 4d6134c commit 0de8b0e

File tree

8 files changed

+24
-17
lines changed

8 files changed

+24
-17
lines changed

ddtrace/appsec/_asm_request_context.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,13 @@ def set_body_response(body_response):
284284
# local import to avoid circular import
285285
from ddtrace.appsec._utils import parse_response_body
286286

287-
set_waf_address(SPAN_DATA_NAMES.RESPONSE_BODY, lambda: parse_response_body(body_response))
287+
set_waf_address(
288+
SPAN_DATA_NAMES.RESPONSE_BODY,
289+
lambda: parse_response_body(
290+
body_response,
291+
get_waf_address(SPAN_DATA_NAMES.RESPONSE_HEADERS_NO_COOKIES),
292+
),
293+
)
288294

289295

290296
def set_waf_address(address: str, value: Any) -> None:

ddtrace/appsec/_ddwaf/waf.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ def __init__(
5151
ruleset_map: Dict[str, Any],
5252
obfuscation_parameter_key_regexp: bytes,
5353
obfuscation_parameter_value_regexp: bytes,
54+
metrics,
5455
):
5556
# avoid circular import
56-
from ddtrace.appsec import _metrics
5757

58-
self.report_error = _metrics._set_waf_error_log
58+
self.report_error = metrics._set_waf_error_log
5959
config = ddwaf_config(
6060
key_regex=obfuscation_parameter_key_regexp, value_regex=obfuscation_parameter_value_regexp
6161
)
@@ -78,7 +78,7 @@ def __init__(
7878
info.errors,
7979
)
8080
self._default_ruleset = ruleset_map_object
81-
_metrics.ddwaf_version = version()
81+
metrics.ddwaf_version = version()
8282

8383
@property
8484
def required_data(self) -> List[str]:

ddtrace/appsec/_ddwaf/waf_mock.py

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def __init__(
3333
rules: Dict[str, Any],
3434
obfuscation_parameter_key_regexp: bytes,
3535
obfuscation_parameter_value_regexp: bytes,
36+
metrics,
3637
):
3738
self._handle = None
3839

ddtrace/appsec/_ddwaf/waf_stubs.py

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ def __init__(
120120
rules: Dict[str, Any],
121121
obfuscation_parameter_key_regexp: bytes,
122122
obfuscation_parameter_value_regexp: bytes,
123+
metrics,
123124
):
124125
pass
125126

ddtrace/appsec/_processor.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def delayed_init(self) -> None:
123123

124124
self.metrics = metrics
125125
self._ddwaf = DDWaf(
126-
self._rules, self.obfuscation_parameter_key_regexp, self.obfuscation_parameter_value_regexp
126+
self._rules, self.obfuscation_parameter_key_regexp, self.obfuscation_parameter_value_regexp, metrics
127127
)
128128
self.metrics._set_waf_init_metric(self._ddwaf.info, self._ddwaf.initialized)
129129
except Exception:

ddtrace/appsec/_utils.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# this module must not load any other unsafe appsec module directly
22

33
import collections
4+
import json
45
import logging
56
import typing
67
from typing import Any
@@ -11,7 +12,6 @@
1112

1213
from ddtrace.appsec._constants import API_SECURITY
1314
from ddtrace.appsec._constants import APPSEC
14-
from ddtrace.appsec._constants import SPAN_DATA_NAMES
1515
from ddtrace.internal._unpatched import unpatched_json_loads
1616
from ddtrace.internal.compat import to_unicode
1717
from ddtrace.internal.logger import get_logger
@@ -156,10 +156,9 @@ def __init__(self):
156156
self.error = 0
157157

158158

159-
def parse_response_body(raw_body):
159+
def parse_response_body(raw_body, headers):
160160
import xmltodict
161161

162-
from ddtrace.appsec import _asm_request_context
163162
from ddtrace.contrib.internal.trace_utils import _get_header_value_case_insensitive
164163

165164
if not raw_body:
@@ -168,7 +167,6 @@ def parse_response_body(raw_body):
168167
if isinstance(raw_body, dict):
169168
return raw_body
170169

171-
headers = _asm_request_context.get_waf_address(SPAN_DATA_NAMES.RESPONSE_HEADERS_NO_COOKIES)
172170
if not headers:
173171
return
174172
content_type = _get_header_value_case_insensitive(
@@ -310,8 +308,6 @@ def has_triggers(span) -> bool:
310308

311309

312310
def get_triggers(span) -> Any:
313-
import json
314-
315311
if asm_config._use_metastruct_for_triggers:
316312
return (span.get_struct_tag(APPSEC.STRUCT) or {}).get("triggers", None)
317313
json_payload = span.get_tag(APPSEC.JSON)

tests/appsec/appsec/api_security/test_schema_fuzz.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from hypothesis import strategies as st
55
import pytest
66

7+
from ddtrace.appsec import _metrics
78
import ddtrace.appsec._constants as constants
89
import ddtrace.appsec._ddwaf as ddwaf
910

@@ -12,7 +13,7 @@ def build_schema(obj):
1213
rules = {}
1314
with open(constants.DEFAULT.RULES, "r") as f_apisec:
1415
rules.update(json.load(f_apisec))
15-
waf = ddwaf.DDWaf(rules, b"", b"")
16+
waf = ddwaf.DDWaf(rules, b"", b"", _metrics)
1617
ctx = waf._at_request_start()
1718
res = waf.run(
1819
ctx,

tests/appsec/appsec/test_processor.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import pytest
77

88
from ddtrace.appsec import _asm_request_context
9+
from ddtrace.appsec import _metrics
910
from ddtrace.appsec._constants import APPSEC
1011
from ddtrace.appsec._constants import DEFAULT
1112
from ddtrace.appsec._constants import FINGERPRINTING
@@ -366,6 +367,7 @@ def test_ddwaf_not_raises_exception():
366367
rules_json,
367368
DEFAULT.APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP.encode("utf-8"),
368369
DEFAULT.APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP.encode("utf-8"),
370+
_metrics,
369371
)
370372

371373

@@ -495,7 +497,7 @@ def test_obfuscation_parameter_value_configured_matching(tracer):
495497
def test_ddwaf_run():
496498
with open(rules.RULES_GOOD_PATH) as rule_set:
497499
rules_json = json.loads(rule_set.read())
498-
_ddwaf = DDWaf(rules_json, b"", b"")
500+
_ddwaf = DDWaf(rules_json, b"", b"", _metrics)
499501
data = {
500502
"server.request.query": {},
501503
"server.request.headers.no_cookies": {"user-agent": "werkzeug/2.1.2", "host": "localhost"},
@@ -515,7 +517,7 @@ def test_ddwaf_run():
515517
def test_ddwaf_run_timeout():
516518
with open(rules.RULES_GOOD_PATH) as rule_set:
517519
rules_json = json.loads(rule_set.read())
518-
_ddwaf = DDWaf(rules_json, b"", b"")
520+
_ddwaf = DDWaf(rules_json, b"", b"", _metrics)
519521
data = {
520522
"server.request.path_params": {"param_{}".format(i): "value_{}".format(i) for i in range(100)},
521523
"server.request.cookies": {"attack{}".format(i): "1' or '1' = '{}'".format(i) for i in range(100)},
@@ -531,7 +533,7 @@ def test_ddwaf_run_timeout():
531533
def test_ddwaf_info():
532534
with open(rules.RULES_GOOD_PATH) as rule_set:
533535
rules_json = json.loads(rule_set.read())
534-
_ddwaf = DDWaf(rules_json, b"", b"")
536+
_ddwaf = DDWaf(rules_json, b"", b"", _metrics)
535537

536538
info = _ddwaf.info
537539
assert info.loaded == len(rules_json["rules"])
@@ -543,7 +545,7 @@ def test_ddwaf_info():
543545
def test_ddwaf_info_with_2_errors():
544546
with open(os.path.join(rules.ROOT_DIR, "rules-with-2-errors.json")) as rule_set:
545547
rules_json = json.loads(rule_set.read())
546-
_ddwaf = DDWaf(rules_json, b"", b"")
548+
_ddwaf = DDWaf(rules_json, b"", b"", _metrics)
547549

548550
info = _ddwaf.info
549551
assert info.loaded == 1
@@ -559,7 +561,7 @@ def test_ddwaf_info_with_2_errors():
559561
def test_ddwaf_info_with_3_errors():
560562
with open(os.path.join(rules.ROOT_DIR, "rules-with-3-errors.json")) as rule_set:
561563
rules_json = json.loads(rule_set.read())
562-
_ddwaf = DDWaf(rules_json, b"", b"")
564+
_ddwaf = DDWaf(rules_json, b"", b"", _metrics)
563565

564566
info = _ddwaf.info
565567
assert info.loaded == 1

0 commit comments

Comments
 (0)