mirror of
https://github.com/Sea-Haven-Industries/procurement-ingest.git
synced 2026-09-30 09:33:15 +00:00
fix(lambda): strip Sentry stack-frame locals
This commit is contained in:
parent
b9c6ec0f78
commit
620e380820
2 changed files with 80 additions and 2 deletions
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
Imported for side effect from each handler. ``init_sentry()`` is a no-op when
|
||||
``SENTRY_DSN`` is unset so pytest, local invokes, and a missing HCP var never
|
||||
talk to Sentry. ``before_send`` strips auth headers and drops request/extra
|
||||
keys that can hold MIME bodies, Bedrock prompts, or HMAC secret material.
|
||||
talk to Sentry. ``before_send`` strips auth headers, drops request/extra keys
|
||||
that can hold MIME bodies, Bedrock prompts, or HMAC secret material, and
|
||||
removes exception stack-frame locals. ``include_local_variables=False`` keeps
|
||||
those locals out of the event in the first place.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
|
@ -63,6 +65,38 @@ def _scrub_headers(headers):
|
|||
return headers
|
||||
|
||||
|
||||
def _stacktraces(event):
|
||||
traces = []
|
||||
stacktrace = event.get("stacktrace")
|
||||
if isinstance(stacktrace, dict):
|
||||
traces.append(stacktrace)
|
||||
for section in ("exception", "threads"):
|
||||
container = event.get(section)
|
||||
if not isinstance(container, dict):
|
||||
continue
|
||||
values = container.get("values")
|
||||
if not isinstance(values, list):
|
||||
continue
|
||||
for item in values:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
inner = item.get("stacktrace")
|
||||
if isinstance(inner, dict):
|
||||
traces.append(inner)
|
||||
return traces
|
||||
|
||||
|
||||
def _strip_stack_locals(event):
|
||||
"""Drop frame locals. Names like ``raw``/``item`` still hold MIME or secrets."""
|
||||
for stacktrace in _stacktraces(event):
|
||||
frames = stacktrace.get("frames")
|
||||
if not isinstance(frames, list):
|
||||
continue
|
||||
for frame in frames:
|
||||
if isinstance(frame, dict):
|
||||
frame.pop("vars", None)
|
||||
|
||||
|
||||
def _before_send(event, _hint):
|
||||
request = event.get("request")
|
||||
if isinstance(request, dict):
|
||||
|
|
@ -78,6 +112,7 @@ def _before_send(event, _hint):
|
|||
lower = str(key).lower()
|
||||
if any(needle in lower for needle in _DROP_EXTRA_NEEDLES):
|
||||
extra.pop(key, None)
|
||||
_strip_stack_locals(event)
|
||||
return event
|
||||
|
||||
|
||||
|
|
@ -89,6 +124,7 @@ def init_sentry():
|
|||
dsn=dsn,
|
||||
integrations=[AwsLambdaIntegration(timeout_warning=True)],
|
||||
send_default_pii=False,
|
||||
include_local_variables=False,
|
||||
enable_logs=False,
|
||||
traces_sample_rate=0.0,
|
||||
before_send=_before_send,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ def test_set_dsn_inits_lambda_integration(sentry_mod, monkeypatch):
|
|||
kwargs = mocked.call_args.kwargs
|
||||
assert kwargs["dsn"] == "https://key@o1.ingest.sentry.io/1"
|
||||
assert kwargs["send_default_pii"] is False
|
||||
assert kwargs["include_local_variables"] is False
|
||||
assert kwargs["enable_logs"] is False
|
||||
assert kwargs["traces_sample_rate"] == 0.0
|
||||
assert kwargs["before_send"] is sentry_mod._before_send
|
||||
|
|
@ -100,3 +101,44 @@ def test_before_send_drops_body_prompt_and_secret_keys(sentry_mod):
|
|||
assert "bedrock_prompt" not in out["extra"]
|
||||
assert "hmac_secret" not in out["extra"]
|
||||
assert out["extra"]["po_number"] == "123"
|
||||
|
||||
|
||||
def test_before_send_drops_exception_and_thread_frame_locals(sentry_mod):
|
||||
event = {
|
||||
"exception": {
|
||||
"values": [
|
||||
{
|
||||
"stacktrace": {
|
||||
"frames": [
|
||||
{
|
||||
"function": "handler",
|
||||
"vars": {
|
||||
"raw_email": "From: attacker",
|
||||
"SecretString": "aabbcc",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"threads": {
|
||||
"values": [
|
||||
{
|
||||
"stacktrace": {
|
||||
"frames": [
|
||||
{"function": "extract_with_claude", "vars": {"prompt": "EXTRACT"}}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"stacktrace": {
|
||||
"frames": [{"function": "save_work_order", "vars": {"item": {"wo": 1}}}]
|
||||
},
|
||||
}
|
||||
out = sentry_mod._before_send(event, {})
|
||||
assert "vars" not in out["exception"]["values"][0]["stacktrace"]["frames"][0]
|
||||
assert "vars" not in out["threads"]["values"][0]["stacktrace"]["frames"][0]
|
||||
assert "vars" not in out["stacktrace"]["frames"][0]
|
||||
assert out["exception"]["values"][0]["stacktrace"]["frames"][0]["function"] == "handler"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue