Skip to content

Commit

Permalink
Merge branch 'emmett.butler/remove-propagate-calls' into emmett.butle…
Browse files Browse the repository at this point in the history
…r/redis-spans-refactor
  • Loading branch information
emmettbutler authored Apr 30, 2024
2 parents 3a2ec42 + 6fc0f19 commit caadd60
Show file tree
Hide file tree
Showing 49 changed files with 1,584 additions and 1,088 deletions.
12 changes: 0 additions & 12 deletions .github/workflows/build_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,6 @@ on:
# before merging/releasing
- build_deploy*
pull_request:
paths:
- ".github/workflows/build_deploy.yml"
- ".github/workflows/build_python_3.yml"
- "setup.py"
- "setup.cfg"
- "pyproject.toml"
- "**.c"
- "**.h"
- "**.cpp"
- "**.hpp"
- "**.pyx"
- "ddtrace/vendor/**"
release:
types:
- published
Expand Down
5 changes: 2 additions & 3 deletions benchmarks/appsec_iast_propagation/scenario.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
from typing import Any # noqa:F401

import bm

from tests.utils import override_env
from bm.utils import override_env


with override_env({"DD_IAST_ENABLED": "True"}):
Expand Down Expand Up @@ -42,7 +41,7 @@ def aspect_function(internal_loop, tainted):
value = ""
res = value
for _ in range(internal_loop):
res = add_aspect(res, join_aspect(str.join, 1, "_", (tainted, "_", tainted)))
res = add_aspect(res, join_aspect("_".join, 1, "_", (tainted, "_", tainted)))
value = res
res = add_aspect(res, tainted)
value = res
Expand Down
8 changes: 7 additions & 1 deletion ddtrace/_trace/trace_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -636,8 +636,9 @@ def _on_botocore_patched_bedrock_api_call_exception(ctx, exc_info):
span = ctx[ctx["call_key"]]
span.set_exc_info(*exc_info)
prompt = ctx["prompt"]
model_name = ctx["model_name"]
integration = ctx["bedrock_integration"]
if integration.is_pc_sampled_llmobs(span):
if integration.is_pc_sampled_llmobs(span) and "embed" not in model_name:
integration.llmobs_set_tags(span, formatted_response=None, prompt=prompt, err=True)
span.finish()

Expand All @@ -659,13 +660,18 @@ def _on_botocore_bedrock_process_response(
) -> None:
text = formatted_response["text"]
span = ctx[ctx["call_key"]]
model_name = ctx["model_name"]
if should_set_choice_ids:
for i in range(len(text)):
span.set_tag_str("bedrock.response.choices.{}.id".format(i), str(body["generations"][i]["id"]))
integration = ctx["bedrock_integration"]
if metadata is not None:
for k, v in metadata.items():
span.set_tag_str("bedrock.{}".format(k), str(v))
if "embed" in model_name:
span.set_metric("bedrock.response.embedding_length", len(formatted_response["text"][0]))
span.finish()
return
for i in range(len(formatted_response["text"])):
if integration.is_pc_sampled_span(span):
span.set_tag_str(
Expand Down
31 changes: 25 additions & 6 deletions ddtrace/appsec/_asm_request_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from ddtrace._trace.span import Span
from ddtrace.appsec import _handlers
from ddtrace.appsec._constants import APPSEC
from ddtrace.appsec._constants import EXPLOIT_PREVENTION
from ddtrace.appsec._constants import SPAN_DATA_NAMES
from ddtrace.appsec._constants import WAF_CONTEXT_NAMES
from ddtrace.appsec._ddwaf import DDWaf_result
Expand Down Expand Up @@ -147,6 +148,12 @@ def __init__(self):
"triggered": False,
"timeout": False,
"version": None,
"rasp": {
"called": False,
"eval": {t: 0 for _, t in EXPLOIT_PREVENTION.TYPE},
"match": {t: 0 for _, t in EXPLOIT_PREVENTION.TYPE},
"timeout": {t: 0 for _, t in EXPLOIT_PREVENTION.TYPE},
},
}
env.callbacks[_CONTEXT_CALL] = []

