Skip to content

Commit 704c219

Browse files
github-actions[bot]gnufede
authored andcommitted
refactor(asm): appsec and iast with product plugin interface [backport 2.20] (#12270)
Co-authored-by: Federico Mon <[email protected]> fix(asm): make sure iast is not loaded by exploit prevention if disabled [backport 2.20] (#12271) Co-authored-by: Christophe Papazian <[email protected]> chore(asm): don't load appsec modules (iast)... [backport 2.20] (#12298) The goal is to make sure no appsec module is loaded if appsec is disabled. This PR is the first one of 2, handling IAST. It removes all non guarded IAST import from outside appsec. - ensure we don't load any iast module if iast is disabled - replace `_is_iast_enabled()` by a field `_iast_enabled` in the asm config APPSEC-56626 - [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)) - [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) (cherry picked from commit ea2a9a5) --------- Co-authored-by: Christophe Papazian <[email protected]> Co-authored-by: Alberto Vara <[email protected]> chore(asm): clean libddwaf loading [backport 2.20] (#12320) Backport 4f0bcb5 from #12102 to 2.20. Depending of the timing, libddwaf loading process could create triggers that would create loops in our instrumentation. From what I investigated: - if loaded too early, it could have bad interactions with gevent. - if loaded too late, it could be self instrumented by the tracer, creating a loop, as ctypes is using Popen and subprocess. while keeping the late loading introduced by 2 previous PRs - #11987 - #12013 this PR introduced a mechanism to bypass tracer instrumentation during ctypes loading, to avoid a possible loop that would prevent the WAF to be loaded. - [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)) - [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) Co-authored-by: Christophe Papazian <[email protected]> fix(asm): decouple appsec [backport 2.20] (#12319) Backport #12212 to 2.20 - [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)) - [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) --------- Co-authored-by: Christophe Papazian <[email protected]> chore(iast): relase note of #12298 [backport 2.20] (#12317) Release note of the PR #12298 - [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)) - [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 8fba060 commit 704c219

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+540
-283
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ ddtrace/contrib/flask_login/ @DataDog/asm-python
115115
ddtrace/contrib/webbrowser @DataDog/asm-python
116116
ddtrace/contrib/urllib @DataDog/asm-python
117117
ddtrace/internal/_exceptions.py @DataDog/asm-python
118+
ddtrace/internal/appsec/ @DataDog/asm-python
119+
ddtrace/internal/iast/ @DataDog/asm-python
118120
tests/appsec/ @DataDog/asm-python
119121
tests/contrib/dbapi/test_dbapi_appsec.py @DataDog/asm-python
120122
tests/contrib/subprocess @DataDog/asm-python

ddtrace/_monkey.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
from ddtrace.appsec import load_common_appsec_modules
99
from ddtrace.internal.telemetry.constants import TELEMETRY_NAMESPACE
10+
from ddtrace.settings.asm import config as asm_config
1011

11-
from .appsec._iast._utils import _is_iast_enabled
1212
from .internal import telemetry
1313
from .internal.logger import get_logger
1414
from .internal.utils import formats
@@ -240,7 +240,7 @@ def patch_all(**patch_modules):
240240
modules.update(patch_modules)
241241

242242
patch(raise_errors=False, **modules)
243-
if _is_iast_enabled():
243+
if asm_config._iast_enabled:
244244
from ddtrace.appsec._iast._patch_modules import patch_iast
245245
from ddtrace.appsec.iast import enable_iast_propagation
246246

ddtrace/appsec/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
# this module must not load any other unsafe appsec module directly
2+
13
from ddtrace.internal import core
2-
from ddtrace.settings.asm import config as asm_config
34

45

56
_APPSEC_TO_BE_LOADED = True
@@ -28,7 +29,9 @@ def load_iast():
2829

2930
def load_common_appsec_modules():
3031
"""Lazily load the common module patches."""
31-
if (asm_config._ep_enabled and asm_config._asm_enabled) or asm_config._iast_enabled:
32+
from ddtrace.settings.asm import config as asm_config
33+
34+
if asm_config._load_modules:
3235
from ddtrace.appsec._common_module_patches import patch_common_modules
3336

3437
patch_common_modules()

ddtrace/appsec/_asm_request_context.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@
1515
from ddtrace.appsec._constants import APPSEC
1616
from ddtrace.appsec._constants import EXPLOIT_PREVENTION
1717
from ddtrace.appsec._constants import SPAN_DATA_NAMES
18-
from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled
19-
from ddtrace.appsec._iast._taint_tracking import OriginType
20-
from ddtrace.appsec._iast._taint_tracking._taint_objects import taint_pyobject
21-
from ddtrace.appsec._iast._utils import _is_iast_enabled
2218
from ddtrace.appsec._utils import add_context_log
2319
from ddtrace.appsec._utils import get_triggers
2420
from ddtrace.internal import core
@@ -29,6 +25,16 @@
2925
from ddtrace.trace import Span
3026

3127

28+
if asm_config._iast_enabled:
29+
from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled
30+
from ddtrace.appsec._iast._taint_tracking import OriginType
31+
from ddtrace.appsec._iast._taint_tracking._taint_objects import taint_pyobject
32+
else:
33+
34+
def is_iast_request_enabled() -> bool:
35+
return False
36+
37+
3238
if TYPE_CHECKING:
3339
from ddtrace.appsec._ddwaf import DDWaf_info
3440
from ddtrace.appsec._ddwaf import DDWaf_result
@@ -493,7 +499,7 @@ def _on_wrapped_view(kwargs):
493499

494500
# If IAST is enabled, taint the Flask function kwargs (path parameters)
495501

496-
if _is_iast_enabled() and kwargs:
502+
if asm_config._iast_enabled and kwargs:
497503
if not is_iast_request_enabled():
498504
return return_value
499505

ddtrace/appsec/_common_module_patches.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
# This module must not import other modules inconditionnaly that
2-
# require iast, ddwaf or any native optional module.
1+
# This module must not import other modules unconditionally that require iast
32

43
import ctypes
54
import os
@@ -17,9 +16,6 @@
1716
from ddtrace.appsec._asm_request_context import get_blocked
1817
from ddtrace.appsec._constants import EXPLOIT_PREVENTION
1918
from ddtrace.appsec._constants import WAF_ACTIONS
20-
from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled
21-
from ddtrace.appsec._iast._metrics import _set_metric_iast_instrumented_sink
22-
from ddtrace.appsec._iast.constants import VULN_PATH_TRAVERSAL
2319
import ddtrace.contrib.internal.subprocess.patch as subprocess_patch
2420
from ddtrace.internal import core
2521
from ddtrace.internal._exceptions import BlockingException
@@ -29,6 +25,14 @@
2925
from ddtrace.settings.asm import config as asm_config
3026

3127

28+
if asm_config._iast_enabled:
29+
from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled
30+
else:
31+
32+
def is_iast_request_enabled() -> bool:
33+
return False
34+
35+
3236
log = get_logger(__name__)
3337
_DD_ORIGINAL_ATTRIBUTES: Dict[Any, Any] = {}
3438

@@ -40,18 +44,31 @@
4044

4145
def patch_common_modules():
4246
global _is_patched
47+
# ensure that the subprocess patch is applied even after one click activation
48+
subprocess_patch.patch()
49+
subprocess_patch.add_str_callback(_RASP_SYSTEM, wrapped_system_5542593D237084A7)
50+
subprocess_patch.add_lst_callback(_RASP_POPEN, popen_FD233052260D8B4D)
4351
if _is_patched:
4452
return
53+
# for testing purposes, we need to update is_iast_request_enabled
54+
if asm_config._iast_enabled:
55+
global is_iast_request_enabled
56+
from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled
57+
else:
58+
global is_iast_request_enabled
59+
60+
def is_iast_request_enabled() -> bool:
61+
return False
62+
4563
try_wrap_function_wrapper("builtins", "open", wrapped_open_CFDDB7ABBA9081B6)
4664
try_wrap_function_wrapper("urllib.request", "OpenerDirector.open", wrapped_open_ED4CF71136E15EBF)
4765
try_wrap_function_wrapper("_io", "BytesIO.read", wrapped_read_F3E51D71B4EC16EF)
4866
try_wrap_function_wrapper("_io", "StringIO.read", wrapped_read_F3E51D71B4EC16EF)
49-
# ensure that the subprocess patch is applied even after one click activation
50-
subprocess_patch.patch()
51-
subprocess_patch.add_str_callback(_RASP_SYSTEM, wrapped_system_5542593D237084A7)
52-
subprocess_patch.add_lst_callback(_RASP_POPEN, popen_FD233052260D8B4D)
5367
core.on("asm.block.dbapi.execute", execute_4C9BAC8E228EB347)
5468
if asm_config._iast_enabled:
69+
from ddtrace.appsec._iast._metrics import _set_metric_iast_instrumented_sink
70+
from ddtrace.appsec._iast.constants import VULN_PATH_TRAVERSAL
71+
5572
_set_metric_iast_instrumented_sink(VULN_PATH_TRAVERSAL)
5673
_is_patched = True
5774

ddtrace/appsec/_constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# this module must not load any other unsafe appsec module directly
2+
13
import os
24
from re import Match
35
import sys

ddtrace/appsec/_ddwaf/ddwaf_types.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222

2323
if system() == "Linux":
2424
try:
25+
asm_config._bypass_instrumentation_for_waf = True
2526
ctypes.CDLL(ctypes.util.find_library("rt"), mode=ctypes.RTLD_GLOBAL)
2627
except Exception: # nosec
2728
pass
29+
finally:
30+
asm_config._bypass_instrumentation_for_waf = False
2831

2932
ARCHI = machine().lower()
3033

ddtrace/appsec/_iast/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ def wrapped_function(wrapped, instance, args, kwargs):
3838
from ddtrace.settings.asm import config as asm_config
3939

4040
from ._overhead_control_engine import OverheadControl
41-
from ._utils import _is_iast_enabled
4241

4342

4443
log = get_logger(__name__)
@@ -54,7 +53,7 @@ def ddtrace_iast_flask_patch():
5453
and must be before the `app.run()` call. It also requires `DD_IAST_ENABLED` to be
5554
activated.
5655
"""
57-
if not _is_iast_enabled():
56+
if not asm_config._iast_enabled:
5857
return
5958

6059
from ._ast.ast_patching import astpatch_module

ddtrace/appsec/_iast/_handlers.py

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
from wrapt import when_imported
55
from wrapt import wrap_function_wrapper as _w
66

7-
from ddtrace.appsec._iast import _is_iast_enabled
8-
from ddtrace.appsec._iast._iast_request_context import in_iast_context
97
from ddtrace.appsec._iast._metrics import _set_metric_iast_instrumented_source
108
from ddtrace.appsec._iast._patch import _iast_instrument_starlette_request
119
from ddtrace.appsec._iast._patch import _iast_instrument_starlette_request_body
@@ -17,6 +15,7 @@
1715
from ddtrace.appsec._iast._taint_tracking._taint_objects import is_pyobject_tainted
1816
from ddtrace.appsec._iast._taint_utils import taint_structure
1917
from ddtrace.internal.logger import get_logger
18+
from ddtrace.settings.asm import config as asm_config
2019

2120
from ._iast_request_context import is_iast_request_enabled
2221
from ._taint_tracking._taint_objects import taint_pyobject
@@ -47,7 +46,7 @@ def _on_set_http_meta_iast(
4746
response_headers,
4847
response_cookies,
4948
):
50-
if _is_iast_enabled():
49+
if asm_config._iast_enabled:
5150
from ddtrace.appsec._iast.taint_sinks.insecure_cookie import asm_check_cookies
5251

5352
if response_cookies:
@@ -56,7 +55,7 @@ def _on_set_http_meta_iast(
5655

5756
def _on_request_init(wrapped, instance, args, kwargs):
5857
wrapped(*args, **kwargs)
59-
if _is_iast_enabled() and in_iast_context():
58+
if asm_config._iast_enabled and is_iast_request_enabled():
6059
try:
6160
instance.query_string = taint_pyobject(
6261
pyobject=instance.query_string,
@@ -75,7 +74,7 @@ def _on_request_init(wrapped, instance, args, kwargs):
7574

7675

7776
def _on_flask_patch(flask_version):
78-
if _is_iast_enabled():
77+
if asm_config._iast_enabled:
7978
try_wrap_function_wrapper(
8079
"werkzeug.datastructures",
8180
"Headers.items",
@@ -129,16 +128,21 @@ def _on_flask_patch(flask_version):
129128
)
130129
_set_metric_iast_instrumented_source(OriginType.QUERY)
131130

131+
# Instrumented on _on_set_request_tags_iast
132+
_set_metric_iast_instrumented_source(OriginType.COOKIE_NAME)
133+
_set_metric_iast_instrumented_source(OriginType.COOKIE)
134+
_set_metric_iast_instrumented_source(OriginType.PARAMETER_NAME)
135+
132136

133137
def _on_wsgi_environ(wrapped, _instance, args, kwargs):
134-
if _is_iast_enabled() and args and in_iast_context():
138+
if asm_config._iast_enabled and args and is_iast_request_enabled():
135139
return wrapped(*((taint_structure(args[0], OriginType.HEADER_NAME, OriginType.HEADER),) + args[1:]), **kwargs)
136140

137141
return wrapped(*args, **kwargs)
138142

139143

140144
def _on_django_patch():
141-
if _is_iast_enabled():
145+
if asm_config._iast_enabled:
142146
try:
143147
# we instrument those sources on _on_django_func_wrapped
144148
_set_metric_iast_instrumented_source(OriginType.HEADER_NAME)
@@ -164,8 +168,8 @@ def _on_django_patch():
164168
def _on_django_func_wrapped(fn_args, fn_kwargs, first_arg_expected_type, *_):
165169
# If IAST is enabled, and we're wrapping a Django view call, taint the kwargs (view's
166170
# path parameters)
167-
if _is_iast_enabled() and fn_args and isinstance(fn_args[0], first_arg_expected_type):
168-
if not in_iast_context():
171+
if asm_config._iast_enabled and fn_args and isinstance(fn_args[0], first_arg_expected_type):
172+
if not is_iast_request_enabled():
169173
return
170174

171175
http_req = fn_args[0]
@@ -272,32 +276,30 @@ def _patch_protobuf_class(cls):
272276

273277

274278
def _on_grpc_response(message):
275-
if _is_iast_enabled():
279+
if asm_config._iast_enabled:
276280
msg_cls = type(message)
277281
_patch_protobuf_class(msg_cls)
278282

279283

280284
def if_iast_taint_yield_tuple_for(origins, wrapped, instance, args, kwargs):
281-
if _is_iast_enabled():
282-
if not is_iast_request_enabled():
283-
for key, value in wrapped(*args, **kwargs):
284-
yield key, value
285-
else:
285+
if asm_config._iast_enabled and is_iast_request_enabled():
286+
try:
286287
for key, value in wrapped(*args, **kwargs):
287288
new_key = taint_pyobject(pyobject=key, source_name=key, source_value=key, source_origin=origins[0])
288289
new_value = taint_pyobject(
289290
pyobject=value, source_name=key, source_value=value, source_origin=origins[1]
290291
)
291292
yield new_key, new_value
292-
293+
except Exception:
294+
log.debug("Unexpected exception while tainting pyobject", exc_info=True)
293295
else:
294296
for key, value in wrapped(*args, **kwargs):
295297
yield key, value
296298

297299

298300
def if_iast_taint_returned_object_for(origin, wrapped, instance, args, kwargs):
299301
value = wrapped(*args, **kwargs)
300-
if _is_iast_enabled() and is_iast_request_enabled():
302+
if asm_config._iast_enabled and is_iast_request_enabled():
301303
try:
302304
if not is_pyobject_tainted(value):
303305
name = str(args[0]) if len(args) else "http.request.body"
@@ -311,7 +313,7 @@ def if_iast_taint_returned_object_for(origin, wrapped, instance, args, kwargs):
311313

312314
def if_iast_taint_starlette_datastructures(origin, wrapped, instance, args, kwargs):
313315
value = wrapped(*args, **kwargs)
314-
if _is_iast_enabled() and is_iast_request_enabled():
316+
if asm_config._iast_enabled and is_iast_request_enabled():
315317
try:
316318
res = []
317319
for element in value:
@@ -417,14 +419,7 @@ def _on_pre_tracedrequest_iast(ctx):
417419

418420

419421
def _on_set_request_tags_iast(request, span, flask_config):
420-
if _is_iast_enabled():
421-
_set_metric_iast_instrumented_source(OriginType.COOKIE_NAME)
422-
_set_metric_iast_instrumented_source(OriginType.COOKIE)
423-
_set_metric_iast_instrumented_source(OriginType.PARAMETER_NAME)
424-
425-
if not is_iast_request_enabled():
426-
return
427-
422+
if asm_config._iast_enabled and is_iast_request_enabled():
428423
request.cookies = taint_structure(
429424
request.cookies,
430425
OriginType.COOKIE_NAME,

ddtrace/appsec/_iast/_iast_request_context.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from ddtrace.appsec._constants import APPSEC
77
from ddtrace.appsec._constants import IAST
8-
from ddtrace.appsec._iast import _is_iast_enabled
98
from ddtrace.appsec._iast import oce
109
from ddtrace.appsec._iast._metrics import _set_metric_iast_request_tainted
1110
from ddtrace.appsec._iast._metrics import _set_span_tag_iast_executed_sink
@@ -17,6 +16,7 @@
1716
from ddtrace.internal import core
1817
from ddtrace.internal.logger import get_logger
1918
from ddtrace.internal.utils.formats import asbool
19+
from ddtrace.settings.asm import config as asm_config
2020
from ddtrace.trace import Span
2121

2222

@@ -57,7 +57,7 @@ def in_iast_context() -> bool:
5757

5858

5959
def start_iast_context():
60-
if _is_iast_enabled():
60+
if asm_config._iast_enabled:
6161
create_propagation_context()
6262
core.set_item(_IAST_CONTEXT, IASTEnvironment())
6363

@@ -104,7 +104,7 @@ def set_iast_request_enabled(request_enabled) -> None:
104104
log.debug("[IAST] Trying to set IAST reporter but no context is present")
105105

106106

107-
def is_iast_request_enabled():
107+
def is_iast_request_enabled() -> bool:
108108
env = _get_iast_context()
109109
if env:
110110
return env.request_enabled
@@ -150,7 +150,7 @@ def _iast_end_request(ctx=None, span=None, *args, **kwargs):
150150
else:
151151
req_span = ctx.get_item("req_span")
152152

153-
if _is_iast_enabled():
153+
if asm_config._iast_enabled:
154154
existing_data = req_span.get_tag(IAST.JSON)
155155
if existing_data is None:
156156
if req_span.get_metric(IAST.ENABLED) is None:
@@ -173,7 +173,7 @@ def _iast_end_request(ctx=None, span=None, *args, **kwargs):
173173

174174
def _iast_start_request(span=None, *args, **kwargs):
175175
try:
176-
if _is_iast_enabled():
176+
if asm_config._iast_enabled:
177177
start_iast_context()
178178
request_iast_enabled = False
179179
if oce.acquire_request(span):

ddtrace/appsec/_iast/_loader.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#!/usr/bin/env python3
22

33
from ddtrace.internal.logger import get_logger
4+
from ddtrace.settings.asm import config as asm_config
45

56
from ._ast.ast_patching import astpatch_module
6-
from ._utils import _is_iast_enabled
77

88

99
log = get_logger(__name__)
1010

11-
IS_IAST_ENABLED = _is_iast_enabled()
11+
IS_IAST_ENABLED = asm_config._iast_enabled
1212

1313

1414
def _exec_iast_patched_module(module_watchdog, module):

0 commit comments

Comments
 (0)