diff --git a/ddtrace/_monkey.py b/ddtrace/_monkey.py index 03417fe0d0f..fad8c8f4d2b 100644 --- a/ddtrace/_monkey.py +++ b/ddtrace/_monkey.py @@ -7,8 +7,8 @@ from ddtrace.appsec import load_common_appsec_modules from ddtrace.internal.telemetry.constants import TELEMETRY_NAMESPACE +from ddtrace.settings.asm import config as asm_config -from .appsec._iast._utils import _is_iast_enabled from .internal import telemetry from .internal.logger import get_logger from .internal.utils import formats @@ -240,7 +240,7 @@ def patch_all(**patch_modules): modules.update(patch_modules) patch(raise_errors=False, **modules) - if _is_iast_enabled(): + if asm_config._iast_enabled: from ddtrace.appsec._iast._patch_modules import patch_iast from ddtrace.appsec.iast import enable_iast_propagation diff --git a/ddtrace/appsec/_asm_request_context.py b/ddtrace/appsec/_asm_request_context.py index 950015b3f80..d8f258d43a7 100644 --- a/ddtrace/appsec/_asm_request_context.py +++ b/ddtrace/appsec/_asm_request_context.py @@ -18,7 +18,6 @@ from ddtrace.appsec._iast._iast_request_context import is_iast_request_enabled from ddtrace.appsec._iast._taint_tracking import OriginType from ddtrace.appsec._iast._taint_tracking._taint_objects import taint_pyobject -from ddtrace.appsec._iast._utils import _is_iast_enabled from ddtrace.appsec._utils import add_context_log from ddtrace.appsec._utils import get_triggers from ddtrace.internal import core @@ -493,7 +492,7 @@ def _on_wrapped_view(kwargs): # If IAST is enabled, taint the Flask function kwargs (path parameters) - if _is_iast_enabled() and kwargs: + if asm_config._iast_enabled and kwargs: if not is_iast_request_enabled(): return return_value diff --git a/ddtrace/appsec/_iast/__init__.py b/ddtrace/appsec/_iast/__init__.py index 724819b17df..f609fe0da7a 100644 --- a/ddtrace/appsec/_iast/__init__.py +++ b/ddtrace/appsec/_iast/__init__.py @@ -38,7 +38,6 @@ def wrapped_function(wrapped, instance, args, kwargs): from ddtrace.settings.asm import config as asm_config from ._overhead_control_engine import OverheadControl -from ._utils import _is_iast_enabled log = get_logger(__name__) @@ -54,7 +53,7 @@ def ddtrace_iast_flask_patch(): and must be before the `app.run()` call. It also requires `DD_IAST_ENABLED` to be activated. """ - if not _is_iast_enabled(): + if not asm_config._iast_enabled: return from ._ast.ast_patching import astpatch_module diff --git a/ddtrace/appsec/_iast/_handlers.py b/ddtrace/appsec/_iast/_handlers.py index c3761451e99..cf60fc610be 100644 --- a/ddtrace/appsec/_iast/_handlers.py +++ b/ddtrace/appsec/_iast/_handlers.py @@ -4,7 +4,6 @@ from wrapt import when_imported from wrapt import wrap_function_wrapper as _w -from ddtrace.appsec._iast import _is_iast_enabled from ddtrace.appsec._iast._iast_request_context import get_iast_stacktrace_reported from ddtrace.appsec._iast._iast_request_context import set_iast_stacktrace_reported from ddtrace.appsec._iast._metrics import _set_metric_iast_instrumented_source @@ -18,6 +17,7 @@ from ddtrace.appsec._iast._taint_tracking._taint_objects import is_pyobject_tainted from ddtrace.appsec._iast._taint_utils import taint_structure from ddtrace.internal.logger import get_logger +from ddtrace.settings.asm import config as asm_config from ._iast_request_context import is_iast_request_enabled from ._taint_tracking._taint_objects import taint_pyobject @@ -48,7 +48,7 @@ def _on_set_http_meta_iast( response_headers, response_cookies, ): - if _is_iast_enabled(): + if asm_config._iast_enabled: from ddtrace.appsec._iast.taint_sinks.insecure_cookie import asm_check_cookies if response_cookies: @@ -57,7 +57,7 @@ def _on_set_http_meta_iast( def _on_request_init(wrapped, instance, args, kwargs): wrapped(*args, **kwargs) - if _is_iast_enabled() and is_iast_request_enabled(): + if asm_config._iast_enabled and is_iast_request_enabled(): try: instance.query_string = taint_pyobject( pyobject=instance.query_string, @@ -76,7 +76,7 @@ def _on_request_init(wrapped, instance, args, kwargs): def _on_flask_patch(flask_version): - if _is_iast_enabled(): + if asm_config._iast_enabled: try_wrap_function_wrapper( "werkzeug.datastructures", "Headers.items", @@ -137,14 +137,14 @@ def _on_flask_patch(flask_version): def _on_wsgi_environ(wrapped, _instance, args, kwargs): - if _is_iast_enabled() and args and is_iast_request_enabled(): + if asm_config._iast_enabled and args and is_iast_request_enabled(): return wrapped(*((taint_structure(args[0], OriginType.HEADER_NAME, OriginType.HEADER),) + args[1:]), **kwargs) return wrapped(*args, **kwargs) def _on_django_patch(): - if _is_iast_enabled(): + if asm_config._iast_enabled: try: when_imported("django.http.request")( lambda m: try_wrap_function_wrapper( @@ -172,7 +172,7 @@ def _on_django_patch(): def _on_django_func_wrapped(fn_args, fn_kwargs, first_arg_expected_type, *_): # If IAST is enabled, and we're wrapping a Django view call, taint the kwargs (view's # path parameters) - if _is_iast_enabled() and fn_args and isinstance(fn_args[0], first_arg_expected_type): + if asm_config._iast_enabled and fn_args and isinstance(fn_args[0], first_arg_expected_type): if not is_iast_request_enabled(): return @@ -280,13 +280,13 @@ def _patch_protobuf_class(cls): def _on_grpc_response(message): - if _is_iast_enabled(): + if asm_config._iast_enabled: msg_cls = type(message) _patch_protobuf_class(msg_cls) def if_iast_taint_yield_tuple_for(origins, wrapped, instance, args, kwargs): - if _is_iast_enabled() and is_iast_request_enabled(): + if asm_config._iast_enabled and is_iast_request_enabled(): try: for key, value in wrapped(*args, **kwargs): new_key = taint_pyobject(pyobject=key, source_name=key, source_value=key, source_origin=origins[0]) @@ -303,7 +303,7 @@ def if_iast_taint_yield_tuple_for(origins, wrapped, instance, args, kwargs): def if_iast_taint_returned_object_for(origin, wrapped, instance, args, kwargs): value = wrapped(*args, **kwargs) - if _is_iast_enabled() and is_iast_request_enabled(): + if asm_config._iast_enabled and is_iast_request_enabled(): try: if not is_pyobject_tainted(value): name = str(args[0]) if len(args) else "http.request.body" @@ -317,7 +317,7 @@ def if_iast_taint_returned_object_for(origin, wrapped, instance, args, kwargs): def if_iast_taint_starlette_datastructures(origin, wrapped, instance, args, kwargs): value = wrapped(*args, **kwargs) - if _is_iast_enabled() and is_iast_request_enabled(): + if asm_config._iast_enabled and is_iast_request_enabled(): try: res = [] for element in value: @@ -423,7 +423,7 @@ def _on_pre_tracedrequest_iast(ctx): def _on_set_request_tags_iast(request, span, flask_config): - if _is_iast_enabled() and is_iast_request_enabled(): + if asm_config._iast_enabled and is_iast_request_enabled(): request.cookies = taint_structure( request.cookies, OriginType.COOKIE_NAME, @@ -447,7 +447,7 @@ def _on_set_request_tags_iast(request, span, flask_config): def _on_django_finalize_response_pre(ctx, after_request_tags, request, response): - if not response or not _is_iast_enabled() or not is_iast_request_enabled() or get_iast_stacktrace_reported(): + if not response or not asm_config._iast_enabled or not is_iast_request_enabled() or get_iast_stacktrace_reported(): return try: @@ -460,7 +460,7 @@ def _on_django_finalize_response_pre(ctx, after_request_tags, request, response) def _on_django_technical_500_response(request, response, exc_type, exc_value, tb): - if not exc_value or not _is_iast_enabled() or not is_iast_request_enabled(): + if not exc_value or not asm_config._iast_enabled or not is_iast_request_enabled(): return try: @@ -474,7 +474,7 @@ def _on_django_technical_500_response(request, response, exc_type, exc_value, tb def _on_flask_finalize_request_post(response, _): - if not response or not _is_iast_enabled() or not is_iast_request_enabled() or get_iast_stacktrace_reported(): + if not response or not asm_config._iast_enabled or not is_iast_request_enabled() or get_iast_stacktrace_reported(): return try: @@ -487,7 +487,7 @@ def _on_flask_finalize_request_post(response, _): def _on_asgi_finalize_response(body, _): - if not body or not _is_iast_enabled() or not is_iast_request_enabled(): + if not body or not asm_config._iast_enabled or not is_iast_request_enabled(): return try: @@ -500,7 +500,7 @@ def _on_asgi_finalize_response(body, _): def _on_werkzeug_render_debugger_html(html): - if not html or not _is_iast_enabled() or not is_iast_request_enabled(): + if not html or not asm_config._iast_enabled or not is_iast_request_enabled(): return try: diff --git a/ddtrace/appsec/_iast/_iast_request_context.py b/ddtrace/appsec/_iast/_iast_request_context.py index 176dceea4de..30a3471b595 100644 --- a/ddtrace/appsec/_iast/_iast_request_context.py +++ b/ddtrace/appsec/_iast/_iast_request_context.py @@ -5,7 +5,6 @@ from ddtrace.appsec._constants import APPSEC from ddtrace.appsec._constants import IAST -from ddtrace.appsec._iast import _is_iast_enabled from ddtrace.appsec._iast import oce from ddtrace.appsec._iast._metrics import _set_metric_iast_request_tainted from ddtrace.appsec._iast._metrics import _set_span_tag_iast_executed_sink @@ -17,6 +16,7 @@ from ddtrace.internal import core from ddtrace.internal.logger import get_logger from ddtrace.internal.utils.formats import asbool +from ddtrace.settings.asm import config as asm_config from ddtrace.trace import Span @@ -58,7 +58,7 @@ def in_iast_context() -> bool: def start_iast_context(): - if _is_iast_enabled(): + if asm_config._iast_enabled: create_propagation_context() core.set_item(_IAST_CONTEXT, IASTEnvironment()) @@ -164,7 +164,7 @@ def _iast_end_request(ctx=None, span=None, *args, **kwargs): else: req_span = ctx.get_item("req_span") - if _is_iast_enabled(): + if asm_config._iast_enabled: existing_data = req_span.get_tag(IAST.JSON) if existing_data is None: if req_span.get_metric(IAST.ENABLED) is None: @@ -187,7 +187,7 @@ def _iast_end_request(ctx=None, span=None, *args, **kwargs): def _iast_start_request(span=None, *args, **kwargs): try: - if _is_iast_enabled(): + if asm_config._iast_enabled: start_iast_context() request_iast_enabled = False if oce.acquire_request(span): diff --git a/ddtrace/appsec/_iast/_loader.py b/ddtrace/appsec/_iast/_loader.py index 382060e3b7f..7621b5f3449 100644 --- a/ddtrace/appsec/_iast/_loader.py +++ b/ddtrace/appsec/_iast/_loader.py @@ -1,14 +1,14 @@ #!/usr/bin/env python3 from ddtrace.internal.logger import get_logger +from ddtrace.settings.asm import config as asm_config from ._ast.ast_patching import astpatch_module -from ._utils import _is_iast_enabled log = get_logger(__name__) -IS_IAST_ENABLED = _is_iast_enabled() +IS_IAST_ENABLED = asm_config._iast_enabled def _exec_iast_patched_module(module_watchdog, module): diff --git a/ddtrace/appsec/_iast/_pytest_plugin.py b/ddtrace/appsec/_iast/_pytest_plugin.py index 82c23c53174..28a5b9e0e08 100644 --- a/ddtrace/appsec/_iast/_pytest_plugin.py +++ b/ddtrace/appsec/_iast/_pytest_plugin.py @@ -4,9 +4,9 @@ from typing import List from ddtrace.appsec._constants import IAST -from ddtrace.appsec._iast._utils import _is_iast_enabled from ddtrace.appsec._iast.reporter import Vulnerability from ddtrace.internal.logger import get_logger +from ddtrace.settings.asm import config as asm_config log = get_logger(__name__) @@ -20,7 +20,7 @@ class VulnerabilityFoundInTest(Vulnerability): try: import pytest - @pytest.fixture(autouse=_is_iast_enabled()) + @pytest.fixture(autouse=asm_config._iast_enabled) def ddtrace_iast(request, ddspan): """ Extract the vulnerabilities discovered in tests. @@ -72,7 +72,7 @@ def extract_code_snippet(filepath, line_number, context=3): def print_iast_report(terminalreporter): - if not _is_iast_enabled(): + if not asm_config._iast_enabled: return if not vuln_data: diff --git a/ddtrace/appsec/_iast/_utils.py b/ddtrace/appsec/_iast/_utils.py index fda05a8b8e5..e2c2dbec836 100644 --- a/ddtrace/appsec/_iast/_utils.py +++ b/ddtrace/appsec/_iast/_utils.py @@ -1,29 +1,8 @@ -from functools import lru_cache -import sys from typing import List -from ddtrace.internal.logger import get_logger from ddtrace.settings.asm import config as asm_config -@lru_cache(maxsize=1) -def _is_python_version_supported() -> bool: - # IAST supports Python versions 3.6 to 3.13 - return (3, 6, 0) <= sys.version_info < (3, 14, 0) - - -def _is_iast_enabled(): - if not asm_config._iast_enabled: - return False - - if not _is_python_version_supported(): - log = get_logger(__name__) - log.info("IAST is not compatible with the current Python version") - return False - - return True - - def _get_source_index(sources: List, source) -> int: i = 0 for source_ in sources: diff --git a/ddtrace/appsec/_iast/taint_sinks/insecure_cookie.py b/ddtrace/appsec/_iast/taint_sinks/insecure_cookie.py index 3e9c05c451c..8f369e85b9a 100644 --- a/ddtrace/appsec/_iast/taint_sinks/insecure_cookie.py +++ b/ddtrace/appsec/_iast/taint_sinks/insecure_cookie.py @@ -1,8 +1,9 @@ from typing import Dict from typing import Optional +from ddtrace.settings.asm import config as asm_config + from ..._constants import IAST_SPAN_TAGS -from .. import _is_iast_enabled from .. import oce from .._iast_request_context import is_iast_request_enabled from .._metrics import _set_metric_iast_executed_sink @@ -36,7 +37,7 @@ class NoSameSite(VulnerabilityBase): def asm_check_cookies(cookies: Optional[Dict[str, str]]) -> None: if not cookies: return - if _is_iast_enabled() and is_iast_request_enabled(): + if asm_config._iast_enabled and is_iast_request_enabled(): try: for cookie_key, cookie_value in cookies.items(): lvalue = cookie_value.lower().replace(" ", "") diff --git a/ddtrace/contrib/dbapi/__init__.py b/ddtrace/contrib/dbapi/__init__.py index fa733c19a63..0ecbbd804fa 100644 --- a/ddtrace/contrib/dbapi/__init__.py +++ b/ddtrace/contrib/dbapi/__init__.py @@ -4,15 +4,14 @@ import wrapt from ddtrace import config -from ddtrace.appsec._iast._utils import _is_iast_enabled +from ddtrace.appsec._constants import IAST_SPAN_TAGS from ddtrace.internal import core from ddtrace.internal.constants import COMPONENT from ddtrace.internal.logger import get_logger from ddtrace.internal.utils import ArgumentError from ddtrace.internal.utils import get_argument_value +from ddtrace.settings.asm import config as asm_config -from ...appsec._constants import IAST_SPAN_TAGS -from ...appsec._iast._metrics import increment_iast_span_metric from ...constants import _ANALYTICS_SAMPLE_RATE_KEY from ...constants import _SPAN_MEASURED_KEY from ...constants import SPAN_KIND @@ -103,9 +102,10 @@ def _trace_method(self, method, name, resource, extra_tags, dbm_propagator, *arg # set span.kind to the type of request being performed s.set_tag_str(SPAN_KIND, SpanKind.CLIENT) - if _is_iast_enabled(): + if asm_config._iast_enabled: try: from ddtrace.appsec._iast._metrics import _set_metric_iast_executed_sink + from ddtrace.appsec._iast._metrics import increment_iast_span_metric from ddtrace.appsec._iast._taint_utils import check_tainted_dbapi_args from ddtrace.appsec._iast.taint_sinks.sql_injection import SqlInjection diff --git a/ddtrace/contrib/dbapi_async/__init__.py b/ddtrace/contrib/dbapi_async/__init__.py index a6ae676f4bd..153e8a2c33e 100644 --- a/ddtrace/contrib/dbapi_async/__init__.py +++ b/ddtrace/contrib/dbapi_async/__init__.py @@ -1,13 +1,12 @@ from ddtrace import config -from ddtrace.appsec._iast._utils import _is_iast_enabled +from ddtrace.appsec._constants import IAST_SPAN_TAGS from ddtrace.internal import core from ddtrace.internal.constants import COMPONENT from ddtrace.internal.logger import get_logger from ddtrace.internal.utils import ArgumentError from ddtrace.internal.utils import get_argument_value +from ddtrace.settings.asm import config as asm_config -from ...appsec._constants import IAST_SPAN_TAGS -from ...appsec._iast._metrics import increment_iast_span_metric from ...constants import _ANALYTICS_SAMPLE_RATE_KEY from ...constants import _SPAN_MEASURED_KEY from ...constants import SPAN_KIND @@ -78,8 +77,9 @@ async def _trace_method(self, method, name, resource, extra_tags, dbm_propagator # set span.kind to the type of request being performed s.set_tag_str(SPAN_KIND, SpanKind.CLIENT) - if _is_iast_enabled(): + if asm_config._iast_enabled: from ddtrace.appsec._iast._metrics import _set_metric_iast_executed_sink + from ddtrace.appsec._iast._metrics import increment_iast_span_metric from ddtrace.appsec._iast._taint_utils import check_tainted_dbapi_args from ddtrace.appsec._iast.taint_sinks.sql_injection import SqlInjection diff --git a/ddtrace/contrib/internal/fastapi/patch.py b/ddtrace/contrib/internal/fastapi/patch.py index c79baefc59d..41473728f03 100644 --- a/ddtrace/contrib/internal/fastapi/patch.py +++ b/ddtrace/contrib/internal/fastapi/patch.py @@ -6,7 +6,6 @@ from wrapt import wrap_function_wrapper as _w from ddtrace import config -from ddtrace.appsec._iast._utils import _is_iast_enabled from ddtrace.contrib.internal.asgi.middleware import TraceMiddleware from ddtrace.contrib.internal.starlette.patch import _trace_background_tasks from ddtrace.contrib.internal.starlette.patch import traced_handler @@ -14,6 +13,7 @@ from ddtrace.internal.logger import get_logger from ddtrace.internal.schema import schematize_service_name from ddtrace.internal.utils.wrappers import unwrap as _u +from ddtrace.settings.asm import config as asm_config from ddtrace.trace import Pin @@ -86,7 +86,7 @@ def patch(): if not isinstance(fastapi.routing.Mount.handle, ObjectProxy): _w("starlette.routing", "Mount.handle", traced_handler) - if _is_iast_enabled(): + if asm_config._iast_enabled: from ddtrace.appsec._iast._handlers import _on_iast_fastapi_patch _on_iast_fastapi_patch() diff --git a/ddtrace/contrib/internal/langchain/patch.py b/ddtrace/contrib/internal/langchain/patch.py index 6c7cd2f41e0..9badbf22d87 100644 --- a/ddtrace/contrib/internal/langchain/patch.py +++ b/ddtrace/contrib/internal/langchain/patch.py @@ -26,7 +26,7 @@ except ImportError: langchain_pinecone = None -from ddtrace.appsec._iast import _is_iast_enabled +from ddtrace.settings.asm import config as asm_config try: @@ -1208,7 +1208,7 @@ def patch(): if langchain_community: _patch_embeddings_and_vectorstores() - if _is_iast_enabled(): + if asm_config._iast_enabled: from ddtrace.appsec._iast._metrics import _set_iast_error_metric def wrap_output_parser(module, parser): diff --git a/ddtrace/contrib/internal/pytest/plugin.py b/ddtrace/contrib/internal/pytest/plugin.py index 6ca4ad91afe..23bf58d7dcb 100644 --- a/ddtrace/contrib/internal/pytest/plugin.py +++ b/ddtrace/contrib/internal/pytest/plugin.py @@ -18,10 +18,10 @@ from ddtrace import config from ddtrace.appsec._iast._pytest_plugin import ddtrace_iast # noqa:F401 -from ddtrace.appsec._iast._utils import _is_iast_enabled from ddtrace.contrib.internal.pytest._utils import _USE_PLUGIN_V2 from ddtrace.contrib.internal.pytest._utils import _extract_span from ddtrace.contrib.internal.pytest._utils import _pytest_version_supports_itr +from ddtrace.settings.asm import config as asm_config # pytest default settings @@ -93,7 +93,7 @@ def pytest_addoption(parser): parser.addini("no-ddtrace", DDTRACE_HELP_MSG, type="bool") parser.addini("ddtrace-patch-all", PATCH_ALL_HELP_MSG, type="bool") parser.addini("ddtrace-include-class-name", DDTRACE_INCLUDE_CLASS_HELP_MSG, type="bool") - if _is_iast_enabled(): + if asm_config._iast_enabled: from ddtrace.appsec._iast import _iast_pytest_activation _iast_pytest_activation() diff --git a/ddtrace/contrib/internal/starlette/patch.py b/ddtrace/contrib/internal/starlette/patch.py index 02d47f8d47c..a48e11cd534 100644 --- a/ddtrace/contrib/internal/starlette/patch.py +++ b/ddtrace/contrib/internal/starlette/patch.py @@ -13,7 +13,6 @@ from wrapt import wrap_function_wrapper as _w from ddtrace import config -from ddtrace.appsec._iast import _is_iast_enabled from ddtrace.contrib import trace_utils from ddtrace.contrib.asgi import TraceMiddleware from ddtrace.contrib.internal.trace_utils import with_traced_module @@ -26,6 +25,7 @@ from ddtrace.internal.utils import get_blocked from ddtrace.internal.utils import set_argument_value from ddtrace.internal.utils.wrappers import unwrap as _u +from ddtrace.settings.asm import config as asm_config from ddtrace.trace import Pin from ddtrace.trace import Span # noqa:F401 from ddtrace.vendor.packaging.version import parse as parse_version @@ -168,7 +168,7 @@ def traced_handler(wrapped, instance, args, kwargs): break if request_spans: - if _is_iast_enabled(): + if asm_config._iast_enabled: from ddtrace.appsec._iast._patch import _iast_instrument_starlette_scope _iast_instrument_starlette_scope(scope) diff --git a/ddtrace/internal/iast/product.py b/ddtrace/internal/iast/product.py index ccbc61b2f5a..68ef24ce00e 100644 --- a/ddtrace/internal/iast/product.py +++ b/ddtrace/internal/iast/product.py @@ -3,7 +3,7 @@ too but patch_all depends of DD_TRACE_ENABLED environment variable. This is the reason why we need to call it here and it's not a duplicate call due to `enable_iast_propagation` has a global variable to avoid multiple calls. """ -from ddtrace.appsec._iast._utils import _is_iast_enabled +from ddtrace.settings.asm import config as asm_config def post_preload(): @@ -11,7 +11,7 @@ def post_preload(): def start(): - if _is_iast_enabled(): + if asm_config._iast_enabled: from ddtrace.appsec._iast import enable_iast_propagation enable_iast_propagation() diff --git a/ddtrace/settings/asm.py b/ddtrace/settings/asm.py index 49fc5e6f6c2..4024c13f982 100644 --- a/ddtrace/settings/asm.py +++ b/ddtrace/settings/asm.py @@ -2,6 +2,7 @@ import os.path from platform import machine from platform import system +import sys from typing import List from typing import Optional @@ -216,6 +217,11 @@ class ASMConfig(Env): ) _bypass_instrumentation_for_waf = False + # IAST supported on python 3.6 to 3.13 and never on windows + _iast_supported: bool = ((3, 6, 0) <= sys.version_info < (3, 14, 0)) and not ( + sys.platform.startswith("win") or sys.platform.startswith("cygwin") + ) + def __init__(self): super().__init__() # Is one click available? @@ -225,6 +231,8 @@ def __init__(self): self._asm_can_be_enabled = False self._iast_enabled = False self._api_security_enabled = False + if not self._iast_supported: + self._iast_enabled = False def reset(self): """For testing purposes, reset the configuration to its default values given current environment variables.""" diff --git a/tests/appsec/iast/fixtures/integration/main_configure.py b/tests/appsec/iast/fixtures/integration/main_configure.py index bc9933a7679..2864b45f01e 100644 --- a/tests/appsec/iast/fixtures/integration/main_configure.py +++ b/tests/appsec/iast/fixtures/integration/main_configure.py @@ -4,8 +4,8 @@ import os import sys -from ddtrace.appsec._iast._utils import _is_iast_enabled from ddtrace.ext import SpanTypes +from ddtrace.settings.asm import config as asm_config from ddtrace.trace import tracer @@ -29,11 +29,11 @@ def main(): main() if not iast_enabled: # Disabled by env var but then enabled with ``tracer.configure`` - assert _is_iast_enabled() + assert asm_config._iast_enabled assert "ddtrace.appsec._iast.processor" in sys.modules else: # Enabled by env var but then disabled with ``tracer.configure`` - assert not _is_iast_enabled() + assert not asm_config._iast_enabled # Module was loaded before assert "ddtrace.appsec._iast.processor" in sys.modules # But processor is not used by the tracer diff --git a/tests/appsec/integrations/django_tests/test_django_appsec_iast.py b/tests/appsec/integrations/django_tests/test_django_appsec_iast.py index 8f4768d8a8c..dd400c64df6 100644 --- a/tests/appsec/integrations/django_tests/test_django_appsec_iast.py +++ b/tests/appsec/integrations/django_tests/test_django_appsec_iast.py @@ -7,7 +7,6 @@ from ddtrace.appsec._constants import IAST from ddtrace.appsec._iast import oce from ddtrace.appsec._iast._patch_modules import patch_iast -from ddtrace.appsec._iast._utils import _is_python_version_supported as python_supported_by_iast from ddtrace.appsec._iast.constants import VULN_CMDI from ddtrace.appsec._iast.constants import VULN_HEADER_INJECTION from ddtrace.appsec._iast.constants import VULN_INSECURE_COOKIE @@ -15,6 +14,7 @@ from ddtrace.appsec._iast.constants import VULN_STACKTRACE_LEAK from ddtrace.ext import SpanTypes from ddtrace.internal.compat import urlencode +from ddtrace.settings.asm import config as asm_config from tests.appsec.iast.iast_utils import get_line_and_hash from tests.utils import override_env from tests.utils import override_global_config @@ -83,7 +83,7 @@ def _aux_appsec_get_root_span_with_exception( return False -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_weak_hash(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): oce.reconfigure() @@ -96,7 +96,7 @@ def test_django_weak_hash(client, test_spans, tracer): assert vulnerability["evidence"]["value"] == "md5" -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_tainted_user_agent_iast_enabled(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -137,7 +137,7 @@ def test_django_tainted_user_agent_iast_enabled(client, test_spans, tracer): 50.0, ], ) -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_view_with_exception(client, test_spans, tracer, payload, content_type, deduplication, sampling): with override_global_config( dict(_iast_enabled=True, _deduplication_enabled=deduplication, _iast_request_sampling=sampling) @@ -153,7 +153,7 @@ def test_django_view_with_exception(client, test_spans, tracer, payload, content assert response is False -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_tainted_user_agent_iast_disabled(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=False, _iast_deduplication_enabled=False)): oce.reconfigure() @@ -175,7 +175,7 @@ def test_django_tainted_user_agent_iast_disabled(client, test_spans, tracer): @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_tainted_user_agent_iast_enabled_sqli_http_request_parameter(client, test_spans, tracer): with override_global_config( dict(_iast_enabled=True, _iast_deduplication_enabled=False, _iast_request_sampling=100.0) @@ -224,7 +224,7 @@ def test_django_tainted_user_agent_iast_enabled_sqli_http_request_parameter(clie @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_request_parameter_name_get(client, test_spans, tracer): with override_global_config( dict(_iast_enabled=True, _iast_deduplication_enabled=False, _iast_request_sampling=100.0) @@ -275,7 +275,7 @@ def test_django_sqli_http_request_parameter_name_get(client, test_spans, tracer) @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_request_parameter_name_post(client, test_spans, tracer): with override_global_config( dict(_iast_enabled=True, _iast_deduplication_enabled=False, _iast_request_sampling=100.0) @@ -327,7 +327,7 @@ def test_django_sqli_http_request_parameter_name_post(client, test_spans, tracer @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_request_header_value(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -365,7 +365,7 @@ def test_django_sqli_http_request_header_value(client, test_spans, tracer): @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_iast_disabled_sqli_http_request_header_value(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -385,7 +385,7 @@ def test_django_iast_disabled_sqli_http_request_header_value(client, test_spans, @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_request_header_name(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -423,7 +423,7 @@ def test_django_sqli_http_request_header_name(client, test_spans, tracer): @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_iast_disabled_sqli_http_request_header_name(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -443,7 +443,7 @@ def test_django_iast_disabled_sqli_http_request_header_name(client, test_spans, @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_path_parameter(client, test_spans, tracer): root_span, response = _aux_appsec_get_root_span( client, @@ -478,7 +478,7 @@ def test_django_sqli_http_path_parameter(client, test_spans, tracer): @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_iast_disabled_sqli_http_path_parameter(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -496,7 +496,7 @@ def test_django_iast_disabled_sqli_http_path_parameter(client, test_spans, trace @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_cookies_name(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -536,7 +536,7 @@ def test_django_sqli_http_cookies_name(client, test_spans, tracer): @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_iast_disabled_sqli_http_cookies_name(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -554,7 +554,7 @@ def test_django_iast_disabled_sqli_http_cookies_name(client, test_spans, tracer) @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_cookies_value(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -596,7 +596,7 @@ def test_django_sqli_http_cookies_value(client, test_spans, tracer): @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_iast_disabled_sqli_http_cookies_value(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -621,7 +621,7 @@ def test_django_iast_disabled_sqli_http_cookies_value(client, test_spans, tracer ], ) @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_sqli_http_body(client, test_spans, tracer, payload, content_type): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -678,7 +678,7 @@ def test_django_sqli_http_body(client, test_spans, tracer, payload, content_type ], ) @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_tainted_http_body_empty(client, test_spans, tracer, payload, content_type, deduplication, sampling): with override_global_config( dict(_iast_enabled=True, _deduplication_enabled=deduplication, _iast_request_sampling=sampling) @@ -698,7 +698,7 @@ def test_django_tainted_http_body_empty(client, test_spans, tracer, payload, con @pytest.mark.django_db() -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_iast_disabled_sqli_http_body(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=False)): root_span, response = _aux_appsec_get_root_span( @@ -716,7 +716,7 @@ def test_django_iast_disabled_sqli_http_body(client, test_spans, tracer): assert response.content == b"master" -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_querydict(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True)): root_span, response = _aux_appsec_get_root_span( @@ -734,7 +734,7 @@ def test_django_querydict(client, test_spans, tracer): ) -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_command_injection(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): oce.reconfigure() @@ -767,7 +767,7 @@ def test_django_command_injection(client, test_spans, tracer): assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_header_injection(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): oce.reconfigure() @@ -795,7 +795,7 @@ def test_django_header_injection(client, test_spans, tracer): assert loaded["vulnerabilities"][0]["location"]["path"] == TEST_FILE -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_insecure_cookie(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): oce.reconfigure() @@ -820,7 +820,7 @@ def test_django_insecure_cookie(client, test_spans, tracer): assert vulnerability["hash"] -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_insecure_cookie_secure(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): oce.reconfigure() @@ -836,7 +836,7 @@ def test_django_insecure_cookie_secure(client, test_spans, tracer): assert root_span.get_tag(IAST.JSON) is None -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_insecure_cookie_empty_cookie(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): oce.reconfigure() @@ -852,7 +852,7 @@ def test_django_insecure_cookie_empty_cookie(client, test_spans, tracer): assert root_span.get_tag(IAST.JSON) is None -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_insecure_cookie_2_insecure_1_secure(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): oce.reconfigure() @@ -870,7 +870,7 @@ def test_django_insecure_cookie_2_insecure_1_secure(client, test_spans, tracer): assert len(loaded["vulnerabilities"]) == 2 -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_insecure_cookie_special_characters(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _iast_deduplication_enabled=False)): oce.reconfigure() @@ -895,7 +895,7 @@ def test_django_insecure_cookie_special_characters(client, test_spans, tracer): assert vulnerability["hash"] -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_stacktrace_leak(client, test_spans, tracer): with override_global_config(dict(_iast_enabled=True, _deduplication_enabled=False)): oce.reconfigure() @@ -931,7 +931,7 @@ def debug_mode(): settings.DEBUG = original_debug -@pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") +@pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_django_stacktrace_from_technical_500_response(client, test_spans, tracer, debug_mode): with override_global_config(dict(_iast_enabled=True, _deduplication_enabled=False)): with tracer.trace("test", span_type=SpanTypes.WEB, service="test") as span: diff --git a/tests/appsec/integrations/flask_tests/test_iast_flask.py b/tests/appsec/integrations/flask_tests/test_iast_flask.py index b50d9a6ad0f..8490fadea19 100644 --- a/tests/appsec/integrations/flask_tests/test_iast_flask.py +++ b/tests/appsec/integrations/flask_tests/test_iast_flask.py @@ -11,7 +11,6 @@ from ddtrace.appsec._iast._iast_request_context import _iast_start_request from ddtrace.appsec._iast._patches.json_tainting import patch as patch_json from ddtrace.appsec._iast._taint_tracking._taint_objects import is_pyobject_tainted -from ddtrace.appsec._iast._utils import _is_python_version_supported as python_supported_by_iast from ddtrace.appsec._iast.constants import VULN_HEADER_INJECTION from ddtrace.appsec._iast.constants import VULN_INSECURE_COOKIE from ddtrace.appsec._iast.constants import VULN_NO_HTTPONLY_COOKIE @@ -20,6 +19,7 @@ from ddtrace.appsec._iast.constants import VULN_STACKTRACE_LEAK from ddtrace.appsec._iast.taint_sinks.header_injection import patch as patch_header_injection from ddtrace.contrib.internal.sqlite3.patch import patch as patch_sqlite_sqli +from ddtrace.settings.asm import config as asm_config from tests.appsec.iast.iast_utils import get_line_and_hash from tests.contrib.flask import BaseFlaskTestCase from tests.utils import override_env @@ -54,7 +54,7 @@ def setUp(self): self.tracer._configure(api_version="v0.4", appsec_enabled=True, iast_enabled=True) oce.reconfigure() - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_http_request_path_parameter(self): @self.app.route("/sqli//", methods=["GET", "POST"]) def sqli_1(param_str): @@ -106,7 +106,7 @@ def sqli_1(param_str): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_enabled_http_request_header_getitem(self): @self.app.route("/sqli//", methods=["GET", "POST"]) def sqli_2(param_str): @@ -162,7 +162,7 @@ def sqli_2(param_str): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_enabled_http_request_header_name_keys(self): @self.app.route("/sqli//", methods=["GET", "POST"]) def sqli_3(param_str): @@ -216,7 +216,7 @@ def sqli_3(param_str): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_enabled_http_request_header_values(self): @self.app.route("/sqli//", methods=["GET", "POST"]) def sqli_4(param_str): @@ -320,7 +320,7 @@ def sqli_5(param_str, param_int): root_span = self.pop_spans()[0] assert root_span.get_metric(IAST.ENABLED) == 1.0 - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_simple_iast_path_header_and_querystring_tainted_request_sampling_0(self): @self.app.route("/sqli//", methods=["GET", "POST"]) def sqli_6(param_str): @@ -352,7 +352,7 @@ class MockSpan: assert root_span.get_metric(IAST.ENABLED) == 0.0 - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_enabled_http_request_cookies_value(self): @self.app.route("/sqli/cookies/", methods=["GET", "POST"]) def sqli_7(): @@ -418,7 +418,7 @@ def sqli_7(): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_enabled_http_request_cookies_name(self): @self.app.route("/sqli/cookies/", methods=["GET", "POST"]) def sqli_8(): @@ -482,7 +482,7 @@ def sqli_8(): assert {VULN_SQL_INJECTION} == vulnerabilities - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_http_request_parameter(self): @self.app.route("/sqli/parameter/", methods=["GET"]) def sqli_9(): @@ -531,7 +531,7 @@ def sqli_9(): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_http_request_parameter_name_post(self): @self.app.route("/sqli/", methods=["POST"]) def sqli_13(): @@ -589,7 +589,7 @@ def sqli_13(): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_http_request_parameter_name_get(self): @self.app.route("/sqli/", methods=["GET"]) def sqli_14(): @@ -647,7 +647,7 @@ def sqli_14(): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_request_body(self): @self.app.route("/sqli/body/", methods=("POST",)) def sqli_10(): @@ -713,7 +713,7 @@ def sqli_10(): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_request_body_complex_3_lvls(self): @self.app.route("/sqli/body/", methods=("POST",)) def sqli_11(): @@ -778,7 +778,7 @@ def sqli_11(): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_request_body_complex_3_lvls_and_list(self): @self.app.route("/sqli/body/", methods=("POST",)) def sqli_11(): @@ -843,7 +843,7 @@ def sqli_11(): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_request_body_complex_3_lvls_list_dict(self): @self.app.route("/sqli/body/", methods=("POST",)) def sqli_11(): @@ -910,7 +910,7 @@ def sqli_11(): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_request_body_complex_json_all_types_of_values(self): @self.app.route("/sqli/body/", methods=("POST",)) def sqli_11(): @@ -1048,7 +1048,7 @@ def iterate_json(data, parent_key=""): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_request_body_iast_and_appsec(self): """Verify IAST, Appsec and API security work correctly running at the same time""" @@ -1101,7 +1101,7 @@ def sqli_10(): list_metrics_logs = list(self._telemetry_writer._logs) assert len(list_metrics_logs) == 0 - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_enabled_http_request_header_values_scrubbed(self): @self.app.route("/sqli//", methods=["GET", "POST"]) def sqli_12(param_str): @@ -1155,7 +1155,7 @@ def sqli_12(param_str): assert vulnerability["location"]["path"] == TEST_FILE_PATH assert vulnerability["hash"] == hash_value - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_header_injection(self): @self.app.route("/header_injection/", methods=["GET", "POST"]) def header_injection(): @@ -1195,7 +1195,7 @@ def header_injection(): } # TODO: vulnerability path is flaky, it points to "tests/contrib/flask/__init__.py" - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_header_injection_exlusions_location(self): @self.app.route("/header_injection/", methods=["GET", "POST"]) def header_injection(): @@ -1224,7 +1224,7 @@ def header_injection(): assert root_span.get_tag(IAST.JSON) is None - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_header_injection_exlusions_access_control(self): @self.app.route("/header_injection/", methods=["GET", "POST"]) def header_injection(): @@ -1253,7 +1253,7 @@ def header_injection(): assert root_span.get_tag(IAST.JSON) is None - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_insecure_cookie(self): @self.app.route("/insecure_cookie/", methods=["GET", "POST"]) def insecure_cookie(): @@ -1291,7 +1291,7 @@ def insecure_cookie(): assert vulnerability["location"]["spanId"] assert vulnerability["hash"] - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_insecure_cookie_empty(self): @self.app.route("/insecure_cookie_empty/", methods=["GET", "POST"]) def insecure_cookie_empty(): @@ -1321,7 +1321,7 @@ def insecure_cookie_empty(): loaded = root_span.get_tag(IAST.JSON) assert loaded is None - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_no_http_only_cookie(self): @self.app.route("/no_http_only_cookie/", methods=["GET", "POST"]) def no_http_only_cookie(): @@ -1359,7 +1359,7 @@ def no_http_only_cookie(): assert vulnerability["location"]["spanId"] assert vulnerability["hash"] - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_no_http_only_cookie_empty(self): @self.app.route("/no_http_only_cookie_empty/", methods=["GET", "POST"]) def no_http_only_cookie_empty(): @@ -1390,7 +1390,7 @@ def no_http_only_cookie_empty(): loaded = root_span.get_tag(IAST.JSON) assert loaded is None - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_no_samesite_cookie(self): @self.app.route("/no_samesite_cookie/", methods=["GET", "POST"]) def no_samesite_cookie(): @@ -1428,7 +1428,7 @@ def no_samesite_cookie(): assert vulnerability["location"]["spanId"] assert vulnerability["hash"] - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_no_samesite_cookie_empty(self): @self.app.route("/no_samesite_cookie_empty/", methods=["GET", "POST"]) def no_samesite_cookie_empty(): @@ -1456,7 +1456,7 @@ def no_samesite_cookie_empty(): loaded = root_span.get_tag(IAST.JSON) assert loaded is None - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_cookie_secure(self): @self.app.route("/cookie_secure/", methods=["GET", "POST"]) def cookie_secure(): @@ -1487,7 +1487,7 @@ def cookie_secure(): loaded = root_span.get_tag(IAST.JSON) assert loaded is None - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_stacktrace_leak(self): @self.app.route("/stacktrace_leak/") def stacktrace_leak(): @@ -1542,7 +1542,7 @@ def stacktrace_leak(): ] } - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_stacktrace_leak_from_debug_page(self): try: from werkzeug.debug.tbtools import DebugTraceback @@ -1605,7 +1605,7 @@ def setUp(self): super(FlaskAppSecIASTDisabledTestCase, self).setUp() self.tracer._configure(api_version="v0.4") - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_disabled_http_request_cookies_name(self): @self.app.route("/sqli/cookies/", methods=["GET", "POST"]) def test_sqli(): @@ -1636,7 +1636,7 @@ def test_sqli(): assert root_span.get_tag(IAST.JSON) is None - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_disabled_http_request_header_getitem(self): @self.app.route("/sqli//", methods=["GET", "POST"]) def test_sqli(param_str): @@ -1668,7 +1668,7 @@ def test_sqli(param_str): assert root_span.get_tag(IAST.JSON) is None - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_disabled_http_request_header_name_keys(self): @self.app.route("/sqli//", methods=["GET", "POST"]) def test_sqli(param_str): @@ -1700,7 +1700,7 @@ def test_sqli(param_str): assert root_span.get_tag(IAST.JSON) is None - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_disabled_http_request_header_values(self): @self.app.route("/sqli//", methods=["GET", "POST"]) def test_sqli(param_str): @@ -1732,7 +1732,7 @@ def test_sqli(param_str): assert root_span.get_tag(IAST.JSON) is None - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_simple_iast_path_header_and_querystring_not_tainted_if_iast_disabled(self): @self.app.route("/sqli//", methods=["GET", "POST"]) def test_sqli(param_str): @@ -1756,7 +1756,7 @@ def test_sqli(param_str): # not all flask versions have r.text assert resp.text == "select%20from%20table" - @pytest.mark.skipif(not python_supported_by_iast(), reason="Python version not supported by IAST") + @pytest.mark.skipif(not asm_config._iast_supported, reason="Python version not supported by IAST") def test_flask_full_sqli_iast_disabled_http_request_cookies_value(self): @self.app.route("/sqli/cookies/", methods=["GET", "POST"]) def test_sqli(): diff --git a/tests/contrib/dbapi/test_dbapi_appsec.py b/tests/contrib/dbapi/test_dbapi_appsec.py index 085166df575..062a4ca667e 100644 --- a/tests/contrib/dbapi/test_dbapi_appsec.py +++ b/tests/contrib/dbapi/test_dbapi_appsec.py @@ -2,9 +2,9 @@ import pytest from ddtrace.appsec._iast import oce -from ddtrace.appsec._iast._utils import _is_python_version_supported from ddtrace.contrib.dbapi import TracedCursor from ddtrace.settings import Config +from ddtrace.settings.asm import config as asm_config from ddtrace.settings.integration import IntegrationConfig from ddtrace.trace import Pin from tests.appsec.iast.conftest import _end_iast_context_and_oce @@ -33,7 +33,7 @@ def tearDown(self): ): _end_iast_context_and_oce() - @pytest.mark.skipif(not _is_python_version_supported(), reason="IAST compatible versions") + @pytest.mark.skipif(not asm_config._iast_supported, reason="IAST compatible versions") def test_tainted_query(self): from ddtrace.appsec._iast._taint_tracking import OriginType from ddtrace.appsec._iast._taint_tracking._taint_objects import taint_pyobject @@ -56,7 +56,7 @@ def test_tainted_query(self): mock_sql_injection_report.assert_called_once_with(evidence_value=query, dialect="sqlite") - @pytest.mark.skipif(not _is_python_version_supported(), reason="IAST compatible versions") + @pytest.mark.skipif(not asm_config._iast_supported, reason="IAST compatible versions") def test_tainted_query_args(self): from ddtrace.appsec._iast._taint_tracking import OriginType from ddtrace.appsec._iast._taint_tracking._taint_objects import taint_pyobject @@ -79,7 +79,7 @@ def test_tainted_query_args(self): mock_sql_injection_report.assert_not_called() - @pytest.mark.skipif(not _is_python_version_supported(), reason="IAST compatible versions") + @pytest.mark.skipif(not asm_config._iast_supported, reason="IAST compatible versions") def test_untainted_query(self): with mock.patch( "ddtrace.appsec._iast.taint_sinks.sql_injection.SqlInjection.report" @@ -94,7 +94,7 @@ def test_untainted_query(self): mock_sql_injection_report.assert_not_called() - @pytest.mark.skipif(not _is_python_version_supported(), reason="IAST compatible versions") + @pytest.mark.skipif(not asm_config._iast_supported, reason="IAST compatible versions") def test_untainted_query_and_args(self): with mock.patch( "ddtrace.appsec._iast.taint_sinks.sql_injection.SqlInjection.report" @@ -110,7 +110,7 @@ def test_untainted_query_and_args(self): mock_sql_injection_report.assert_not_called() - @pytest.mark.skipif(not _is_python_version_supported(), reason="IAST compatible versions") + @pytest.mark.skipif(not asm_config._iast_supported, reason="IAST compatible versions") def test_tainted_query_iast_disabled(self): from ddtrace.appsec._iast._taint_tracking import OriginType from ddtrace.appsec._iast._taint_tracking._taint_objects import taint_pyobject