`EventScrubber` doesn't scrub a request body that's a top level JSON array
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 78/100
調査の方向性
提供された repro.py で問題を再現し、その後 EventScrubber.scrub_request、scrub_dict、scrub_list を調べて、リクエストデータがどのように処理されるかを追跡します。既存の scrubber テストを使用するか、トップレベルの配列に対するカバレッジを追加します。配列の body 内にあるネストされた password または api_key の値が、オブジェクトの body と同じようにフィルタリングされれば完了です。
索引モデルが issue の本文から書いたものです。
説明
How do you use Sentry?
Sentry Saas (sentry.io)
Version
2.69.2 (also on master at 494ecb3)
Steps to Reproduce
When a request body parses to a top level JSON array, nothing in it gets scrubbed. The same secrets in an object body are filtered normally. No event_scrubber argument, no _experiments data collection config, default max_request_body_size. The integration and the transport in the snippet are only there to catch the event.
A top level array is the usual shape for a bulk endpoint, something like POST /api/v1/users/bulk with a list of records. If those records carry a password or an api_key, they leave the process in the clear. A team that spot checks a single object endpoint sees scrubbing work fine, so there's nothing to tip them off.
Python 3.13.15, Flask 3.1.3, sentry-sdk 2.69.2. Save this as repro.py and run it.
import json
import logging
import sentry_sdk
from flask import Flask
from sentry_sdk.integrations.flask import FlaskIntegration
events = []
class Capture(sentry_sdk.transport.Transport):
def capture_envelope(self, envelope):
for item in envelope.items:
if item.headers.get("type") == "event":
events.append(item.payload.json)
sentry_sdk.init(
dsn="https://public@example.com/1",
integrations=[FlaskIntegration()],
transport=Capture(),
)
app = Flask(__name__)
app.logger.disabled = True
logging.getLogger("werkzeug").disabled = True
@app.route("/bulk", methods=["POST"])
def bulk():
raise ValueError("boom")
@app.route("/single", methods=["POST"])
def single():
raise ValueError("boom")
client = app.test_client()
client.post("/bulk", json=[{"user": "a", "password": "hunter2"}])
client.post("/single", json={"user": "a", "password": "hunter2"})
sentry_sdk.get_client().close()
print("array body :", json.dumps(events[0]["request"]["data"]))
print("object body:", json.dumps(events[1]["request"]["data"]))
Expected Result
The array body should come out filtered the same way the object body does:
array body : [{"password": "[Filtered]", "user": "a"}]
object body: {"password": "[Filtered]", "user": "a"}
Actual Result
array body : [{"password": "hunter2", "user": "a"}]
object body: {"password": "[Filtered]", "user": "a"}
EventScrubber.scrub_request calls scrub_dict on event["request"]["data"], and scrub_dict returns immediately when what it's given isn't a dict, so a list body stops scrubbing before it starts. The class already ships scrub_list, whose docstring says it walks a list and any nested lists and calls scrub_dict on every dictionary it finds, but it's never called on the request body.
This is separate from #7542, which is about how denylist keys are matched. Here the keys never get looked at at all. I have a fix and tests ready if you want a PR.
- 主要言語
- Python
- スター
- 2.2k
- フォーク
- 672
- 平均マージ
- 1日 13分
- マージ済み PR(30日)
- 212
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
getsentry/sentry-python のほかの issue
-
Python
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
getsentry/sentry-python#6992 · コメント 1 件 ·
-
Improvement Python
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
getsentry/sentry-python#6970 · コメント 1 件 ·
-
Bug Python
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
getsentry/sentry-python#6504 · コメント 1 件 ·
-
Improvement Python Spans
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
getsentry/sentry-python#5833 · コメント 1 件 ·
-
Improvement Python Spans
難易度 1/5 1時間未満 初心者へのやさしさ 84/100
getsentry/sentry-python#5832 · コメント 1 件 ·
getsentry/sentry-python の issue をすべて見る
似ている issue
-
documentation help wanted
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
simonw/sqlite-utils#872 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100