Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 8 additions & 8 deletions benchmarks/bm/iast_fixtures/str_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ def get_random_string_join(mystring: str) -> Text:

def get_random_string_seed(
length=12,
allowed_chars="abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
allowed_chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
): # type: (int, str) -> str
"""
Returns a securely generated random string.
Expand Down Expand Up @@ -1180,13 +1180,13 @@ def do_add_re_compile():
import re

invalid_unicode_no_surrogate = (
"[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF"
"\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF"
"\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF"
"\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF"
"\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF"
"\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF"
"\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]"
"[\u0001-\u0008\u000b\u000e-\u001f\u007f-\u009f\ufdd0-\ufdef"
"\ufffe\uffff\U0001fffe\U0001ffff\U0002fffe\U0002ffff"
"\U0003fffe\U0003ffff\U0004fffe\U0004ffff\U0005fffe\U0005ffff"
"\U0006fffe\U0006ffff\U0007fffe\U0007ffff\U0008fffe\U0008ffff"
"\U0009fffe\U0009ffff\U000afffe\U000affff\U000bfffe\U000bffff"
"\U000cfffe\U000cffff\U000dfffe\U000dffff\U000efffe\U000effff"
"\U000ffffe\U000fffff\U0010fffe\U0010ffff]"
) # noqa:F401
_ = re.compile(invalid_unicode_no_surrogate[:-1] + eval('"\\uD800-\\uDFFF"') + "]") # pylint:disable=eval-used

Expand Down
1 change: 1 addition & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Local plugins: https://docs.pytest.org/en/3.10.1/writing_plugins.html#local-conftest-plugins
Hook reference: https://docs.pytest.org/en/3.10.1/reference.html#hook-reference
"""

import os
import re
import sys
Expand Down
1 change: 1 addition & 0 deletions ddtrace/_trace/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Any `sampled = False` trace won't be written, and can be ignored by the instrumentation.
"""

import json
from json.decoder import JSONDecodeError
from typing import Dict
Expand Down
19 changes: 11 additions & 8 deletions ddtrace/_trace/utils_valkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,17 @@ def _set_span_tags(
@contextmanager
def _instrument_valkey_cmd(pin, config_integration, instance, args):
query = stringify_cache_args(args, cmd_max_len=config_integration.cmd_max_length)
with core.context_with_data(
"valkey.command",
span_name=schematize_cache_operation(valkeyx.CMD, cache_provider=valkeyx.APP),
pin=pin,
service=trace_utils.ext_service(pin, config_integration),
span_type=SpanTypes.VALKEY,
resource=query.split(" ")[0] if config_integration.resource_only_command else query,
) as ctx, ctx.span as span:
with (
core.context_with_data(
"valkey.command",
span_name=schematize_cache_operation(valkeyx.CMD, cache_provider=valkeyx.APP),
pin=pin,
service=trace_utils.ext_service(pin, config_integration),
span_type=SpanTypes.VALKEY,
resource=query.split(" ")[0] if config_integration.resource_only_command else query,
) as ctx,
ctx.span as span,
):
_set_span_tags(span, pin, config_integration, args, instance, query)
yield ctx

Expand Down
60 changes: 30 additions & 30 deletions ddtrace/appsec/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,43 +81,43 @@ class APPSEC(metaclass=Constant_Class):
USER_LOGIN_EVENT_PREFIX_PUBLIC: Literal["appsec.events.users.login"] = "appsec.events.users.login"
USER_LOGIN_USERID: Literal["_dd.appsec.usr.id"] = "_dd.appsec.usr.id"
USER_LOGIN_USERNAME: Literal["_dd.appsec.usr.login"] = "_dd.appsec.usr.login"
USER_LOGIN_EVENT_SUCCESS_TRACK: Literal[
USER_LOGIN_EVENT_SUCCESS_TRACK: Literal["appsec.events.users.login.success.track"] = (
"appsec.events.users.login.success.track"
] = "appsec.events.users.login.success.track"
USER_LOGIN_EVENT_FAILURE_TRACK: Literal[
)
USER_LOGIN_EVENT_FAILURE_TRACK: Literal["appsec.events.users.login.failure.track"] = (
"appsec.events.users.login.failure.track"
] = "appsec.events.users.login.failure.track"
)
USER_SIGNUP_EVENT: Literal["appsec.events.users.signup.track"] = "appsec.events.users.signup.track"
USER_SIGNUP_EVENT_USERNAME: Literal["appsec.events.users.signup.usr.login"] = "appsec.events.users.signup.usr.login"
USER_SIGNUP_EVENT_USERID: Literal["appsec.events.users.signup.usr.id"] = "appsec.events.users.signup.usr.id"
USER_SIGNUP_EVENT_MODE: Literal[
USER_SIGNUP_EVENT_MODE: Literal["_dd.appsec.events.users.signup.auto.mode"] = (
"_dd.appsec.events.users.signup.auto.mode"
] = "_dd.appsec.events.users.signup.auto.mode"
AUTO_LOGIN_EVENTS_SUCCESS_MODE: Literal[
)
AUTO_LOGIN_EVENTS_SUCCESS_MODE: Literal["_dd.appsec.events.users.login.success.auto.mode"] = (
"_dd.appsec.events.users.login.success.auto.mode"
] = "_dd.appsec.events.users.login.success.auto.mode"
AUTO_LOGIN_EVENTS_FAILURE_MODE: Literal[
)
AUTO_LOGIN_EVENTS_FAILURE_MODE: Literal["_dd.appsec.events.users.login.failure.auto.mode"] = (
"_dd.appsec.events.users.login.failure.auto.mode"
] = "_dd.appsec.events.users.login.failure.auto.mode"
)
AUTO_LOGIN_EVENTS_COLLECTION_MODE: Literal["_dd.appsec.user.collection_mode"] = "_dd.appsec.user.collection_mode"
BLOCKED: Literal["appsec.blocked"] = "appsec.blocked"
EVENT: Literal["appsec.event"] = "appsec.event"
AUTO_USER_INSTRUMENTATION_MODE: Literal[
AUTO_USER_INSTRUMENTATION_MODE: Literal["DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE"] = (
"DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE"
] = "DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE"
AUTO_USER_INSTRUMENTATION_MODE_ENABLED: Literal[
)
AUTO_USER_INSTRUMENTATION_MODE_ENABLED: Literal["DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED"] = (
"DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED"
] = "DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING_ENABLED"
)
USER_MODEL_LOGIN_FIELD: Literal["DD_USER_MODEL_LOGIN_FIELD"] = "DD_USER_MODEL_LOGIN_FIELD"
USER_MODEL_EMAIL_FIELD: Literal["DD_USER_MODEL_EMAIL_FIELD"] = "DD_USER_MODEL_EMAIL_FIELD"
USER_MODEL_NAME_FIELD: Literal["DD_USER_MODEL_NAME_FIELD"] = "DD_USER_MODEL_NAME_FIELD"
PROPAGATION_HEADER: Literal["_dd.p.ts"] = "_dd.p.ts"
OBFUSCATION_PARAMETER_KEY_REGEXP: Literal[
OBFUSCATION_PARAMETER_KEY_REGEXP: Literal["DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP"] = (
"DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP"
] = "DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP"
OBFUSCATION_PARAMETER_VALUE_REGEXP: Literal[
)
OBFUSCATION_PARAMETER_VALUE_REGEXP: Literal["DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP"] = (
"DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP"
] = "DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP"
)
RC_CLIENT_ID: Literal["_dd.rc.client_id"] = "_dd.rc.client_id"
WAF_ERROR: Literal["_dd.appsec.waf.error"] = "_dd.appsec.waf.error"
RASP_ERROR: Literal["_dd.appsec.rasp.error"] = "_dd.appsec.rasp.error"
Expand Down Expand Up @@ -148,9 +148,9 @@ class IAST(metaclass=Constant_Class):
ENV_SINK_POINTS_ENABLED: Literal["DD_IAST_SINK_POINTS_ENABLED"] = "DD_IAST_SINK_POINTS_ENABLED"
ENV_PROPAGATION_DEBUG: Literal["DD_IAST_PROPAGATION_DEBUG"] = "DD_IAST_PROPAGATION_DEBUG"
ENV_REQUEST_SAMPLING: Literal["DD_IAST_REQUEST_SAMPLING"] = "DD_IAST_REQUEST_SAMPLING"
DD_IAST_VULNERABILITIES_PER_REQUEST: Literal[
DD_IAST_VULNERABILITIES_PER_REQUEST: Literal["DD_IAST_VULNERABILITIES_PER_REQUEST"] = (
"DD_IAST_VULNERABILITIES_PER_REQUEST"
] = "DD_IAST_VULNERABILITIES_PER_REQUEST"
)
DD_IAST_MAX_CONCURRENT_REQUESTS: Literal["DD_IAST_MAX_CONCURRENT_REQUESTS"] = "DD_IAST_MAX_CONCURRENT_REQUESTS"
ENV_TELEMETRY_REPORT_LVL: Literal["DD_IAST_TELEMETRY_VERBOSITY"] = "DD_IAST_TELEMETRY_VERBOSITY"
LAZY_TAINT: Literal["_DD_IAST_LAZY_TAINT"] = "_DD_IAST_LAZY_TAINT"
Expand Down Expand Up @@ -185,9 +185,9 @@ class IAST_SPAN_TAGS(metaclass=Constant_Class):

TELEMETRY_REQUEST_TAINTED: Literal["_dd.iast.telemetry.request.tainted"] = "_dd.iast.telemetry.request.tainted"
TELEMETRY_EXECUTED_SINK: Literal["_dd.iast.telemetry.executed.sink"] = "_dd.iast.telemetry.executed.sink"
TELEMETRY_SUPPRESSED_VULNERABILITY: Literal[
TELEMETRY_SUPPRESSED_VULNERABILITY: Literal["_dd.iast.telemetry.suppressed.vulnerabilities"] = (
"_dd.iast.telemetry.suppressed.vulnerabilities"
] = "_dd.iast.telemetry.suppressed.vulnerabilities"
)
TELEMETRY_EXECUTED_SOURCE: Literal["_dd.iast.telemetry.executed.source"] = "_dd.iast.telemetry.executed.source"


Expand Down Expand Up @@ -252,9 +252,9 @@ class SPAN_DATA_NAMES(metaclass=Constant_Class):
REQUEST_BODY: Literal["http.request.body"] = "http.request.body"
REQUEST_QUERY: Literal["http.request.query"] = "http.request.query"
REQUEST_HEADERS_NO_COOKIES: Literal["http.request.headers"] = "http.request.headers"
REQUEST_HEADERS_NO_COOKIES_CASE: Literal[
REQUEST_HEADERS_NO_COOKIES_CASE: Literal["http.request.headers_case_sensitive"] = (
"http.request.headers_case_sensitive"
] = "http.request.headers_case_sensitive"
)
REQUEST_URI_RAW: Literal["http.request.uri"] = "http.request.uri"
REQUEST_ROUTE: Literal["http.request.route"] = "http.request.route"
REQUEST_METHOD: Literal["http.request.method"] = "http.request.method"
Expand Down Expand Up @@ -287,12 +287,12 @@ class API_SECURITY(metaclass=Constant_Class):
SAMPLE_RATE: Literal["DD_API_SECURITY_REQUEST_SAMPLE_RATE"] = "DD_API_SECURITY_REQUEST_SAMPLE_RATE"
SAMPLE_DELAY: Literal["DD_API_SECURITY_SAMPLE_DELAY"] = "DD_API_SECURITY_SAMPLE_DELAY"
MAX_PAYLOAD_SIZE: Literal[0x1000000] = 0x1000000 # 16MB maximum size
ENDPOINT_COLLECTION: Literal[
ENDPOINT_COLLECTION: Literal["DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED"] = (
"DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED"
] = "DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED"
ENDPOINT_COLLECTION_LIMIT: Literal[
)
ENDPOINT_COLLECTION_LIMIT: Literal["DD_API_SECURITY_ENDPOINT_COLLECTION_MESSAGE_LIMIT"] = (
"DD_API_SECURITY_ENDPOINT_COLLECTION_MESSAGE_LIMIT"
] = "DD_API_SECURITY_ENDPOINT_COLLECTION_MESSAGE_LIMIT"
)


class WAF_CONTEXT_NAMES(metaclass=Constant_Class):
Expand Down Expand Up @@ -376,9 +376,9 @@ class EXPLOIT_PREVENTION(metaclass=Constant_Class):
STACK_TRACE_ENABLED: Literal["DD_APPSEC_STACK_TRACE_ENABLED"] = "DD_APPSEC_STACK_TRACE_ENABLED"
MAX_STACK_TRACES: Literal["DD_APPSEC_MAX_STACK_TRACES"] = "DD_APPSEC_MAX_STACK_TRACES"
MAX_STACK_TRACE_DEPTH: Literal["DD_APPSEC_MAX_STACK_TRACE_DEPTH"] = "DD_APPSEC_MAX_STACK_TRACE_DEPTH"
STACK_TOP_PERCENT: Literal[
STACK_TOP_PERCENT: Literal["DD_APPSEC_MAX_STACK_TRACE_DEPTH_TOP_PERCENT"] = (
"DD_APPSEC_MAX_STACK_TRACE_DEPTH_TOP_PERCENT"
] = "DD_APPSEC_MAX_STACK_TRACE_DEPTH_TOP_PERCENT"
)

class TYPE(metaclass=Constant_Class):
CMDI: Literal["command_injection"] = "command_injection"
Expand Down
1 change: 1 addition & 0 deletions ddtrace/appsec/_iast/_overhead_control_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
limit. It will measure operations being executed in a request and it will deactivate detection
(and therefore reduce the overhead to nearly 0) if a certain threshold is reached.
"""

