Repository navigation
feat(cymbal): mask python code variables with the sdk rules - #112465
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MxaTpjkJ3QxjaCSrYxXFHW
|
😎 Merged successfully - details. |
🤖 CI report✅ Trunk lane — non-backend lane (
|
| File | Comment lines | Added lines |
|---|---|---|
rust/cymbal/src/core/code_variables.rs |
37 | 492 |
rust/cymbal/tests/event.rs |
2 | 70 |
rust/cymbal/src/modes/processing/stages/http_pipeline.rs |
1 | 3 |
This check does not block merging. It updates on every push and clears when the share drops.
|
[Medium risk] Adds server-side masking of Python exception variables. The PR appears safe to merge, though the Authorization matcher can unnecessarily remove diagnostic text. Reviews (2) · Last reviewed commit: "fix(cymbal): port the sdk url-first, pro..." |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe change adds recursive masking for sensitive values in Python-frame Priority: ➖ Normal Merge Risk: 🟡 Moderate · up to Masking of Python code variables can leave short, alphabetic Bearer tokens visible in error-tracking frames, which weakens the privacy guarantee this change is meant to provide. Tighten the prose exemption before merging. Also confirm that the URL credential pattern stops at query and fragment characters. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change reduces credential exposure without expanding access or privileges. Some credential forms still pass through, as they did before, and previously stored secrets are not removed. These limitations prevent treating masking as complete credential protection. Retained concerns Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (1)
rust/cymbal/src/core/code_variables.rs-80-81 (1)
80-81: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winStop the URL userinfo match at
?and#.
[^/\s]*@excludes/but not?or#. Takehttps://host?next=a:b@c. The pattern captureshost?next=a:bas userinfo. That text contains:, so the host and query are replaced withREDACTED. The opposite case also fails: forhttps://u:p@host?x=a@b, the greedy match runs to the last@. The redaction then removes the host, while the credential stays redacted. Exclude?and#from the userinfo class. Keep the greedy match up to the last@in the authority, so a password that contains@is fully masked.Proposed fix
- LazyLock::new(|| Regex::new(r"(?i)([a-z][a-z0-9+.\-]{0,30}://)([^/\s]*)@").unwrap()); + LazyLock::new(|| Regex::new(r"(?i)([a-z][a-z0-9+.\-]{0,30}://)([^/?#\s]*)@").unwrap());Based on learnings: the userinfo pattern "must not span past '/', '?', or '#'".
Source: Learnings
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
- Review profile: QUIET
- Plan: Enterprise
- Run ID:
8e1b3cda-9494-46e6-8f7b-ef7d7c4d9ae0
📒 Files selected for processing (10)
rust/cymbal/README.mdrust/cymbal/src/core/code_variables.rsrust/cymbal/src/core/mod.rsrust/cymbal/src/modes/processing/config.rsrust/cymbal/src/modes/processing/stages/http_pipeline.rsrust/cymbal/src/modes/processing/stages/resolution/mod.rsrust/cymbal/src/modes/processing/types/event.rsrust/cymbal/src/modes/processing/types/exception_event.rsrust/cymbal/tests/common/mod.rsrust/cymbal/tests/event.rs
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.
HostHog preview —
|
…ials Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MxaTpjkJ3QxjaCSrYxXFHW
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MxaTpjkJ3QxjaCSrYxXFHW
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MxaTpjkJ3QxjaCSrYxXFHW
|
CodeRabbit's outside-diff note on |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
rust/cymbal/src/core/code_variables.rs (1)
28-30: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the comment that records a change from the SDK patterns.
The sentence beginning "One difference" explains how this code differs from an earlier or external version. The guideline says comments must not record how the code got here. Keep only the durable fact:
sk_must start a word, sotask_idanddisk_usagekeep their values. Put the SDK comparison in the PR description.Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
- Review profile: QUIET
- Plan: Enterprise
- Run ID:
02aecd37-0186-4814-8a33-f7532578d5f2
📒 Files selected for processing (1)
rust/cymbal/src/core/code_variables.rs
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MxaTpjkJ3QxjaCSrYxXFHW
|
Risk: No findings This delta fixes the prior finding: a single capitalized (or lowercase) word of 8-15 letters after Bearer/Basic is now redacted when it ends the value, and kept as prose only when more alphabetic text follows, via the new is_auth_credential/redact_auth_credentials rewrite loop. No new vulnerabilities found in the change; the only behavioral divergences I could construct are in the over-masking direction, which is safe. Sentinel reviewed |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MxaTpjkJ3QxjaCSrYxXFHW
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository: PostHog/posthog/.coderabbit.yaml
- Review profile: QUIET
- Plan: Enterprise
- Run ID:
3df53658-fee1-4466-9b46-b091a9bcf4e2
📒 Files selected for processing (1)
rust/cymbal/src/core/code_variables.rs
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 9 remain after this review.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MxaTpjkJ3QxjaCSrYxXFHW
Problem
Error tracking shows credentials in Python
code_variableswhen the sending SDK predates a masking rule, and stored frame records keep them.ERROR_TRACKING_DROP_CODE_VARIABLES_TEAM_IDS. Every other team gets them as sent.Changes
code_variablesfor every team not on the drop list, with the posthog-python SDK's default rules. Users see$$_posthog_redacted_based_on_masking_rules_$$where an older SDK sent a credential.Bearer/Basicvalues, the signed-URLsigparameter, URLs scrubbed beforeAuthorizationvalues, and shortBasiccredentials that decode touser:password.sk_must start a word, sotask_idanddisk_usagekeep their values. A team can tune the SDK patterns in its own code but not cymbal's, so a false positive costs more here.Bearer/Basic, a plain word of up to 15 letters counts as prose only when more text follows it. A word at the end of a value, such asBearer Sunflower, looks exactly like a header value, so it is redacted./,?or#, so a:or@in a query string no longer wipes the host.passwordkey the SDK already redacted.Note
Frame records already in Postgres keep their raw values until they are replayed. #110760 adds a command that drops them.
How did you test this code?
Test rationale:
masks_what_the_python_sdk_masksandleaves_benign_values_alonefail when a ported rule stops matching, or starts touching UUIDs, hex digests, paths or prose. No test covered masking, and it is a pure function, so these are unit tests.stores_masked_code_variablesandmasks_code_variables_replayed_from_stored_framesextend the existing drop tests intests/event.rswith the same harness. Removing either hook fails exactly its own test.Performance
Before this PR, cymbal did not mask, so all of the cost below is new. It falls only on Python exception events that carry code variables.
Method and harness
Release build of f46cc04 on an Apple M4 Pro, rustc 1.91.1. The inputs are the wire form that posthog-python
mainproduces for the same cases as the SDK PR's benchmark, so cymbal masks what it would receive. Median of 7 samples per case. The harness ran as a temporary ignored integration test and is not part of this PR.Release status
Docs update
rust/cymbal/README.mddocuments the masking and its setting. No public docs change in this PR.🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Opus 5.5 (
claude-opus-5-5)/writing-tests,/writing-code-comments,/writing-pr-descriptions,/reviewing-with-coderabbit.ERROR_TRACKING_MASK_CODE_VARIABLESkill switch. It was removed on request, so masking is unconditional.🤖 Generated with Claude Code
https://claude.ai/code/session_01MxaTpjkJ3QxjaCSrYxXFHW