Skip to content

Commit 997a12e

Browse files
chore(asm): remove circular dependencies (#13191)
PR to remove all static circular import from appsec - split iast_request_context module into 2 to avoid circular references with several other iast modules - change several import statement to avoid cycles - small test updates for import - move several functions from ddtrace.contrib.internal.trace_utils to ddtrace.contrib.internal.trace_utils_base to avoid further circular dependencies most remaining static circular imports are related to `ddtrace.contrib.internal.trace_utils` ## 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 0f76e0a commit 997a12e

File tree

24 files changed

+323
-261
lines changed

24 files changed

+323
-261
lines changed

benchmarks/appsec_iast_aspects/scenario.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@
55
with override_env({"DD_IAST_ENABLED": "True"}):
66
# from ddtrace.appsec._iast import oce
77
try:
8-
# 2.15+
9-
from ddtrace.appsec._iast._iast_request_context import end_iast_context
10-
from ddtrace.appsec._iast._iast_request_context import set_iast_request_enabled
11-
from ddtrace.appsec._iast._iast_request_context import start_iast_context
8+
# 3.6+
9+
from ddtrace.appsec._iast._iast_request_context_base import end_iast_context
10+
from ddtrace.appsec._iast._iast_request_context_base import set_iast_request_enabled
11+
from ddtrace.appsec._iast._iast_request_context_base import start_iast_context
1212
except ImportError:
13-
# Pre 2.15
14-
from ddtrace.appsec._iast._taint_tracking._context import create_context as start_iast_context
15-
from ddtrace.appsec._iast._taint_tracking._context import reset_context as end_iast_context
16-
17-
set_iast_request_enabled = lambda x: None # noqa: E731
13+
# Pre 3.6
14+
try:
15+
from ddtrace.appsec._iast._iast_request_context import end_iast_context
16+
from ddtrace.appsec._iast._iast_request_context import set_iast_request_enabled
17+
from ddtrace.appsec._iast._iast_request_context import start_iast_context
18+
except ImportError:
19+
# Pre 2.15
20+
from ddtrace.appsec._iast._taint_tracking._context import create_context as start_iast_context
21+
from ddtrace.appsec._iast._taint_tracking._context import reset_context as end_iast_context
22+
23+
set_iast_request_enabled = lambda x: None # noqa: E731
1824

1925

2026
def _start_iast_context_and_oce():

benchmarks/appsec_iast_aspects_ospath/scenario.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@
55
with override_env({"DD_IAST_ENABLED": "True"}):
66
# from ddtrace.appsec._iast import oce
77
try:
8-
# 2.15+
9-
from ddtrace.appsec._iast._iast_request_context import end_iast_context
10-
from ddtrace.appsec._iast._iast_request_context import set_iast_request_enabled
11-
from ddtrace.appsec._iast._iast_request_context import start_iast_context
8+
# 3.6+
9+
from ddtrace.appsec._iast._iast_request_context_base import end_iast_context
10+
from ddtrace.appsec._iast._iast_request_context_base import set_iast_request_enabled
11+
from ddtrace.appsec._iast._iast_request_context_base import start_iast_context
1212
except ImportError:
13-
# Pre 2.15
14-
from ddtrace.appsec._iast._taint_tracking._context import create_context as start_iast_context
15-
from ddtrace.appsec._iast._taint_tracking._context import reset_context as end_iast_context
16-
17-
set_iast_request_enabled = lambda x: None # noqa: E731
13+
# Pre 3.6
14+
try:
15+
from ddtrace.appsec._iast._iast_request_context import end_iast_context
16+
from ddtrace.appsec._iast._iast_request_context import set_iast_request_enabled
17+
from ddtrace.appsec._iast._iast_request_context import start_iast_context
18+
except ImportError:
19+
# Pre 2.15
20+
from ddtrace.appsec._iast._taint_tracking._context import create_context as start_iast_context
21+
from ddtrace.appsec._iast._taint_tracking._context import reset_context as end_iast_context
22+
23+
set_iast_request_enabled = lambda x: None # noqa: E731
1824

1925

2026
def _start_iast_context_and_oce():

benchmarks/appsec_iast_aspects_re_module/scenario.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@
55
with override_env({"DD_IAST_ENABLED": "True"}):
66
# from ddtrace.appsec._iast import oce
77
try:
8-
# 2.15+
9-
from ddtrace.appsec._iast._iast_request_context import end_iast_context
10-
from ddtrace.appsec._iast._iast_request_context import set_iast_request_enabled
11-
from ddtrace.appsec._iast._iast_request_context import start_iast_context
8+
# 3.6+
9+
from ddtrace.appsec._iast._iast_request_context_base import end_iast_context
10+
from ddtrace.appsec._iast._iast_request_context_base import set_iast_request_enabled
11+
from ddtrace.appsec._iast._iast_request_context_base import start_iast_context
1212
except ImportError:
13-
# Pre 2.15
14-
from ddtrace.appsec._iast._taint_tracking._context import create_context as start_iast_context
15-
from ddtrace.appsec._iast._taint_tracking._context import reset_context as end_iast_context
16-
17-
set_iast_request_enabled = lambda x: None # noqa: E731
13+
# Pre 3.6
14+
try:
15+
from ddtrace.appsec._iast._iast_request_context import end_iast_context
16+
from ddtrace.appsec._iast._iast_request_context import set_iast_request_enabled
17+
from ddtrace.appsec._iast._iast_request_context import start_iast_context
18+
except ImportError:
19+
# Pre 2.15
20+
from ddtrace.appsec._iast._taint_tracking._context import create_context as start_iast_context
21+
from ddtrace.appsec._iast._taint_tracking._context import reset_context as end_iast_context
22+
23+
set_iast_request_enabled = lambda x: None # noqa: E731
1824

1925

2026
def _start_iast_context_and_oce():

benchmarks/appsec_iast_aspects_split/scenario.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@
55
with override_env({"DD_IAST_ENABLED": "True"}):
66
# from ddtrace.appsec._iast import oce
77
try:
8-
# 2.15+
9-
from ddtrace.appsec._iast._iast_request_context import end_iast_context
10-
from ddtrace.appsec._iast._iast_request_context import set_iast_request_enabled
11-
from ddtrace.appsec._iast._iast_request_context import start_iast_context
8+
# 3.6+
9+
from ddtrace.appsec._iast._iast_request_context_base import end_iast_context
10+
from ddtrace.appsec._iast._iast_request_context_base import set_iast_request_enabled
11+
from ddtrace.appsec._iast._iast_request_context_base import start_iast_context
1212
except ImportError:
13-
# Pre 2.15
14-
from ddtrace.appsec._iast._taint_tracking._context import create_context as start_iast_context
15-
from ddtrace.appsec._iast._taint_tracking._context import reset_context as end_iast_context
16-
17-
set_iast_request_enabled = lambda x: None # noqa: E731
13+
# Pre 3.6
14+
try:
15+
from ddtrace.appsec._iast._iast_request_context import end_iast_context
16+
from ddtrace.appsec._iast._iast_request_context import set_iast_request_enabled
17+
from ddtrace.appsec._iast._iast_request_context import start_iast_context
18+
except ImportError:
19+
# Pre 2.15
20+
from ddtrace.appsec._iast._taint_tracking._context import create_context as start_iast_context
21+
from ddtrace.appsec._iast._taint_tracking._context import reset_context as end_iast_context
22+
23+
set_iast_request_enabled = lambda x: None # noqa: E731
1824

1925

2026
def _start_iast_context_and_oce():

benchmarks/appsec_iast_propagation/scenario.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
import bm
22

3-
from ddtrace.appsec._iast._iast_request_context import end_iast_context
4-
from ddtrace.appsec._iast._iast_request_context import set_iast_request_enabled
5-
from ddtrace.appsec._iast._iast_request_context import start_iast_context
3+
4+
try:
5+
# 3.6+
6+
from ddtrace.appsec._iast._iast_request_context_base import end_iast_context
7+
from ddtrace.appsec._iast._iast_request_context_base import set_iast_request_enabled
8+
from ddtrace.appsec._iast._iast_request_context_base import start_iast_context
9+
except ImportError:
10+
# Pre 3.6
11+
try:
12+
from ddtrace.appsec._iast._iast_request_context import end_iast_context
13+
from ddtrace.appsec._iast._iast_request_context import set_iast_request_enabled
14+
from ddtrace.appsec._iast._iast_request_context import start_iast_context
15+
except ImportError:
16+
# Pre 2.15
17+
from ddtrace.appsec._iast._taint_tracking._context import create_context as start_iast_context
18+
from ddtrace.appsec._iast._taint_tracking._context import reset_context as end_iast_context
19+
20+
set_iast_request_enabled = lambda x: None # noqa: E731
621
from ddtrace.appsec._iast._taint_tracking import OriginType
722
from ddtrace.appsec._iast._taint_tracking._taint_objects import taint_pyobject
823
from ddtrace.appsec._iast._taint_tracking.aspects import add_aspect

ddtrace/appsec/_handlers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
from ddtrace.appsec._asm_request_context import get_blocked
77
from ddtrace.appsec._constants import SPAN_DATA_NAMES
88
from ddtrace.contrib import trace_utils
9-
from ddtrace.contrib.internal.trace_utils import _get_request_header_user_agent
10-
from ddtrace.contrib.internal.trace_utils import _set_url_tag
9+
from ddtrace.contrib.internal.trace_utils_base import _get_request_header_user_agent
10+
from ddtrace.contrib.internal.trace_utils_base import _set_url_tag
1111
from ddtrace.ext import SpanTypes
1212
from ddtrace.ext import http
1313
from ddtrace.internal import core
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +0,0 @@
1-
from ddtrace.appsec._iast._evidence_redaction._sensitive_handler import sensitive_handler
2-
3-
4-
sensitive_handler

ddtrace/appsec/_iast/_handlers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
from wrapt import wrap_function_wrapper as _w
66

77
from ddtrace.appsec._constants import IAST
8-
from ddtrace.appsec._iast._iast_request_context import get_iast_stacktrace_reported
9-
from ddtrace.appsec._iast._iast_request_context import set_iast_stacktrace_reported
8+
from ddtrace.appsec._iast._iast_request_context_base import get_iast_stacktrace_reported
9+
from ddtrace.appsec._iast._iast_request_context_base import set_iast_stacktrace_reported
1010
from ddtrace.appsec._iast._logs import iast_instrumentation_wrapt_debug_log
1111
from ddtrace.appsec._iast._logs import iast_propagation_listener_log_log
1212
from ddtrace.appsec._iast._metrics import _set_metric_iast_instrumented_source

ddtrace/appsec/_iast/_iast_env.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import TYPE_CHECKING
1+
from typing import Any
22
from typing import Dict
33
from typing import Optional
44

@@ -7,10 +7,6 @@
77
from ddtrace.internal import core
88

99

10-
if TYPE_CHECKING:
11-
from ddtrace.appsec._iast.reporter import IastSpanReporter
12-
13-
1410
class IASTEnvironment:
1511
"""
1612
an object of this class contains all asm data (waf and telemetry)
@@ -22,7 +18,7 @@ def __init__(self, span: Optional[Span] = None):
2218
self.span = span or core.get_span()
2319

2420
self.request_enabled: bool = False
25-
self.iast_reporter: Optional["IastSpanReporter"] = None
21+
self.iast_reporter: Optional[Any] = None
2622
self.iast_span_metrics: Dict[str, int] = {}
2723
self.iast_stack_trace_id: int = 0
2824
self.iast_stack_trace_reported: bool = False
Lines changed: 6 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
1-
import os
21
from typing import TYPE_CHECKING # noqa:F401
32
from typing import Literal # noqa:F401
43
from typing import Optional
54

65
from ddtrace._trace.span import Span
76
from ddtrace.appsec._constants import APPSEC
87
from ddtrace.appsec._constants import IAST
9-
from ddtrace.appsec._constants import IAST_SPAN_TAGS
10-
from ddtrace.appsec._iast._iast_env import IASTEnvironment
118
from ddtrace.appsec._iast._iast_env import _get_iast_env
9+
import ddtrace.appsec._iast._iast_request_context_base as base
1210
from ddtrace.appsec._iast._metrics import _set_metric_iast_request_tainted
1311
from ddtrace.appsec._iast._overhead_control_engine import oce
1412
from ddtrace.appsec._iast._span_metrics import _set_span_tag_iast_executed_sink
15-
from ddtrace.appsec._iast._taint_tracking._context import create_context as create_propagation_context
16-
from ddtrace.appsec._iast._taint_tracking._context import reset_context as reset_propagation_context
17-
from ddtrace.appsec._iast._utils import _request_tainted
1813
from ddtrace.appsec._iast.reporter import IastSpanReporter
1914
from ddtrace.constants import _ORIGIN_KEY
2015
from ddtrace.internal import core
2116
from ddtrace.internal.logger import get_logger
22-
from ddtrace.internal.utils.formats import asbool
2317
from ddtrace.settings.asm import config as asm_config
2418

2519

@@ -28,30 +22,6 @@
2822
# Stopgap module for providing ASM context for the blocking features wrapping some contextvars.
2923

3024

31-
def _set_span_tag_iast_request_tainted(span):
32-
total_objects_tainted = _request_tainted()
33-
34-
if total_objects_tainted > 0:
35-
span.set_tag(IAST_SPAN_TAGS.TELEMETRY_REQUEST_TAINTED, total_objects_tainted)
36-
37-
38-
def start_iast_context():
39-
if asm_config._iast_enabled:
40-
create_propagation_context()
41-
core.set_item(IAST.REQUEST_CONTEXT_KEY, IASTEnvironment())
42-
43-
44-
def end_iast_context(span: Optional["Span"] = None):
45-
env = _get_iast_env()
46-
if env is not None and env.span is span:
47-
finalize_iast_env(env)
48-
reset_propagation_context()
49-
50-
51-
def finalize_iast_env(env: IASTEnvironment) -> None:
52-
core.discard_item(IAST.REQUEST_CONTEXT_KEY)
53-
54-
5525
def set_iast_reporter(iast_reporter: IastSpanReporter) -> None:
5626
env = _get_iast_env()
5727
if env:
@@ -67,39 +37,6 @@ def get_iast_reporter() -> Optional[IastSpanReporter]:
6737
return None
6838

6939

70-
def get_iast_stacktrace_reported() -> bool:
71-
env = _get_iast_env()
72-
if env:
73-
return env.iast_stack_trace_reported
74-
return False
75-
76-
77-
def set_iast_stacktrace_reported(reported: bool) -> None:
78-
env = _get_iast_env()
79-
if env:
80-
env.iast_stack_trace_reported = reported
81-
82-
83-
def get_iast_stacktrace_id() -> int:
84-
env = _get_iast_env()
85-
if env:
86-
env.iast_stack_trace_id += 1
87-
return env.iast_stack_trace_id
88-
return 0
89-
90-
91-
def set_iast_request_enabled(request_enabled) -> None:
92-
env = _get_iast_env()
93-
if env:
94-
env.request_enabled = request_enabled
95-
else:
96-
log.debug("iast::propagation::context::Trying to set IAST reporter but no context is present")
97-
98-
99-
def _move_iast_data_to_root_span():
100-
return asbool(os.getenv("_DD_IAST_USE_ROOT_SPAN"))
101-
102-
10340
def _create_and_attach_iast_report_to_span(req_span: "Span", existing_data: Optional[str], merge: bool = False):
10441
report_data: Optional[IastSpanReporter] = get_iast_reporter()
10542
if merge and existing_data is not None and report_data is not None:
@@ -112,11 +49,11 @@ def _create_and_attach_iast_report_to_span(req_span: "Span", existing_data: Opti
11249
report_data.build_and_scrub_value_parts()
11350
req_span.set_tag_str(IAST.JSON, report_data._to_str())
11451
_set_metric_iast_request_tainted()
115-
_set_span_tag_iast_request_tainted(req_span)
52+
base._set_span_tag_iast_request_tainted(req_span)
11653
_set_span_tag_iast_executed_sink(req_span)
11754

118-
set_iast_request_enabled(False)
119-
end_iast_context(req_span)
55+
base.set_iast_request_enabled(False)
56+
base.end_iast_context(req_span)
12057

12158
if req_span.get_tag(_ORIGIN_KEY) is None:
12259
req_span.set_tag_str(_ORIGIN_KEY, APPSEC.ORIGIN_VALUE)
@@ -126,7 +63,7 @@ def _create_and_attach_iast_report_to_span(req_span: "Span", existing_data: Opti
12663

12764
def _iast_end_request(ctx=None, span=None, *args, **kwargs):
12865
try:
129-
move_to_root = _move_iast_data_to_root_span()
66+
move_to_root = base._move_iast_data_to_root_span()
13067
if move_to_root:
13168
req_span = core.get_root_span()
13269
else:
@@ -143,7 +80,7 @@ def _iast_end_request(ctx=None, span=None, *args, **kwargs):
14380
if req_span.get_metric(IAST.ENABLED) is None:
14481
if not asm_config.is_iast_request_enabled:
14582
req_span.set_metric(IAST.ENABLED, 0.0)
146-
end_iast_context(req_span)
83+
base.end_iast_context(req_span)
14784
oce.release_request()
14885
return
14986

@@ -156,15 +93,3 @@ def _iast_end_request(ctx=None, span=None, *args, **kwargs):
15693

15794
except Exception:
15895
log.debug("iast::propagation::context::Error finishing IAST context", exc_info=True)
159-
160-
161-
def _iast_start_request(span=None, *args, **kwargs):
162-
try:
163-
if asm_config._iast_enabled:
164-
start_iast_context()
165-
request_iast_enabled = False
166-
if oce.acquire_request(span):
167-
request_iast_enabled = True
168-
set_iast_request_enabled(request_iast_enabled)
169-
except Exception:
170-
log.debug("iast::propagation::context::Error starting IAST context", exc_info=True)

0 commit comments

Comments
 (0)