from ddtrace._trace.sampler import RateSampler
from ddtrace._trace.span import Span
from ddtrace.appsec._iast._utils import _is_iast_debug_enabled
Expand Down
8 changes: 2 additions & 6 deletions ddtrace/appsec/_iast/_patch_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
The module uses wrapt's function wrapping capabilities to intercept calls to security-sensitive
functions and enable taint tracking and vulnerability detection.
"""

import functools
from typing import Callable
from typing import Optional
Expand Down Expand Up @@ -110,12 +111,7 @@ def unpatch(self):

def __repr__(self):
"""Return a string representation of the IASTFunction instance."""
return (
f"IASTFunction(name={self.name}, "
f"function={self.function}, "
f"hook={self.hook}, "
f"force={self.force})"
)
return f"IASTFunction(name={self.name}, function={self.function}, hook={self.hook}, force={self.force})"


class WrapFunctonsForIAST:
Expand Down
1 change: 1 addition & 0 deletions ddtrace/appsec/_iast/taint_sinks/header_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
This module implements taint sink detection to track and block cases where tainted data
is passed to header-setting APIs without proper sanitization.
""" # noqa: D301

import typing
from typing import Text

Expand Down
1 change: 1 addition & 0 deletions ddtrace/appsec/trace_utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Public API for User events"""

from functools import wraps

from ddtrace.appsec import _metrics
Expand Down
1 change: 1 addition & 0 deletions ddtrace/auto.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ def main():
If you'd like more granular control over instrumentation setup, you can call the `patch*` functions
directly.
"""

import ddtrace.bootstrap.sitecustomize # noqa:F401
1 change: 1 addition & 0 deletions ddtrace/contrib/aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ async def home_handler(request):
:ref:`All HTTP tags <http-tagging>` are supported for this integration.

"""

from ddtrace.contrib.internal.aiohttp.middlewares import trace_app


Expand Down
1 change: 0 additions & 1 deletion ddtrace/contrib/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ def handle_request(scope, send):
.. __: https://asgi.readthedocs.io/
"""


from ddtrace.contrib.internal.asgi.middleware import TraceMiddleware
from ddtrace.contrib.internal.asgi.middleware import span_from_scope

Expand Down
1 change: 1 addition & 0 deletions ddtrace/contrib/bottle.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
config.bottle['distributed_tracing'] = True

"""

from ddtrace.contrib.internal.bottle.trace import TracePlugin


Expand Down
1 change: 1 addition & 0 deletions ddtrace/contrib/celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def run(self):
Default: ``'celery-worker'``

"""

from ddtrace.contrib.internal.celery.app import patch_app
from ddtrace.contrib.internal.celery.app import unpatch_app

Expand Down
1 change: 1 addition & 0 deletions ddtrace/contrib/cherrypy.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def index(self):

cherrypy.quickstart(HelloWorld())
"""

from ddtrace.contrib.internal.cherrypy.patch import TraceMiddleware


Expand Down
1 change: 1 addition & 0 deletions ddtrace/contrib/dbapi.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Generic dbapi tracing code.
"""

import wrapt

from ddtrace import config
Expand Down
1 change: 1 addition & 0 deletions ddtrace/contrib/falcon.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def on_falcon_request(span, request, response):

:ref:`Headers tracing <http-headers-tracing>` is supported for this integration.
"""

from ddtrace.contrib.internal.falcon.middleware import TraceMiddleware


Expand Down
1 change: 1 addition & 0 deletions ddtrace/contrib/flask_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def counter():
Cache = get_traced_cache(tracer, service='my-flask-cache-app', cache_cls=Cache)

"""

from ddtrace.contrib.internal.flask_cache.patch import get_traced_cache


Expand Down
35 changes: 19 additions & 16 deletions ddtrace/contrib/internal/asgi/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,22 +209,25 @@ async def __call__(self, scope: Mapping[str, Any], receive: Callable, send: Call
if scope["type"] == "http":
operation_name = schematize_url_operation(operation_name, direction=SpanDirection.INBOUND, protocol="http")

with core.context_with_data(
"asgi.request",
remote_addr=scope.get("REMOTE_ADDR"),
headers=headers,
headers_case_sensitive=True,
environ=scope,
middleware=self,
span_name=operation_name,
resource=resource,
span_type=SpanTypes.WEB,
service=trace_utils.int_service(None, self.integration_config),
distributed_headers=headers,
activate_distributed_headers=True,
scope=scope,
integration_config=self.integration_config,
) as ctx, ctx.span as span:
with (
core.context_with_data(
"asgi.request",
remote_addr=scope.get("REMOTE_ADDR"),
headers=headers,
headers_case_sensitive=True,
environ=scope,
middleware=self,
span_name=operation_name,
resource=resource,
span_type=SpanTypes.WEB,
service=trace_utils.int_service(None, self.integration_config),
distributed_headers=headers,
activate_distributed_headers=True,
scope=scope,
integration_config=self.integration_config,
) as ctx,
ctx.span as span,
):
if self.span_modifier:
self.span_modifier(span, scope)

Expand Down
1 change: 1 addition & 0 deletions ddtrace/contrib/internal/asgi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""

import asyncio
import inspect

Expand Down
Loading
Loading