Expand Down Expand Up @@ -330,15 +337,27 @@ def asm_request_context_set(


def set_waf_telemetry_results(
rules_version: Optional[str], is_triggered: bool, is_blocked: bool, is_timeout: bool
rules_version: Optional[str],
is_triggered: bool,
is_blocked: bool,
is_timeout: bool,
rule_type: Optional[str],
) -> None:
result = get_value(_TELEMETRY, _TELEMETRY_WAF_RESULTS)
if result is not None:
result["triggered"] |= is_triggered
result["blocked"] |= is_blocked
result["timeout"] |= is_timeout
if rules_version is not None:
result["version"] = rules_version
if rule_type is None:
# Request Blocking telemetry
result["triggered"] |= is_triggered
result["blocked"] |= is_blocked
result["timeout"] |= is_timeout
if rules_version is not None:
result["version"] = rules_version
else:
# Exploit Prevention telemetry
result["rasp"]["called"] = True
result["rasp"]["eval"][rule_type] += 1
result["rasp"]["match"][rule_type] += int(is_triggered)
result["rasp"]["timeout"][rule_type] += int(is_timeout)


def get_waf_telemetry_results() -> Optional[Dict[str, Any]]:
Expand Down
28 changes: 24 additions & 4 deletions ddtrace/appsec/_common_module_patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import ctypes
import gc
import os
from typing import Any
from typing import Callable
from typing import Dict
Expand Down Expand Up @@ -48,14 +49,23 @@ def wrapped_open_CFDDB7ABBA9081B6(original_open_callable, instance, args, kwargs
try:
from ddtrace.appsec._asm_request_context import call_waf_callback
from ddtrace.appsec._asm_request_context import in_context
from ddtrace.appsec._constants import EXPLOIT_PREVENTION
except ImportError:
# open is used during module initialization
# and shouldn't be changed at that time
return original_open_callable(*args, **kwargs)

filename = args[0] if args else kwargs.get("file", None)
filename_arg = args[0] if args else kwargs.get("file", None)
try:
filename = os.fspath(filename_arg)
except Exception:
filename = ""
if filename and in_context():
call_waf_callback({"LFI_ADDRESS": filename}, crop_trace="wrapped_open_CFDDB7ABBA9081B6")
call_waf_callback(
{EXPLOIT_PREVENTION.ADDRESS.LFI: filename},
crop_trace="wrapped_open_CFDDB7ABBA9081B6",
rule_type=EXPLOIT_PREVENTION.TYPE.LFI,
)
# DEV: Next part of the exploit prevention feature: add block here
return original_open_callable(*args, **kwargs)

Expand All @@ -72,6 +82,7 @@ def wrapped_open_ED4CF71136E15EBF(original_open_callable, instance, args, kwargs
try:
from ddtrace.appsec._asm_request_context import call_waf_callback
from ddtrace.appsec._asm_request_context import in_context
from ddtrace.appsec._constants import EXPLOIT_PREVENTION
except ImportError:
# open is used during module initialization
# and shouldn't be changed at that time
Expand All @@ -82,7 +93,11 @@ def wrapped_open_ED4CF71136E15EBF(original_open_callable, instance, args, kwargs
if url.__class__.__name__ == "Request":
url = url.get_full_url()
if isinstance(url, str):
call_waf_callback({"SSRF_ADDRESS": url}, crop_trace="wrapped_open_ED4CF71136E15EBF")
call_waf_callback(
{EXPLOIT_PREVENTION.ADDRESS.SSRF: url},
crop_trace="wrapped_open_ED4CF71136E15EBF",
rule_type=EXPLOIT_PREVENTION.TYPE.SSRF,
)
# DEV: Next part of the exploit prevention feature: add block here
return original_open_callable(*args, **kwargs)

Expand All @@ -100,6 +115,7 @@ def wrapped_request_D8CB81E472AF98A2(original_request_callable, instance, args,
try:
from ddtrace.appsec._asm_request_context import call_waf_callback
from ddtrace.appsec._asm_request_context import in_context
from ddtrace.appsec._constants import EXPLOIT_PREVENTION
except ImportError:
# open is used during module initialization
# and shouldn't be changed at that time
Expand All @@ -108,7 +124,11 @@ def wrapped_request_D8CB81E472AF98A2(original_request_callable, instance, args,
url = args[1] if len(args) > 1 else kwargs.get("url", None)
if url and in_context():
if isinstance(url, str):
call_waf_callback({"SSRF_ADDRESS": url}, crop_trace="wrapped_request_D8CB81E472AF98A2")
call_waf_callback(
{EXPLOIT_PREVENTION.ADDRESS.SSRF: url},
crop_trace="wrapped_request_D8CB81E472AF98A2",
rule_type=EXPLOIT_PREVENTION.TYPE.SSRF,
)
# DEV: Next part of the exploit prevention feature: add block here
return original_request_callable(*args, **kwargs)

Expand Down
9 changes: 9 additions & 0 deletions ddtrace/appsec/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,12 @@ class EXPLOIT_PREVENTION(metaclass=Constant_Class):
STACK_TRACE_ENABLED = "DD_APPSEC_STACK_TRACE_ENABLED"
MAX_STACK_TRACES = "DD_APPSEC_MAX_STACK_TRACES"
MAX_STACK_TRACE_DEPTH = "DD_APPSEC_MAX_STACK_TRACE_DEPTH"

class TYPE(metaclass=Constant_Class):
LFI = "lfi"
SSRF = "ssrf"
SQLI = "sql_injection"

class ADDRESS(metaclass=Constant_Class):
LFI = "LFI_ADDRESS"
SSRF = "SSRF_ADDRESS"
4 changes: 4 additions & 0 deletions ddtrace/appsec/_iast/_evidence_redaction/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from ddtrace.appsec._iast._evidence_redaction._sensitive_handler import sensitive_handler


sensitive_handler
Loading

0 comments on commit caadd60

Please sign in to comment.