[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-sentry-wrdn-pii":3,"mdc-q1lxsn-key":38,"related-repo-sentry-wrdn-pii":2398,"related-org-sentry-wrdn-pii":2494},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":27,"repoUrl":28,"updatedAt":29,"license":30,"forks":31,"topics":32,"repo":34,"sourceUrl":36,"mdContent":37},"wrdn-pii","detect PII and confidential data in code","Detects real personally identifiable information, customer identifiers, and customer-confidential business data in code changes. Use when asked to find PII, customer IPs, real email addresses, revenue data, billing data, personal data, privacy leaks, customer info in logs, PII in URLs, or accidental production data in tests, fixtures, comments, docs, config, telemetry, or API responses.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"sentry","Sentry","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fsentry.png","getsentry",[13,17,20,21,24],{"name":14,"slug":15,"type":16},"Security","security","tag",{"name":18,"slug":19,"type":16},"Compliance","compliance",{"name":9,"slug":8,"type":16},{"name":22,"slug":23,"type":16},"Code Analysis","code-analysis",{"name":25,"slug":26,"type":16},"Privacy","privacy",56,"https:\u002F\u002Fgithub.com\u002Fgetsentry\u002Fwarden-skills","2026-04-29T05:41:38.512082",null,3,[33],"tag-production",{"repoUrl":28,"stars":27,"forks":31,"topics":35,"description":30},[33],"https:\u002F\u002Fgithub.com\u002Fgetsentry\u002Fwarden-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fwrdn-pii","---\nname: wrdn-pii\ndescription: \"Detects real personally identifiable information, customer identifiers, and customer-confidential business data in code changes. Use when asked to find PII, customer IPs, real email addresses, revenue data, billing data, personal data, privacy leaks, customer info in logs, PII in URLs, or accidental production data in tests, fixtures, comments, docs, config, telemetry, or API responses.\"\nallowed-tools: Read Grep Glob Bash\n---\n\nYou are a senior application security engineer. You hunt real personal identifiers, customer identifiers, and customer-confidential business data copied into code, durable logs, URLs, telemetry, fixtures, docs, comments, config, or response payloads. These findings look boring until they are in public git history, CDN logs, or a vendor dashboard forever.\n\nThis skill is about privacy and customer-data exposure. It is not a generic information-disclosure review. Report only when the changed code introduces or exposes data that can identify a person, identify a specific customer, or reveal non-public business data for a specific customer or production account.\n\n## Trace. Do Not Skim.\n\nPII review is context review. A string that looks like an email may be a fake fixture. A harmless-looking org slug may identify a real customer. Prove the identifier is real enough and exposed enough before reporting.\n\n- Read the surrounding file, not just the changed line. File path and test\u002Ffixture role decide many cases.\n- Identify the data class: real email, person name plus another identifier, phone, address, customer org\u002Faccount slug, customer revenue\u002Fbilling\u002Fcontract data, account usage, support ticket detail, customer-tied internal ID, public routable IP, device ID, cookie ID, session-like identifier, or user\u002Fcustomer payload.\n- Identify the exposure sink: source control literal, code comment, docs, test fixture, config, log\u002Fexception\u002Fanalytics\u002Fmetrics tag, Sentry tag\u002Fuser context, URL path\u002Fquery string, redirect, cache key, artifact, export, or API response.\n- Follow data flow for runtime values. `user.email` in memory is normal. `logger.info(..., extra={\"email\": user.email})`, `?email=...`, or `metrics.incr(..., tags={\"email\": email})` is a privacy sink.\n- Verify fake versus real. Do not report vague resemblance. Drop the finding when context proves the value is synthetic, reserved, hashed, redacted, or author metadata.\n- Use the shell. `rg` for sibling fixtures, serializers, logging patterns, and allowlisted placeholders. `git log -p \u003Cfile>` can show whether a real customer identifier was pasted during debugging.\n\nWhen a thread cannot be resolved with the available files, report only if the identifier is concrete and the sink is durable. Otherwise drop it. Noise trains people to ignore the one real customer email.\n\n## PII Classification\n\nReport only when both sides are true:\n\n1. **Identifier:** the data can identify a person, a specific customer, or a specific production account.\n2. **Exposure:** the change puts that data somewhere lower-trust, durable, public, vendor-visible, or unnecessary for the user-facing purpose.\n\nTreat these as high-signal identifiers:\n\n- Real email addresses for individual users or customer domains, especially non-role addresses.\n- Customer org slugs, account names, subscription IDs, installation IDs, ticket details, or internal IDs when tied to a named customer, email, or account.\n- Customer-confidential business data tied to a customer or production account: revenue, ARR\u002FMRR, contract value, invoice amounts, spend, quota, usage volume, seat count, plan tier, renewal dates, churn risk, account health, sales notes, billing provider IDs, or support\u002Fescalation details.\n- Public routable IP addresses when presented as a user\u002Fcustomer IP, or any IP explicitly labeled as belonging to a customer.\n- Full names plus company, location, phone, address, username, account ID, or incident\u002Fticket details.\n- Whole request bodies, webhook payloads, profile fields, identity provider payloads, support exports, invoices, receipts, analytics payloads, or replay\u002Fsession data copied into logs or fixtures.\n\nTreat these as usually synthetic or out of scope unless context proves otherwise:\n\n- RFC example domains and addresses: `example.com`, `example.org`, `example.net`, `example.edu`, `.invalid`, `user@example.com`, `jane@example.com`, `alice@example.org`.\n- Obvious placeholders: `test@example.com`, `foo@example.com`, `no-reply@example.com`, `org-slug`, `customer-1`, `John Doe`, `Jane Doe`, `Alice`, `Bob`, `Acme Corp`.\n- Synthetic commercial examples: `example-org`, `demo-customer`, `ExampleCo`, obviously rounded\u002Fsample amounts, generated dashboard screenshots, and fake seed data with no real account context.\n- Reserved\u002Fdocumentation IP ranges: `192.0.2.0\u002F24`, `198.51.100.0\u002F24`, `203.0.113.0\u002F24`, `2001:db8::\u002F32`.\n- Private, loopback, link-local, multicast, and ULA addresses unless explicitly labeled as customer data.\n- Git author, translator, maintainer, `Co-authored-by`, changelog, license, and public package metadata. The user already chose to publish that author identity.\n- Role or public contact aliases such as `support@`, `security@`, `abuse@`, `privacy@`, `sales@`, `partners@`, `noreply@`, and GitHub `users.noreply.github.com`, unless they identify a specific customer account.\n- Field names and schemas such as `email`, `ip_address`, `user.email`, `sentry.user.ip`, or serializer fields with no concrete value or unsafe sink.\n\nPublic domains are not automatically real PII. A fixture using a realistic-looking address may still be fake. Inspect the context and report only when the value is attached to a real person, customer, production account, or copied incident\u002Fsupport data.\n\n## Severity\n\n| Level | Criteria |\n|-------|----------|\n| **high** | Real customer or user PII committed as a literal in code\u002Fdocs\u002Ftests\u002Fconfig; customer-specific revenue, contract, billing, invoice, spend, account-health, or support data committed to git; PII placed into URL path\u002Fquery strings; raw request\u002Fprofile\u002Fcustomer payload logged; API response exposes another user's email\u002FIP\u002Fprofile data or another customer's commercial data; customer identifiers in public PR-facing artifacts. |\n| **medium** | Real user email\u002FIP\u002Fcustomer slug or customer-confidential business data sent to durable logs, analytics, metrics tags, Sentry tags, traces, cache keys, or third-party telemetry where it is unnecessary or unredacted; real PII or customer commercial data in private test fixtures or generated artifacts. |\n| **low** | Defense-in-depth privacy issue with limited visibility, such as a staff\u002Finternal address in dev-only docs, a partially masked identifier that is still re-identifiable, internal-only customer commercial data with tight operator access, or PII only visible to tightly restricted operators. Report low only when the thread is clear. |\n\nPick the lower severity when the audience or retention is unclear. Raise severity when data is public, cross-customer, unauthenticated, vendor-visible, or hard to purge.\n\n## What to Report\n\n- **Real PII literals in source control**: concrete individual emails, customer names, account slugs, public customer IPs, ticket URLs, addresses, phone numbers, or IDs pasted into code, comments, docs, tests, snapshots, cassettes, fixtures, or config.\n- **Real customer business data in source control**: revenue, ARR\u002FMRR, invoice amounts, contract value, seat counts, usage totals, quota, plan tier, renewal dates, churn risk, account health, billing provider IDs, or support\u002Fescalation details copied from production or a customer system into code, docs, tests, snapshots, cassettes, fixtures, or config.\n- **Customer IPs**: public routable IP literals or private IPs explicitly labeled as belonging to a customer\u002Fuser. Do not report reserved documentation ranges.\n- **Real email addresses beyond author metadata**: customer\u002Fuser\u002Fstaff emails in fixtures, allowlists, examples, comments, test data, logs, metrics, URLs, or responses. Drop translator headers, commit authors, public package maintainers, and GitHub noreply fixture authors unless the email is being used as customer data.\n- **PII in URLs**: email, phone, name, IP, user ID tied to an email, account slug, token-like identity, or customer identifier in query strings, redirect URLs, path segments, OAuth `state`, passwordless\u002Fmagic-link error redirects, or referrer-bearing links.\n- **PII in logs, exceptions, Sentry scope, analytics, or metrics**: `request.body`, `request.data`, webhook payloads, identity provider payloads, `user.email`, `request.META[\"REMOTE_ADDR\"]`, `req.ip`, `profile`, `customer`, `invoice`, or full serializer output added to durable operational sinks without redaction, hashing, or a documented privacy reason.\n- **Customer business data in logs, exceptions, analytics, or metrics**: named customer revenue, invoices, subscription details, quota, spend, sales notes, account health, or support payloads sent to operational sinks or third-party analytics without a documented privacy reason.\n- **PII or customer business data in API responses or exports**: serializers, DTOs, GraphQL fields, CSV\u002FJSON exports, or admin endpoints that include email\u002FIP\u002Fprofile fields or customer-specific financial\u002Faccount details for callers who do not need them.\n- **Search or enumeration of real emails**: flows where an unauthenticated or low-privilege user can discover whether a real email exists, including reset-token, invite, OAuth, admin, or back-office flows.\n- **Prompt\u002FAI\u002Freplay payload leakage**: AI conversation text, replay metadata, support transcripts, crash event payloads, or user feedback copied wholesale into logs, snapshots, traces, or test fixtures when they can contain real identifiers.\n- **Weak masking**: `j***@customer.com`, last-four-only masking, partial IP, or customer slug fragments when surrounding context still identifies the person or customer.\n\n## What NOT to Report\n\n- Code that stores, compares, validates, or emails a user's address for the product feature itself, with no lower-trust exposure.\n- Code that computes, stores, or displays revenue\u002Fbilling\u002Fusage data to authorized users as part of the product feature, with no lower-trust exposure.\n- Database columns, model fields, serializer field names, schemas, or type definitions that merely define `email`, `ip_address`, `name`, or `user`.\n- Aggregated, anonymized, public, or synthetic revenue\u002Fusage numbers that cannot identify a customer or production account.\n- Synthetic examples and placeholders listed in the classification section.\n- Reserved IP ranges and private\u002Finternal IPs used as network examples, unless the surrounding text says they are a customer\u002Fuser's address.\n- Author, translator, changelog, license, `Co-authored-by`, and public maintainer metadata.\n- Public business contact aliases or role accounts, unless tied to a customer record.\n- Secrets, API keys, passwords, and tokens as standalone findings. Those belong to a secrets skill. Report here only when the primary issue is personal\u002Fcustomer identity exposure.\n- Broad data-exfiltration primitives with no personal\u002Fcustomer identifier. Use a data-exfiltration review for SSRF, SQLi, path traversal, XXE, and generic over-broad responses unless PII is the exposed data.\n- Mere collection of IPs for rate limiting, audit logs, consent records, or security events when the code keeps the value in the approved store and does not add a new broad log\u002Ftelemetry\u002Fexport sink.\n\n## False-Positive Traps\n\n1. **Fixture files copy public webhook examples.** GitHub\u002FBitbucket fixtures often contain commit `author.email` values. If the value is clearly an author field from a public VCS event or a noreply address, drop it.\n2. **Locale and translation headers contain translator emails.** These are author metadata, not customer data.\n3. **Sentry events intentionally model PII fields.** `user.email` and `user.ip` field names or schema examples are not findings by themselves. Report only unsafe exposure or concrete real values.\n4. **Audit and rate-limit paths may legitimately use IPs.** Check whether the change adds a new sink or simply uses an existing controlled store.\n5. **Example domains can look realistic.** `jane@example.com` is deliberately safe. Conversely, an address at a real customer domain may still identify a customer if the domain or surrounding slug is real.\n6. **Hashing can be acceptable.** A stable salted hash or HMAC of an email\u002FIP for rate limiting or correlation is usually safe. Unsalted hashes of low-entropy emails may be reversible enough to report when exposed externally.\n7. **Public corporate domains are not personal by themselves.** `sentry.io` or `github.com` is not PII. A named-person mailbox at a real customer domain can be.\n8. **Business metrics need customer linkage.** \"Revenue increased 12%\" or a fake dashboard seed is not a finding. \"Customer X ARR is ...\" in a fixture, snapshot, comment, or log is.\n\n## Canonical Patterns\n\n### Pattern: Real customer email in committed test data\n\n**Python - bad:**\n```python\n# Copied from a support case. Do not commit the real customer address.\npayload = {\"email\": customer_email_from_ticket, \"org\": customer_org_slug_from_ticket}\n```\n\n**Python - safe:**\n```python\npayload = {\"email\": \"user@example.com\", \"org\": \"org-slug\"}\n```\n\n**TypeScript - bad:**\n```ts\nconst fixture = {\n  email: customerEmailFromIncident,\n  orgSlug: customerOrgSlugFromIncident,\n};\n```\n\n**TypeScript - safe:**\n```ts\nconst fixture = {\n  email: 'user@example.com',\n  orgSlug: 'org-slug',\n};\n```\n\n### Pattern: PII in logs or telemetry\n\n**Python - bad:**\n```python\nlogger.warning(\"identity lookup failed\", extra={\"email\": user.email, \"ip\": request.META[\"REMOTE_ADDR\"]})\n```\n\n**Python - safe:**\n```python\nlogger.warning(\"identity lookup failed\", extra={\"user_id\": user.id, \"email_hash\": hash_email(user.email)})\n```\n\n**TypeScript - bad:**\n```ts\nlogger.warn('signup failed', {email: req.body.email, ip: req.ip, body: req.body});\n```\n\n**TypeScript - safe:**\n```ts\nlogger.warn('signup failed', {userId: user.id, reason: 'validation_failed'});\n```\n\n### Pattern: Email in URL query string\n\n**Python - bad:**\n```python\nreturn redirect(f\"\u002Flogin\u002Ferror?email={quote(email)}\")\n```\n\n**Python - safe:**\n```python\nrequest.session[\"login_error\"] = \"invalid_magic_code\"\nreturn redirect(\"\u002Flogin\u002Ferror\")\n```\n\n**TypeScript - bad:**\n```ts\nreturn redirect(`\u002Foauth\u002Ferror?email=${encodeURIComponent(email)}`);\n```\n\n**TypeScript - safe:**\n```ts\nreturn redirect('\u002Foauth\u002Ferror?reason=invalid_code');\n```\n\n### Pattern: Customer IP copied into docs or config\n\n**Python - bad:**\n```python\n# Customer allowlist from support ticket. Use an internal note, not git history.\nCUSTOMER_DEBUG_IPS = [customer_public_ip_from_ticket]\n```\n\n**Python - safe:**\n```python\nEXAMPLE_DEBUG_IPS = [\"198.51.100.23\"]\n```\n\n**TypeScript - bad:**\n```ts\n\u002F\u002F Temporary customer bypass.\nconst customerDebugIps = [customerPublicIpFromTicket];\n```\n\n**TypeScript - safe:**\n```ts\nconst exampleDebugIps = ['198.51.100.23'];\n```\n\n### Pattern: Customer revenue or account data in fixtures\n\n**Python - bad:**\n```python\n# Copied from an account review. Use synthetic data instead.\nfixture = {\n    \"org_slug\": customer_org_slug_from_crm,\n    \"arr_usd\": customer_arr_from_crm,\n    \"renewal_date\": customer_renewal_date_from_crm,\n}\n```\n\n**Python - safe:**\n```python\nfixture = {\n    \"org_slug\": \"org-slug\",\n    \"arr_usd\": 120000,\n    \"renewal_date\": \"2026-01-01\",\n}\n```\n\n**TypeScript - bad:**\n```ts\nconst accountSnapshot = {\n  orgSlug: customerOrgSlugFromBilling,\n  monthlySpendUsd: customerMonthlySpendFromBilling,\n  seatCount: customerSeatCountFromBilling,\n};\n```\n\n**TypeScript - safe:**\n```ts\nconst accountSnapshot = {\n  orgSlug: 'org-slug',\n  monthlySpendUsd: 1000,\n  seatCount: 25,\n};\n```\n\n## Output Requirements\n\nFor each finding, include:\n\n- Exact file and line.\n- The identifier or customer-data class and why it appears real, without repeating the full PII value or customer-confidential value when a partial description is enough.\n- The exposure sink and who can see or retain it.\n- Why fake\u002Fexample\u002Fauthor exceptions do not apply.\n- How to fix: replace with synthetic data, hash\u002FHMAC, redact, remove from URL\u002Flog\u002Ftelemetry, narrow serializer fields, or keep the real identifier in internal tooling outside git.\n- Severity (`high` \u002F `medium` \u002F `low`) based on impact and retention.\n\nIf there are no findings, say so. Mention any unresolved ambiguity only if it materially limited the review.\n",{"data":39,"body":41},{"name":4,"description":6,"allowed-tools":40},"Read Grep Glob Bash",{"type":42,"children":43},"root",[44,52,57,64,69,153,158,164,169,194,199,232,237,551,556,562,638,643,649,834,840,931,937,1064,1070,1077,1085,1116,1124,1138,1146,1235,1243,1333,1339,1346,1360,1367,1381,1388,1537,1544,1651,1657,1664,1678,1685,1708,1715,1778,1785,1828,1834,1841,1864,1871,1885,1892,1933,1940,1990,1996,2003,2060,2067,2112,2119,2215,2222,2323,2329,2334,2387,2392],{"type":45,"tag":46,"props":47,"children":48},"element","p",{},[49],{"type":50,"value":51},"text","You are a senior application security engineer. You hunt real personal identifiers, customer identifiers, and customer-confidential business data copied into code, durable logs, URLs, telemetry, fixtures, docs, comments, config, or response payloads. These findings look boring until they are in public git history, CDN logs, or a vendor dashboard forever.",{"type":45,"tag":46,"props":53,"children":54},{},[55],{"type":50,"value":56},"This skill is about privacy and customer-data exposure. It is not a generic information-disclosure review. Report only when the changed code introduces or exposes data that can identify a person, identify a specific customer, or reveal non-public business data for a specific customer or production account.",{"type":45,"tag":58,"props":59,"children":61},"h2",{"id":60},"trace-do-not-skim",[62],{"type":50,"value":63},"Trace. Do Not Skim.",{"type":45,"tag":46,"props":65,"children":66},{},[67],{"type":50,"value":68},"PII review is context review. A string that looks like an email may be a fake fixture. A harmless-looking org slug may identify a real customer. Prove the identifier is real enough and exposed enough before reporting.",{"type":45,"tag":70,"props":71,"children":72},"ul",{},[73,79,84,89,127,132],{"type":45,"tag":74,"props":75,"children":76},"li",{},[77],{"type":50,"value":78},"Read the surrounding file, not just the changed line. File path and test\u002Ffixture role decide many cases.",{"type":45,"tag":74,"props":80,"children":81},{},[82],{"type":50,"value":83},"Identify the data class: real email, person name plus another identifier, phone, address, customer org\u002Faccount slug, customer revenue\u002Fbilling\u002Fcontract data, account usage, support ticket detail, customer-tied internal ID, public routable IP, device ID, cookie ID, session-like identifier, or user\u002Fcustomer payload.",{"type":45,"tag":74,"props":85,"children":86},{},[87],{"type":50,"value":88},"Identify the exposure sink: source control literal, code comment, docs, test fixture, config, log\u002Fexception\u002Fanalytics\u002Fmetrics tag, Sentry tag\u002Fuser context, URL path\u002Fquery string, redirect, cache key, artifact, export, or API response.",{"type":45,"tag":74,"props":90,"children":91},{},[92,94,101,103,109,111,117,119,125],{"type":50,"value":93},"Follow data flow for runtime values. ",{"type":45,"tag":95,"props":96,"children":98},"code",{"className":97},[],[99],{"type":50,"value":100},"user.email",{"type":50,"value":102}," in memory is normal. ",{"type":45,"tag":95,"props":104,"children":106},{"className":105},[],[107],{"type":50,"value":108},"logger.info(..., extra={\"email\": user.email})",{"type":50,"value":110},", ",{"type":45,"tag":95,"props":112,"children":114},{"className":113},[],[115],{"type":50,"value":116},"?email=...",{"type":50,"value":118},", or ",{"type":45,"tag":95,"props":120,"children":122},{"className":121},[],[123],{"type":50,"value":124},"metrics.incr(..., tags={\"email\": email})",{"type":50,"value":126}," is a privacy sink.",{"type":45,"tag":74,"props":128,"children":129},{},[130],{"type":50,"value":131},"Verify fake versus real. Do not report vague resemblance. Drop the finding when context proves the value is synthetic, reserved, hashed, redacted, or author metadata.",{"type":45,"tag":74,"props":133,"children":134},{},[135,137,143,145,151],{"type":50,"value":136},"Use the shell. ",{"type":45,"tag":95,"props":138,"children":140},{"className":139},[],[141],{"type":50,"value":142},"rg",{"type":50,"value":144}," for sibling fixtures, serializers, logging patterns, and allowlisted placeholders. ",{"type":45,"tag":95,"props":146,"children":148},{"className":147},[],[149],{"type":50,"value":150},"git log -p \u003Cfile>",{"type":50,"value":152}," can show whether a real customer identifier was pasted during debugging.",{"type":45,"tag":46,"props":154,"children":155},{},[156],{"type":50,"value":157},"When a thread cannot be resolved with the available files, report only if the identifier is concrete and the sink is durable. Otherwise drop it. Noise trains people to ignore the one real customer email.",{"type":45,"tag":58,"props":159,"children":161},{"id":160},"pii-classification",[162],{"type":50,"value":163},"PII Classification",{"type":45,"tag":46,"props":165,"children":166},{},[167],{"type":50,"value":168},"Report only when both sides are true:",{"type":45,"tag":170,"props":171,"children":172},"ol",{},[173,184],{"type":45,"tag":74,"props":174,"children":175},{},[176,182],{"type":45,"tag":177,"props":178,"children":179},"strong",{},[180],{"type":50,"value":181},"Identifier:",{"type":50,"value":183}," the data can identify a person, a specific customer, or a specific production account.",{"type":45,"tag":74,"props":185,"children":186},{},[187,192],{"type":45,"tag":177,"props":188,"children":189},{},[190],{"type":50,"value":191},"Exposure:",{"type":50,"value":193}," the change puts that data somewhere lower-trust, durable, public, vendor-visible, or unnecessary for the user-facing purpose.",{"type":45,"tag":46,"props":195,"children":196},{},[197],{"type":50,"value":198},"Treat these as high-signal identifiers:",{"type":45,"tag":70,"props":200,"children":201},{},[202,207,212,217,222,227],{"type":45,"tag":74,"props":203,"children":204},{},[205],{"type":50,"value":206},"Real email addresses for individual users or customer domains, especially non-role addresses.",{"type":45,"tag":74,"props":208,"children":209},{},[210],{"type":50,"value":211},"Customer org slugs, account names, subscription IDs, installation IDs, ticket details, or internal IDs when tied to a named customer, email, or account.",{"type":45,"tag":74,"props":213,"children":214},{},[215],{"type":50,"value":216},"Customer-confidential business data tied to a customer or production account: revenue, ARR\u002FMRR, contract value, invoice amounts, spend, quota, usage volume, seat count, plan tier, renewal dates, churn risk, account health, sales notes, billing provider IDs, or support\u002Fescalation details.",{"type":45,"tag":74,"props":218,"children":219},{},[220],{"type":50,"value":221},"Public routable IP addresses when presented as a user\u002Fcustomer IP, or any IP explicitly labeled as belonging to a customer.",{"type":45,"tag":74,"props":223,"children":224},{},[225],{"type":50,"value":226},"Full names plus company, location, phone, address, username, account ID, or incident\u002Fticket details.",{"type":45,"tag":74,"props":228,"children":229},{},[230],{"type":50,"value":231},"Whole request bodies, webhook payloads, profile fields, identity provider payloads, support exports, invoices, receipts, analytics payloads, or replay\u002Fsession data copied into logs or fixtures.",{"type":45,"tag":46,"props":233,"children":234},{},[235],{"type":50,"value":236},"Treat these as usually synthetic or out of scope unless context proves otherwise:",{"type":45,"tag":70,"props":238,"children":239},{},[240,302,377,404,437,442,455,518],{"type":45,"tag":74,"props":241,"children":242},{},[243,245,251,252,258,259,265,266,272,273,279,280,286,287,293,294,300],{"type":50,"value":244},"RFC example domains and addresses: ",{"type":45,"tag":95,"props":246,"children":248},{"className":247},[],[249],{"type":50,"value":250},"example.com",{"type":50,"value":110},{"type":45,"tag":95,"props":253,"children":255},{"className":254},[],[256],{"type":50,"value":257},"example.org",{"type":50,"value":110},{"type":45,"tag":95,"props":260,"children":262},{"className":261},[],[263],{"type":50,"value":264},"example.net",{"type":50,"value":110},{"type":45,"tag":95,"props":267,"children":269},{"className":268},[],[270],{"type":50,"value":271},"example.edu",{"type":50,"value":110},{"type":45,"tag":95,"props":274,"children":276},{"className":275},[],[277],{"type":50,"value":278},".invalid",{"type":50,"value":110},{"type":45,"tag":95,"props":281,"children":283},{"className":282},[],[284],{"type":50,"value":285},"user@example.com",{"type":50,"value":110},{"type":45,"tag":95,"props":288,"children":290},{"className":289},[],[291],{"type":50,"value":292},"jane@example.com",{"type":50,"value":110},{"type":45,"tag":95,"props":295,"children":297},{"className":296},[],[298],{"type":50,"value":299},"alice@example.org",{"type":50,"value":301},".",{"type":45,"tag":74,"props":303,"children":304},{},[305,307,313,314,320,321,327,328,334,335,341,342,348,349,355,356,362,363,369,370,376],{"type":50,"value":306},"Obvious placeholders: ",{"type":45,"tag":95,"props":308,"children":310},{"className":309},[],[311],{"type":50,"value":312},"test@example.com",{"type":50,"value":110},{"type":45,"tag":95,"props":315,"children":317},{"className":316},[],[318],{"type":50,"value":319},"foo@example.com",{"type":50,"value":110},{"type":45,"tag":95,"props":322,"children":324},{"className":323},[],[325],{"type":50,"value":326},"no-reply@example.com",{"type":50,"value":110},{"type":45,"tag":95,"props":329,"children":331},{"className":330},[],[332],{"type":50,"value":333},"org-slug",{"type":50,"value":110},{"type":45,"tag":95,"props":336,"children":338},{"className":337},[],[339],{"type":50,"value":340},"customer-1",{"type":50,"value":110},{"type":45,"tag":95,"props":343,"children":345},{"className":344},[],[346],{"type":50,"value":347},"John Doe",{"type":50,"value":110},{"type":45,"tag":95,"props":350,"children":352},{"className":351},[],[353],{"type":50,"value":354},"Jane Doe",{"type":50,"value":110},{"type":45,"tag":95,"props":357,"children":359},{"className":358},[],[360],{"type":50,"value":361},"Alice",{"type":50,"value":110},{"type":45,"tag":95,"props":364,"children":366},{"className":365},[],[367],{"type":50,"value":368},"Bob",{"type":50,"value":110},{"type":45,"tag":95,"props":371,"children":373},{"className":372},[],[374],{"type":50,"value":375},"Acme Corp",{"type":50,"value":301},{"type":45,"tag":74,"props":378,"children":379},{},[380,382,388,389,395,396,402],{"type":50,"value":381},"Synthetic commercial examples: ",{"type":45,"tag":95,"props":383,"children":385},{"className":384},[],[386],{"type":50,"value":387},"example-org",{"type":50,"value":110},{"type":45,"tag":95,"props":390,"children":392},{"className":391},[],[393],{"type":50,"value":394},"demo-customer",{"type":50,"value":110},{"type":45,"tag":95,"props":397,"children":399},{"className":398},[],[400],{"type":50,"value":401},"ExampleCo",{"type":50,"value":403},", obviously rounded\u002Fsample amounts, generated dashboard screenshots, and fake seed data with no real account context.",{"type":45,"tag":74,"props":405,"children":406},{},[407,409,415,416,422,423,429,430,436],{"type":50,"value":408},"Reserved\u002Fdocumentation IP ranges: ",{"type":45,"tag":95,"props":410,"children":412},{"className":411},[],[413],{"type":50,"value":414},"192.0.2.0\u002F24",{"type":50,"value":110},{"type":45,"tag":95,"props":417,"children":419},{"className":418},[],[420],{"type":50,"value":421},"198.51.100.0\u002F24",{"type":50,"value":110},{"type":45,"tag":95,"props":424,"children":426},{"className":425},[],[427],{"type":50,"value":428},"203.0.113.0\u002F24",{"type":50,"value":110},{"type":45,"tag":95,"props":431,"children":433},{"className":432},[],[434],{"type":50,"value":435},"2001:db8::\u002F32",{"type":50,"value":301},{"type":45,"tag":74,"props":438,"children":439},{},[440],{"type":50,"value":441},"Private, loopback, link-local, multicast, and ULA addresses unless explicitly labeled as customer data.",{"type":45,"tag":74,"props":443,"children":444},{},[445,447,453],{"type":50,"value":446},"Git author, translator, maintainer, ",{"type":45,"tag":95,"props":448,"children":450},{"className":449},[],[451],{"type":50,"value":452},"Co-authored-by",{"type":50,"value":454},", changelog, license, and public package metadata. The user already chose to publish that author identity.",{"type":45,"tag":74,"props":456,"children":457},{},[458,460,466,467,473,474,480,481,487,488,494,495,501,502,508,510,516],{"type":50,"value":459},"Role or public contact aliases such as ",{"type":45,"tag":95,"props":461,"children":463},{"className":462},[],[464],{"type":50,"value":465},"support@",{"type":50,"value":110},{"type":45,"tag":95,"props":468,"children":470},{"className":469},[],[471],{"type":50,"value":472},"security@",{"type":50,"value":110},{"type":45,"tag":95,"props":475,"children":477},{"className":476},[],[478],{"type":50,"value":479},"abuse@",{"type":50,"value":110},{"type":45,"tag":95,"props":482,"children":484},{"className":483},[],[485],{"type":50,"value":486},"privacy@",{"type":50,"value":110},{"type":45,"tag":95,"props":489,"children":491},{"className":490},[],[492],{"type":50,"value":493},"sales@",{"type":50,"value":110},{"type":45,"tag":95,"props":496,"children":498},{"className":497},[],[499],{"type":50,"value":500},"partners@",{"type":50,"value":110},{"type":45,"tag":95,"props":503,"children":505},{"className":504},[],[506],{"type":50,"value":507},"noreply@",{"type":50,"value":509},", and GitHub ",{"type":45,"tag":95,"props":511,"children":513},{"className":512},[],[514],{"type":50,"value":515},"users.noreply.github.com",{"type":50,"value":517},", unless they identify a specific customer account.",{"type":45,"tag":74,"props":519,"children":520},{},[521,523,529,530,536,537,542,543,549],{"type":50,"value":522},"Field names and schemas such as ",{"type":45,"tag":95,"props":524,"children":526},{"className":525},[],[527],{"type":50,"value":528},"email",{"type":50,"value":110},{"type":45,"tag":95,"props":531,"children":533},{"className":532},[],[534],{"type":50,"value":535},"ip_address",{"type":50,"value":110},{"type":45,"tag":95,"props":538,"children":540},{"className":539},[],[541],{"type":50,"value":100},{"type":50,"value":110},{"type":45,"tag":95,"props":544,"children":546},{"className":545},[],[547],{"type":50,"value":548},"sentry.user.ip",{"type":50,"value":550},", or serializer fields with no concrete value or unsafe sink.",{"type":45,"tag":46,"props":552,"children":553},{},[554],{"type":50,"value":555},"Public domains are not automatically real PII. A fixture using a realistic-looking address may still be fake. Inspect the context and report only when the value is attached to a real person, customer, production account, or copied incident\u002Fsupport data.",{"type":45,"tag":58,"props":557,"children":559},{"id":558},"severity",[560],{"type":50,"value":561},"Severity",{"type":45,"tag":563,"props":564,"children":565},"table",{},[566,585],{"type":45,"tag":567,"props":568,"children":569},"thead",{},[570],{"type":45,"tag":571,"props":572,"children":573},"tr",{},[574,580],{"type":45,"tag":575,"props":576,"children":577},"th",{},[578],{"type":50,"value":579},"Level",{"type":45,"tag":575,"props":581,"children":582},{},[583],{"type":50,"value":584},"Criteria",{"type":45,"tag":586,"props":587,"children":588},"tbody",{},[589,606,622],{"type":45,"tag":571,"props":590,"children":591},{},[592,601],{"type":45,"tag":593,"props":594,"children":595},"td",{},[596],{"type":45,"tag":177,"props":597,"children":598},{},[599],{"type":50,"value":600},"high",{"type":45,"tag":593,"props":602,"children":603},{},[604],{"type":50,"value":605},"Real customer or user PII committed as a literal in code\u002Fdocs\u002Ftests\u002Fconfig; customer-specific revenue, contract, billing, invoice, spend, account-health, or support data committed to git; PII placed into URL path\u002Fquery strings; raw request\u002Fprofile\u002Fcustomer payload logged; API response exposes another user's email\u002FIP\u002Fprofile data or another customer's commercial data; customer identifiers in public PR-facing artifacts.",{"type":45,"tag":571,"props":607,"children":608},{},[609,617],{"type":45,"tag":593,"props":610,"children":611},{},[612],{"type":45,"tag":177,"props":613,"children":614},{},[615],{"type":50,"value":616},"medium",{"type":45,"tag":593,"props":618,"children":619},{},[620],{"type":50,"value":621},"Real user email\u002FIP\u002Fcustomer slug or customer-confidential business data sent to durable logs, analytics, metrics tags, Sentry tags, traces, cache keys, or third-party telemetry where it is unnecessary or unredacted; real PII or customer commercial data in private test fixtures or generated artifacts.",{"type":45,"tag":571,"props":623,"children":624},{},[625,633],{"type":45,"tag":593,"props":626,"children":627},{},[628],{"type":45,"tag":177,"props":629,"children":630},{},[631],{"type":50,"value":632},"low",{"type":45,"tag":593,"props":634,"children":635},{},[636],{"type":50,"value":637},"Defense-in-depth privacy issue with limited visibility, such as a staff\u002Finternal address in dev-only docs, a partially masked identifier that is still re-identifiable, internal-only customer commercial data with tight operator access, or PII only visible to tightly restricted operators. Report low only when the thread is clear.",{"type":45,"tag":46,"props":639,"children":640},{},[641],{"type":50,"value":642},"Pick the lower severity when the audience or retention is unclear. Raise severity when data is public, cross-customer, unauthenticated, vendor-visible, or hard to purge.",{"type":45,"tag":58,"props":644,"children":646},{"id":645},"what-to-report",[647],{"type":50,"value":648},"What to Report",{"type":45,"tag":70,"props":650,"children":651},{},[652,662,672,682,692,710,777,787,797,807,817],{"type":45,"tag":74,"props":653,"children":654},{},[655,660],{"type":45,"tag":177,"props":656,"children":657},{},[658],{"type":50,"value":659},"Real PII literals in source control",{"type":50,"value":661},": concrete individual emails, customer names, account slugs, public customer IPs, ticket URLs, addresses, phone numbers, or IDs pasted into code, comments, docs, tests, snapshots, cassettes, fixtures, or config.",{"type":45,"tag":74,"props":663,"children":664},{},[665,670],{"type":45,"tag":177,"props":666,"children":667},{},[668],{"type":50,"value":669},"Real customer business data in source control",{"type":50,"value":671},": revenue, ARR\u002FMRR, invoice amounts, contract value, seat counts, usage totals, quota, plan tier, renewal dates, churn risk, account health, billing provider IDs, or support\u002Fescalation details copied from production or a customer system into code, docs, tests, snapshots, cassettes, fixtures, or config.",{"type":45,"tag":74,"props":673,"children":674},{},[675,680],{"type":45,"tag":177,"props":676,"children":677},{},[678],{"type":50,"value":679},"Customer IPs",{"type":50,"value":681},": public routable IP literals or private IPs explicitly labeled as belonging to a customer\u002Fuser. Do not report reserved documentation ranges.",{"type":45,"tag":74,"props":683,"children":684},{},[685,690],{"type":45,"tag":177,"props":686,"children":687},{},[688],{"type":50,"value":689},"Real email addresses beyond author metadata",{"type":50,"value":691},": customer\u002Fuser\u002Fstaff emails in fixtures, allowlists, examples, comments, test data, logs, metrics, URLs, or responses. Drop translator headers, commit authors, public package maintainers, and GitHub noreply fixture authors unless the email is being used as customer data.",{"type":45,"tag":74,"props":693,"children":694},{},[695,700,702,708],{"type":45,"tag":177,"props":696,"children":697},{},[698],{"type":50,"value":699},"PII in URLs",{"type":50,"value":701},": email, phone, name, IP, user ID tied to an email, account slug, token-like identity, or customer identifier in query strings, redirect URLs, path segments, OAuth ",{"type":45,"tag":95,"props":703,"children":705},{"className":704},[],[706],{"type":50,"value":707},"state",{"type":50,"value":709},", passwordless\u002Fmagic-link error redirects, or referrer-bearing links.",{"type":45,"tag":74,"props":711,"children":712},{},[713,718,720,726,727,733,735,740,741,747,748,754,755,761,762,768,769,775],{"type":45,"tag":177,"props":714,"children":715},{},[716],{"type":50,"value":717},"PII in logs, exceptions, Sentry scope, analytics, or metrics",{"type":50,"value":719},": ",{"type":45,"tag":95,"props":721,"children":723},{"className":722},[],[724],{"type":50,"value":725},"request.body",{"type":50,"value":110},{"type":45,"tag":95,"props":728,"children":730},{"className":729},[],[731],{"type":50,"value":732},"request.data",{"type":50,"value":734},", webhook payloads, identity provider payloads, ",{"type":45,"tag":95,"props":736,"children":738},{"className":737},[],[739],{"type":50,"value":100},{"type":50,"value":110},{"type":45,"tag":95,"props":742,"children":744},{"className":743},[],[745],{"type":50,"value":746},"request.META[\"REMOTE_ADDR\"]",{"type":50,"value":110},{"type":45,"tag":95,"props":749,"children":751},{"className":750},[],[752],{"type":50,"value":753},"req.ip",{"type":50,"value":110},{"type":45,"tag":95,"props":756,"children":758},{"className":757},[],[759],{"type":50,"value":760},"profile",{"type":50,"value":110},{"type":45,"tag":95,"props":763,"children":765},{"className":764},[],[766],{"type":50,"value":767},"customer",{"type":50,"value":110},{"type":45,"tag":95,"props":770,"children":772},{"className":771},[],[773],{"type":50,"value":774},"invoice",{"type":50,"value":776},", or full serializer output added to durable operational sinks without redaction, hashing, or a documented privacy reason.",{"type":45,"tag":74,"props":778,"children":779},{},[780,785],{"type":45,"tag":177,"props":781,"children":782},{},[783],{"type":50,"value":784},"Customer business data in logs, exceptions, analytics, or metrics",{"type":50,"value":786},": named customer revenue, invoices, subscription details, quota, spend, sales notes, account health, or support payloads sent to operational sinks or third-party analytics without a documented privacy reason.",{"type":45,"tag":74,"props":788,"children":789},{},[790,795],{"type":45,"tag":177,"props":791,"children":792},{},[793],{"type":50,"value":794},"PII or customer business data in API responses or exports",{"type":50,"value":796},": serializers, DTOs, GraphQL fields, CSV\u002FJSON exports, or admin endpoints that include email\u002FIP\u002Fprofile fields or customer-specific financial\u002Faccount details for callers who do not need them.",{"type":45,"tag":74,"props":798,"children":799},{},[800,805],{"type":45,"tag":177,"props":801,"children":802},{},[803],{"type":50,"value":804},"Search or enumeration of real emails",{"type":50,"value":806},": flows where an unauthenticated or low-privilege user can discover whether a real email exists, including reset-token, invite, OAuth, admin, or back-office flows.",{"type":45,"tag":74,"props":808,"children":809},{},[810,815],{"type":45,"tag":177,"props":811,"children":812},{},[813],{"type":50,"value":814},"Prompt\u002FAI\u002Freplay payload leakage",{"type":50,"value":816},": AI conversation text, replay metadata, support transcripts, crash event payloads, or user feedback copied wholesale into logs, snapshots, traces, or test fixtures when they can contain real identifiers.",{"type":45,"tag":74,"props":818,"children":819},{},[820,825,826,832],{"type":45,"tag":177,"props":821,"children":822},{},[823],{"type":50,"value":824},"Weak masking",{"type":50,"value":719},{"type":45,"tag":95,"props":827,"children":829},{"className":828},[],[830],{"type":50,"value":831},"j***@customer.com",{"type":50,"value":833},", last-four-only masking, partial IP, or customer slug fragments when surrounding context still identifies the person or customer.",{"type":45,"tag":58,"props":835,"children":837},{"id":836},"what-not-to-report",[838],{"type":50,"value":839},"What NOT to Report",{"type":45,"tag":70,"props":841,"children":842},{},[843,848,853,884,889,894,899,911,916,921,926],{"type":45,"tag":74,"props":844,"children":845},{},[846],{"type":50,"value":847},"Code that stores, compares, validates, or emails a user's address for the product feature itself, with no lower-trust exposure.",{"type":45,"tag":74,"props":849,"children":850},{},[851],{"type":50,"value":852},"Code that computes, stores, or displays revenue\u002Fbilling\u002Fusage data to authorized users as part of the product feature, with no lower-trust exposure.",{"type":45,"tag":74,"props":854,"children":855},{},[856,858,863,864,869,870,876,877,883],{"type":50,"value":857},"Database columns, model fields, serializer field names, schemas, or type definitions that merely define ",{"type":45,"tag":95,"props":859,"children":861},{"className":860},[],[862],{"type":50,"value":528},{"type":50,"value":110},{"type":45,"tag":95,"props":865,"children":867},{"className":866},[],[868],{"type":50,"value":535},{"type":50,"value":110},{"type":45,"tag":95,"props":871,"children":873},{"className":872},[],[874],{"type":50,"value":875},"name",{"type":50,"value":118},{"type":45,"tag":95,"props":878,"children":880},{"className":879},[],[881],{"type":50,"value":882},"user",{"type":50,"value":301},{"type":45,"tag":74,"props":885,"children":886},{},[887],{"type":50,"value":888},"Aggregated, anonymized, public, or synthetic revenue\u002Fusage numbers that cannot identify a customer or production account.",{"type":45,"tag":74,"props":890,"children":891},{},[892],{"type":50,"value":893},"Synthetic examples and placeholders listed in the classification section.",{"type":45,"tag":74,"props":895,"children":896},{},[897],{"type":50,"value":898},"Reserved IP ranges and private\u002Finternal IPs used as network examples, unless the surrounding text says they are a customer\u002Fuser's address.",{"type":45,"tag":74,"props":900,"children":901},{},[902,904,909],{"type":50,"value":903},"Author, translator, changelog, license, ",{"type":45,"tag":95,"props":905,"children":907},{"className":906},[],[908],{"type":50,"value":452},{"type":50,"value":910},", and public maintainer metadata.",{"type":45,"tag":74,"props":912,"children":913},{},[914],{"type":50,"value":915},"Public business contact aliases or role accounts, unless tied to a customer record.",{"type":45,"tag":74,"props":917,"children":918},{},[919],{"type":50,"value":920},"Secrets, API keys, passwords, and tokens as standalone findings. Those belong to a secrets skill. Report here only when the primary issue is personal\u002Fcustomer identity exposure.",{"type":45,"tag":74,"props":922,"children":923},{},[924],{"type":50,"value":925},"Broad data-exfiltration primitives with no personal\u002Fcustomer identifier. Use a data-exfiltration review for SSRF, SQLi, path traversal, XXE, and generic over-broad responses unless PII is the exposed data.",{"type":45,"tag":74,"props":927,"children":928},{},[929],{"type":50,"value":930},"Mere collection of IPs for rate limiting, audit logs, consent records, or security events when the code keeps the value in the approved store and does not add a new broad log\u002Ftelemetry\u002Fexport sink.",{"type":45,"tag":58,"props":932,"children":934},{"id":933},"false-positive-traps",[935],{"type":50,"value":936},"False-Positive Traps",{"type":45,"tag":170,"props":938,"children":939},{},[940,958,968,993,1003,1019,1029,1054],{"type":45,"tag":74,"props":941,"children":942},{},[943,948,950,956],{"type":45,"tag":177,"props":944,"children":945},{},[946],{"type":50,"value":947},"Fixture files copy public webhook examples.",{"type":50,"value":949}," GitHub\u002FBitbucket fixtures often contain commit ",{"type":45,"tag":95,"props":951,"children":953},{"className":952},[],[954],{"type":50,"value":955},"author.email",{"type":50,"value":957}," values. If the value is clearly an author field from a public VCS event or a noreply address, drop it.",{"type":45,"tag":74,"props":959,"children":960},{},[961,966],{"type":45,"tag":177,"props":962,"children":963},{},[964],{"type":50,"value":965},"Locale and translation headers contain translator emails.",{"type":50,"value":967}," These are author metadata, not customer data.",{"type":45,"tag":74,"props":969,"children":970},{},[971,976,978,983,985,991],{"type":45,"tag":177,"props":972,"children":973},{},[974],{"type":50,"value":975},"Sentry events intentionally model PII fields.",{"type":50,"value":977}," ",{"type":45,"tag":95,"props":979,"children":981},{"className":980},[],[982],{"type":50,"value":100},{"type":50,"value":984}," and ",{"type":45,"tag":95,"props":986,"children":988},{"className":987},[],[989],{"type":50,"value":990},"user.ip",{"type":50,"value":992}," field names or schema examples are not findings by themselves. Report only unsafe exposure or concrete real values.",{"type":45,"tag":74,"props":994,"children":995},{},[996,1001],{"type":45,"tag":177,"props":997,"children":998},{},[999],{"type":50,"value":1000},"Audit and rate-limit paths may legitimately use IPs.",{"type":50,"value":1002}," Check whether the change adds a new sink or simply uses an existing controlled store.",{"type":45,"tag":74,"props":1004,"children":1005},{},[1006,1011,1012,1017],{"type":45,"tag":177,"props":1007,"children":1008},{},[1009],{"type":50,"value":1010},"Example domains can look realistic.",{"type":50,"value":977},{"type":45,"tag":95,"props":1013,"children":1015},{"className":1014},[],[1016],{"type":50,"value":292},{"type":50,"value":1018}," is deliberately safe. Conversely, an address at a real customer domain may still identify a customer if the domain or surrounding slug is real.",{"type":45,"tag":74,"props":1020,"children":1021},{},[1022,1027],{"type":45,"tag":177,"props":1023,"children":1024},{},[1025],{"type":50,"value":1026},"Hashing can be acceptable.",{"type":50,"value":1028}," A stable salted hash or HMAC of an email\u002FIP for rate limiting or correlation is usually safe. Unsalted hashes of low-entropy emails may be reversible enough to report when exposed externally.",{"type":45,"tag":74,"props":1030,"children":1031},{},[1032,1037,1038,1044,1046,1052],{"type":45,"tag":177,"props":1033,"children":1034},{},[1035],{"type":50,"value":1036},"Public corporate domains are not personal by themselves.",{"type":50,"value":977},{"type":45,"tag":95,"props":1039,"children":1041},{"className":1040},[],[1042],{"type":50,"value":1043},"sentry.io",{"type":50,"value":1045}," or ",{"type":45,"tag":95,"props":1047,"children":1049},{"className":1048},[],[1050],{"type":50,"value":1051},"github.com",{"type":50,"value":1053}," is not PII. A named-person mailbox at a real customer domain can be.",{"type":45,"tag":74,"props":1055,"children":1056},{},[1057,1062],{"type":45,"tag":177,"props":1058,"children":1059},{},[1060],{"type":50,"value":1061},"Business metrics need customer linkage.",{"type":50,"value":1063}," \"Revenue increased 12%\" or a fake dashboard seed is not a finding. \"Customer X ARR is ...\" in a fixture, snapshot, comment, or log is.",{"type":45,"tag":58,"props":1065,"children":1067},{"id":1066},"canonical-patterns",[1068],{"type":50,"value":1069},"Canonical Patterns",{"type":45,"tag":1071,"props":1072,"children":1074},"h3",{"id":1073},"pattern-real-customer-email-in-committed-test-data",[1075],{"type":50,"value":1076},"Pattern: Real customer email in committed test data",{"type":45,"tag":46,"props":1078,"children":1079},{},[1080],{"type":45,"tag":177,"props":1081,"children":1082},{},[1083],{"type":50,"value":1084},"Python - bad:",{"type":45,"tag":1086,"props":1087,"children":1092},"pre",{"className":1088,"code":1089,"language":1090,"meta":1091,"style":1091},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Copied from a support case. Do not commit the real customer address.\npayload = {\"email\": customer_email_from_ticket, \"org\": customer_org_slug_from_ticket}\n","python","",[1093],{"type":45,"tag":95,"props":1094,"children":1095},{"__ignoreMap":1091},[1096,1107],{"type":45,"tag":1097,"props":1098,"children":1101},"span",{"class":1099,"line":1100},"line",1,[1102],{"type":45,"tag":1097,"props":1103,"children":1104},{},[1105],{"type":50,"value":1106},"# Copied from a support case. Do not commit the real customer address.\n",{"type":45,"tag":1097,"props":1108,"children":1110},{"class":1099,"line":1109},2,[1111],{"type":45,"tag":1097,"props":1112,"children":1113},{},[1114],{"type":50,"value":1115},"payload = {\"email\": customer_email_from_ticket, \"org\": customer_org_slug_from_ticket}\n",{"type":45,"tag":46,"props":1117,"children":1118},{},[1119],{"type":45,"tag":177,"props":1120,"children":1121},{},[1122],{"type":50,"value":1123},"Python - safe:",{"type":45,"tag":1086,"props":1125,"children":1127},{"className":1088,"code":1126,"language":1090,"meta":1091,"style":1091},"payload = {\"email\": \"user@example.com\", \"org\": \"org-slug\"}\n",[1128],{"type":45,"tag":95,"props":1129,"children":1130},{"__ignoreMap":1091},[1131],{"type":45,"tag":1097,"props":1132,"children":1133},{"class":1099,"line":1100},[1134],{"type":45,"tag":1097,"props":1135,"children":1136},{},[1137],{"type":50,"value":1126},{"type":45,"tag":46,"props":1139,"children":1140},{},[1141],{"type":45,"tag":177,"props":1142,"children":1143},{},[1144],{"type":50,"value":1145},"TypeScript - bad:",{"type":45,"tag":1086,"props":1147,"children":1151},{"className":1148,"code":1149,"language":1150,"meta":1091,"style":1091},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const fixture = {\n  email: customerEmailFromIncident,\n  orgSlug: customerOrgSlugFromIncident,\n};\n","ts",[1152],{"type":45,"tag":95,"props":1153,"children":1154},{"__ignoreMap":1091},[1155,1181,1205,1226],{"type":45,"tag":1097,"props":1156,"children":1157},{"class":1099,"line":1100},[1158,1164,1170,1176],{"type":45,"tag":1097,"props":1159,"children":1161},{"style":1160},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[1162],{"type":50,"value":1163},"const",{"type":45,"tag":1097,"props":1165,"children":1167},{"style":1166},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[1168],{"type":50,"value":1169}," fixture ",{"type":45,"tag":1097,"props":1171,"children":1173},{"style":1172},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[1174],{"type":50,"value":1175},"=",{"type":45,"tag":1097,"props":1177,"children":1178},{"style":1172},[1179],{"type":50,"value":1180}," {\n",{"type":45,"tag":1097,"props":1182,"children":1183},{"class":1099,"line":1109},[1184,1190,1195,1200],{"type":45,"tag":1097,"props":1185,"children":1187},{"style":1186},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[1188],{"type":50,"value":1189},"  email",{"type":45,"tag":1097,"props":1191,"children":1192},{"style":1172},[1193],{"type":50,"value":1194},":",{"type":45,"tag":1097,"props":1196,"children":1197},{"style":1166},[1198],{"type":50,"value":1199}," customerEmailFromIncident",{"type":45,"tag":1097,"props":1201,"children":1202},{"style":1172},[1203],{"type":50,"value":1204},",\n",{"type":45,"tag":1097,"props":1206,"children":1207},{"class":1099,"line":31},[1208,1213,1217,1222],{"type":45,"tag":1097,"props":1209,"children":1210},{"style":1186},[1211],{"type":50,"value":1212},"  orgSlug",{"type":45,"tag":1097,"props":1214,"children":1215},{"style":1172},[1216],{"type":50,"value":1194},{"type":45,"tag":1097,"props":1218,"children":1219},{"style":1166},[1220],{"type":50,"value":1221}," customerOrgSlugFromIncident",{"type":45,"tag":1097,"props":1223,"children":1224},{"style":1172},[1225],{"type":50,"value":1204},{"type":45,"tag":1097,"props":1227,"children":1229},{"class":1099,"line":1228},4,[1230],{"type":45,"tag":1097,"props":1231,"children":1232},{"style":1172},[1233],{"type":50,"value":1234},"};\n",{"type":45,"tag":46,"props":1236,"children":1237},{},[1238],{"type":45,"tag":177,"props":1239,"children":1240},{},[1241],{"type":50,"value":1242},"TypeScript - safe:",{"type":45,"tag":1086,"props":1244,"children":1246},{"className":1148,"code":1245,"language":1150,"meta":1091,"style":1091},"const fixture = {\n  email: 'user@example.com',\n  orgSlug: 'org-slug',\n};\n",[1247],{"type":45,"tag":95,"props":1248,"children":1249},{"__ignoreMap":1091},[1250,1269,1299,1326],{"type":45,"tag":1097,"props":1251,"children":1252},{"class":1099,"line":1100},[1253,1257,1261,1265],{"type":45,"tag":1097,"props":1254,"children":1255},{"style":1160},[1256],{"type":50,"value":1163},{"type":45,"tag":1097,"props":1258,"children":1259},{"style":1166},[1260],{"type":50,"value":1169},{"type":45,"tag":1097,"props":1262,"children":1263},{"style":1172},[1264],{"type":50,"value":1175},{"type":45,"tag":1097,"props":1266,"children":1267},{"style":1172},[1268],{"type":50,"value":1180},{"type":45,"tag":1097,"props":1270,"children":1271},{"class":1099,"line":1109},[1272,1276,1280,1285,1290,1295],{"type":45,"tag":1097,"props":1273,"children":1274},{"style":1186},[1275],{"type":50,"value":1189},{"type":45,"tag":1097,"props":1277,"children":1278},{"style":1172},[1279],{"type":50,"value":1194},{"type":45,"tag":1097,"props":1281,"children":1282},{"style":1172},[1283],{"type":50,"value":1284}," '",{"type":45,"tag":1097,"props":1286,"children":1288},{"style":1287},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[1289],{"type":50,"value":285},{"type":45,"tag":1097,"props":1291,"children":1292},{"style":1172},[1293],{"type":50,"value":1294},"'",{"type":45,"tag":1097,"props":1296,"children":1297},{"style":1172},[1298],{"type":50,"value":1204},{"type":45,"tag":1097,"props":1300,"children":1301},{"class":1099,"line":31},[1302,1306,1310,1314,1318,1322],{"type":45,"tag":1097,"props":1303,"children":1304},{"style":1186},[1305],{"type":50,"value":1212},{"type":45,"tag":1097,"props":1307,"children":1308},{"style":1172},[1309],{"type":50,"value":1194},{"type":45,"tag":1097,"props":1311,"children":1312},{"style":1172},[1313],{"type":50,"value":1284},{"type":45,"tag":1097,"props":1315,"children":1316},{"style":1287},[1317],{"type":50,"value":333},{"type":45,"tag":1097,"props":1319,"children":1320},{"style":1172},[1321],{"type":50,"value":1294},{"type":45,"tag":1097,"props":1323,"children":1324},{"style":1172},[1325],{"type":50,"value":1204},{"type":45,"tag":1097,"props":1327,"children":1328},{"class":1099,"line":1228},[1329],{"type":45,"tag":1097,"props":1330,"children":1331},{"style":1172},[1332],{"type":50,"value":1234},{"type":45,"tag":1071,"props":1334,"children":1336},{"id":1335},"pattern-pii-in-logs-or-telemetry",[1337],{"type":50,"value":1338},"Pattern: PII in logs or telemetry",{"type":45,"tag":46,"props":1340,"children":1341},{},[1342],{"type":45,"tag":177,"props":1343,"children":1344},{},[1345],{"type":50,"value":1084},{"type":45,"tag":1086,"props":1347,"children":1349},{"className":1088,"code":1348,"language":1090,"meta":1091,"style":1091},"logger.warning(\"identity lookup failed\", extra={\"email\": user.email, \"ip\": request.META[\"REMOTE_ADDR\"]})\n",[1350],{"type":45,"tag":95,"props":1351,"children":1352},{"__ignoreMap":1091},[1353],{"type":45,"tag":1097,"props":1354,"children":1355},{"class":1099,"line":1100},[1356],{"type":45,"tag":1097,"props":1357,"children":1358},{},[1359],{"type":50,"value":1348},{"type":45,"tag":46,"props":1361,"children":1362},{},[1363],{"type":45,"tag":177,"props":1364,"children":1365},{},[1366],{"type":50,"value":1123},{"type":45,"tag":1086,"props":1368,"children":1370},{"className":1088,"code":1369,"language":1090,"meta":1091,"style":1091},"logger.warning(\"identity lookup failed\", extra={\"user_id\": user.id, \"email_hash\": hash_email(user.email)})\n",[1371],{"type":45,"tag":95,"props":1372,"children":1373},{"__ignoreMap":1091},[1374],{"type":45,"tag":1097,"props":1375,"children":1376},{"class":1099,"line":1100},[1377],{"type":45,"tag":1097,"props":1378,"children":1379},{},[1380],{"type":50,"value":1369},{"type":45,"tag":46,"props":1382,"children":1383},{},[1384],{"type":45,"tag":177,"props":1385,"children":1386},{},[1387],{"type":50,"value":1145},{"type":45,"tag":1086,"props":1389,"children":1391},{"className":1148,"code":1390,"language":1150,"meta":1091,"style":1091},"logger.warn('signup failed', {email: req.body.email, ip: req.ip, body: req.body});\n",[1392],{"type":45,"tag":95,"props":1393,"children":1394},{"__ignoreMap":1091},[1395],{"type":45,"tag":1097,"props":1396,"children":1397},{"class":1099,"line":1100},[1398,1403,1407,1413,1418,1422,1427,1431,1436,1441,1445,1449,1454,1458,1463,1467,1471,1475,1480,1484,1488,1492,1497,1501,1506,1510,1514,1518,1522,1527,1532],{"type":45,"tag":1097,"props":1399,"children":1400},{"style":1166},[1401],{"type":50,"value":1402},"logger",{"type":45,"tag":1097,"props":1404,"children":1405},{"style":1172},[1406],{"type":50,"value":301},{"type":45,"tag":1097,"props":1408,"children":1410},{"style":1409},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[1411],{"type":50,"value":1412},"warn",{"type":45,"tag":1097,"props":1414,"children":1415},{"style":1166},[1416],{"type":50,"value":1417},"(",{"type":45,"tag":1097,"props":1419,"children":1420},{"style":1172},[1421],{"type":50,"value":1294},{"type":45,"tag":1097,"props":1423,"children":1424},{"style":1287},[1425],{"type":50,"value":1426},"signup failed",{"type":45,"tag":1097,"props":1428,"children":1429},{"style":1172},[1430],{"type":50,"value":1294},{"type":45,"tag":1097,"props":1432,"children":1433},{"style":1172},[1434],{"type":50,"value":1435},",",{"type":45,"tag":1097,"props":1437,"children":1438},{"style":1172},[1439],{"type":50,"value":1440}," {",{"type":45,"tag":1097,"props":1442,"children":1443},{"style":1186},[1444],{"type":50,"value":528},{"type":45,"tag":1097,"props":1446,"children":1447},{"style":1172},[1448],{"type":50,"value":1194},{"type":45,"tag":1097,"props":1450,"children":1451},{"style":1166},[1452],{"type":50,"value":1453}," req",{"type":45,"tag":1097,"props":1455,"children":1456},{"style":1172},[1457],{"type":50,"value":301},{"type":45,"tag":1097,"props":1459,"children":1460},{"style":1166},[1461],{"type":50,"value":1462},"body",{"type":45,"tag":1097,"props":1464,"children":1465},{"style":1172},[1466],{"type":50,"value":301},{"type":45,"tag":1097,"props":1468,"children":1469},{"style":1166},[1470],{"type":50,"value":528},{"type":45,"tag":1097,"props":1472,"children":1473},{"style":1172},[1474],{"type":50,"value":1435},{"type":45,"tag":1097,"props":1476,"children":1477},{"style":1186},[1478],{"type":50,"value":1479}," ip",{"type":45,"tag":1097,"props":1481,"children":1482},{"style":1172},[1483],{"type":50,"value":1194},{"type":45,"tag":1097,"props":1485,"children":1486},{"style":1166},[1487],{"type":50,"value":1453},{"type":45,"tag":1097,"props":1489,"children":1490},{"style":1172},[1491],{"type":50,"value":301},{"type":45,"tag":1097,"props":1493,"children":1494},{"style":1166},[1495],{"type":50,"value":1496},"ip",{"type":45,"tag":1097,"props":1498,"children":1499},{"style":1172},[1500],{"type":50,"value":1435},{"type":45,"tag":1097,"props":1502,"children":1503},{"style":1186},[1504],{"type":50,"value":1505}," body",{"type":45,"tag":1097,"props":1507,"children":1508},{"style":1172},[1509],{"type":50,"value":1194},{"type":45,"tag":1097,"props":1511,"children":1512},{"style":1166},[1513],{"type":50,"value":1453},{"type":45,"tag":1097,"props":1515,"children":1516},{"style":1172},[1517],{"type":50,"value":301},{"type":45,"tag":1097,"props":1519,"children":1520},{"style":1166},[1521],{"type":50,"value":1462},{"type":45,"tag":1097,"props":1523,"children":1524},{"style":1172},[1525],{"type":50,"value":1526},"}",{"type":45,"tag":1097,"props":1528,"children":1529},{"style":1166},[1530],{"type":50,"value":1531},")",{"type":45,"tag":1097,"props":1533,"children":1534},{"style":1172},[1535],{"type":50,"value":1536},";\n",{"type":45,"tag":46,"props":1538,"children":1539},{},[1540],{"type":45,"tag":177,"props":1541,"children":1542},{},[1543],{"type":50,"value":1242},{"type":45,"tag":1086,"props":1545,"children":1547},{"className":1148,"code":1546,"language":1150,"meta":1091,"style":1091},"logger.warn('signup failed', {userId: user.id, reason: 'validation_failed'});\n",[1548],{"type":45,"tag":95,"props":1549,"children":1550},{"__ignoreMap":1091},[1551],{"type":45,"tag":1097,"props":1552,"children":1553},{"class":1099,"line":1100},[1554,1558,1562,1566,1570,1574,1578,1582,1586,1590,1595,1599,1604,1608,1613,1617,1622,1626,1630,1635,1639,1643,1647],{"type":45,"tag":1097,"props":1555,"children":1556},{"style":1166},[1557],{"type":50,"value":1402},{"type":45,"tag":1097,"props":1559,"children":1560},{"style":1172},[1561],{"type":50,"value":301},{"type":45,"tag":1097,"props":1563,"children":1564},{"style":1409},[1565],{"type":50,"value":1412},{"type":45,"tag":1097,"props":1567,"children":1568},{"style":1166},[1569],{"type":50,"value":1417},{"type":45,"tag":1097,"props":1571,"children":1572},{"style":1172},[1573],{"type":50,"value":1294},{"type":45,"tag":1097,"props":1575,"children":1576},{"style":1287},[1577],{"type":50,"value":1426},{"type":45,"tag":1097,"props":1579,"children":1580},{"style":1172},[1581],{"type":50,"value":1294},{"type":45,"tag":1097,"props":1583,"children":1584},{"style":1172},[1585],{"type":50,"value":1435},{"type":45,"tag":1097,"props":1587,"children":1588},{"style":1172},[1589],{"type":50,"value":1440},{"type":45,"tag":1097,"props":1591,"children":1592},{"style":1186},[1593],{"type":50,"value":1594},"userId",{"type":45,"tag":1097,"props":1596,"children":1597},{"style":1172},[1598],{"type":50,"value":1194},{"type":45,"tag":1097,"props":1600,"children":1601},{"style":1166},[1602],{"type":50,"value":1603}," user",{"type":45,"tag":1097,"props":1605,"children":1606},{"style":1172},[1607],{"type":50,"value":301},{"type":45,"tag":1097,"props":1609,"children":1610},{"style":1166},[1611],{"type":50,"value":1612},"id",{"type":45,"tag":1097,"props":1614,"children":1615},{"style":1172},[1616],{"type":50,"value":1435},{"type":45,"tag":1097,"props":1618,"children":1619},{"style":1186},[1620],{"type":50,"value":1621}," reason",{"type":45,"tag":1097,"props":1623,"children":1624},{"style":1172},[1625],{"type":50,"value":1194},{"type":45,"tag":1097,"props":1627,"children":1628},{"style":1172},[1629],{"type":50,"value":1284},{"type":45,"tag":1097,"props":1631,"children":1632},{"style":1287},[1633],{"type":50,"value":1634},"validation_failed",{"type":45,"tag":1097,"props":1636,"children":1637},{"style":1172},[1638],{"type":50,"value":1294},{"type":45,"tag":1097,"props":1640,"children":1641},{"style":1172},[1642],{"type":50,"value":1526},{"type":45,"tag":1097,"props":1644,"children":1645},{"style":1166},[1646],{"type":50,"value":1531},{"type":45,"tag":1097,"props":1648,"children":1649},{"style":1172},[1650],{"type":50,"value":1536},{"type":45,"tag":1071,"props":1652,"children":1654},{"id":1653},"pattern-email-in-url-query-string",[1655],{"type":50,"value":1656},"Pattern: Email in URL query string",{"type":45,"tag":46,"props":1658,"children":1659},{},[1660],{"type":45,"tag":177,"props":1661,"children":1662},{},[1663],{"type":50,"value":1084},{"type":45,"tag":1086,"props":1665,"children":1667},{"className":1088,"code":1666,"language":1090,"meta":1091,"style":1091},"return redirect(f\"\u002Flogin\u002Ferror?email={quote(email)}\")\n",[1668],{"type":45,"tag":95,"props":1669,"children":1670},{"__ignoreMap":1091},[1671],{"type":45,"tag":1097,"props":1672,"children":1673},{"class":1099,"line":1100},[1674],{"type":45,"tag":1097,"props":1675,"children":1676},{},[1677],{"type":50,"value":1666},{"type":45,"tag":46,"props":1679,"children":1680},{},[1681],{"type":45,"tag":177,"props":1682,"children":1683},{},[1684],{"type":50,"value":1123},{"type":45,"tag":1086,"props":1686,"children":1688},{"className":1088,"code":1687,"language":1090,"meta":1091,"style":1091},"request.session[\"login_error\"] = \"invalid_magic_code\"\nreturn redirect(\"\u002Flogin\u002Ferror\")\n",[1689],{"type":45,"tag":95,"props":1690,"children":1691},{"__ignoreMap":1091},[1692,1700],{"type":45,"tag":1097,"props":1693,"children":1694},{"class":1099,"line":1100},[1695],{"type":45,"tag":1097,"props":1696,"children":1697},{},[1698],{"type":50,"value":1699},"request.session[\"login_error\"] = \"invalid_magic_code\"\n",{"type":45,"tag":1097,"props":1701,"children":1702},{"class":1099,"line":1109},[1703],{"type":45,"tag":1097,"props":1704,"children":1705},{},[1706],{"type":50,"value":1707},"return redirect(\"\u002Flogin\u002Ferror\")\n",{"type":45,"tag":46,"props":1709,"children":1710},{},[1711],{"type":45,"tag":177,"props":1712,"children":1713},{},[1714],{"type":50,"value":1145},{"type":45,"tag":1086,"props":1716,"children":1718},{"className":1148,"code":1717,"language":1150,"meta":1091,"style":1091},"return redirect(`\u002Foauth\u002Ferror?email=${encodeURIComponent(email)}`);\n",[1719],{"type":45,"tag":95,"props":1720,"children":1721},{"__ignoreMap":1091},[1722],{"type":45,"tag":1097,"props":1723,"children":1724},{"class":1099,"line":1100},[1725,1731,1736,1740,1745,1750,1755,1760,1765,1770,1774],{"type":45,"tag":1097,"props":1726,"children":1728},{"style":1727},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[1729],{"type":50,"value":1730},"return",{"type":45,"tag":1097,"props":1732,"children":1733},{"style":1409},[1734],{"type":50,"value":1735}," redirect",{"type":45,"tag":1097,"props":1737,"children":1738},{"style":1166},[1739],{"type":50,"value":1417},{"type":45,"tag":1097,"props":1741,"children":1742},{"style":1172},[1743],{"type":50,"value":1744},"`",{"type":45,"tag":1097,"props":1746,"children":1747},{"style":1287},[1748],{"type":50,"value":1749},"\u002Foauth\u002Ferror?email=",{"type":45,"tag":1097,"props":1751,"children":1752},{"style":1172},[1753],{"type":50,"value":1754},"${",{"type":45,"tag":1097,"props":1756,"children":1757},{"style":1409},[1758],{"type":50,"value":1759},"encodeURIComponent",{"type":45,"tag":1097,"props":1761,"children":1762},{"style":1166},[1763],{"type":50,"value":1764},"(email)",{"type":45,"tag":1097,"props":1766,"children":1767},{"style":1172},[1768],{"type":50,"value":1769},"}`",{"type":45,"tag":1097,"props":1771,"children":1772},{"style":1166},[1773],{"type":50,"value":1531},{"type":45,"tag":1097,"props":1775,"children":1776},{"style":1172},[1777],{"type":50,"value":1536},{"type":45,"tag":46,"props":1779,"children":1780},{},[1781],{"type":45,"tag":177,"props":1782,"children":1783},{},[1784],{"type":50,"value":1242},{"type":45,"tag":1086,"props":1786,"children":1788},{"className":1148,"code":1787,"language":1150,"meta":1091,"style":1091},"return redirect('\u002Foauth\u002Ferror?reason=invalid_code');\n",[1789],{"type":45,"tag":95,"props":1790,"children":1791},{"__ignoreMap":1091},[1792],{"type":45,"tag":1097,"props":1793,"children":1794},{"class":1099,"line":1100},[1795,1799,1803,1807,1811,1816,1820,1824],{"type":45,"tag":1097,"props":1796,"children":1797},{"style":1727},[1798],{"type":50,"value":1730},{"type":45,"tag":1097,"props":1800,"children":1801},{"style":1409},[1802],{"type":50,"value":1735},{"type":45,"tag":1097,"props":1804,"children":1805},{"style":1166},[1806],{"type":50,"value":1417},{"type":45,"tag":1097,"props":1808,"children":1809},{"style":1172},[1810],{"type":50,"value":1294},{"type":45,"tag":1097,"props":1812,"children":1813},{"style":1287},[1814],{"type":50,"value":1815},"\u002Foauth\u002Ferror?reason=invalid_code",{"type":45,"tag":1097,"props":1817,"children":1818},{"style":1172},[1819],{"type":50,"value":1294},{"type":45,"tag":1097,"props":1821,"children":1822},{"style":1166},[1823],{"type":50,"value":1531},{"type":45,"tag":1097,"props":1825,"children":1826},{"style":1172},[1827],{"type":50,"value":1536},{"type":45,"tag":1071,"props":1829,"children":1831},{"id":1830},"pattern-customer-ip-copied-into-docs-or-config",[1832],{"type":50,"value":1833},"Pattern: Customer IP copied into docs or config",{"type":45,"tag":46,"props":1835,"children":1836},{},[1837],{"type":45,"tag":177,"props":1838,"children":1839},{},[1840],{"type":50,"value":1084},{"type":45,"tag":1086,"props":1842,"children":1844},{"className":1088,"code":1843,"language":1090,"meta":1091,"style":1091},"# Customer allowlist from support ticket. Use an internal note, not git history.\nCUSTOMER_DEBUG_IPS = [customer_public_ip_from_ticket]\n",[1845],{"type":45,"tag":95,"props":1846,"children":1847},{"__ignoreMap":1091},[1848,1856],{"type":45,"tag":1097,"props":1849,"children":1850},{"class":1099,"line":1100},[1851],{"type":45,"tag":1097,"props":1852,"children":1853},{},[1854],{"type":50,"value":1855},"# Customer allowlist from support ticket. Use an internal note, not git history.\n",{"type":45,"tag":1097,"props":1857,"children":1858},{"class":1099,"line":1109},[1859],{"type":45,"tag":1097,"props":1860,"children":1861},{},[1862],{"type":50,"value":1863},"CUSTOMER_DEBUG_IPS = [customer_public_ip_from_ticket]\n",{"type":45,"tag":46,"props":1865,"children":1866},{},[1867],{"type":45,"tag":177,"props":1868,"children":1869},{},[1870],{"type":50,"value":1123},{"type":45,"tag":1086,"props":1872,"children":1874},{"className":1088,"code":1873,"language":1090,"meta":1091,"style":1091},"EXAMPLE_DEBUG_IPS = [\"198.51.100.23\"]\n",[1875],{"type":45,"tag":95,"props":1876,"children":1877},{"__ignoreMap":1091},[1878],{"type":45,"tag":1097,"props":1879,"children":1880},{"class":1099,"line":1100},[1881],{"type":45,"tag":1097,"props":1882,"children":1883},{},[1884],{"type":50,"value":1873},{"type":45,"tag":46,"props":1886,"children":1887},{},[1888],{"type":45,"tag":177,"props":1889,"children":1890},{},[1891],{"type":50,"value":1145},{"type":45,"tag":1086,"props":1893,"children":1895},{"className":1148,"code":1894,"language":1150,"meta":1091,"style":1091},"\u002F\u002F Temporary customer bypass.\nconst customerDebugIps = [customerPublicIpFromTicket];\n",[1896],{"type":45,"tag":95,"props":1897,"children":1898},{"__ignoreMap":1091},[1899,1908],{"type":45,"tag":1097,"props":1900,"children":1901},{"class":1099,"line":1100},[1902],{"type":45,"tag":1097,"props":1903,"children":1905},{"style":1904},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[1906],{"type":50,"value":1907},"\u002F\u002F Temporary customer bypass.\n",{"type":45,"tag":1097,"props":1909,"children":1910},{"class":1099,"line":1109},[1911,1915,1920,1924,1929],{"type":45,"tag":1097,"props":1912,"children":1913},{"style":1160},[1914],{"type":50,"value":1163},{"type":45,"tag":1097,"props":1916,"children":1917},{"style":1166},[1918],{"type":50,"value":1919}," customerDebugIps ",{"type":45,"tag":1097,"props":1921,"children":1922},{"style":1172},[1923],{"type":50,"value":1175},{"type":45,"tag":1097,"props":1925,"children":1926},{"style":1166},[1927],{"type":50,"value":1928}," [customerPublicIpFromTicket]",{"type":45,"tag":1097,"props":1930,"children":1931},{"style":1172},[1932],{"type":50,"value":1536},{"type":45,"tag":46,"props":1934,"children":1935},{},[1936],{"type":45,"tag":177,"props":1937,"children":1938},{},[1939],{"type":50,"value":1242},{"type":45,"tag":1086,"props":1941,"children":1943},{"className":1148,"code":1942,"language":1150,"meta":1091,"style":1091},"const exampleDebugIps = ['198.51.100.23'];\n",[1944],{"type":45,"tag":95,"props":1945,"children":1946},{"__ignoreMap":1091},[1947],{"type":45,"tag":1097,"props":1948,"children":1949},{"class":1099,"line":1100},[1950,1954,1959,1963,1968,1972,1977,1981,1986],{"type":45,"tag":1097,"props":1951,"children":1952},{"style":1160},[1953],{"type":50,"value":1163},{"type":45,"tag":1097,"props":1955,"children":1956},{"style":1166},[1957],{"type":50,"value":1958}," exampleDebugIps ",{"type":45,"tag":1097,"props":1960,"children":1961},{"style":1172},[1962],{"type":50,"value":1175},{"type":45,"tag":1097,"props":1964,"children":1965},{"style":1166},[1966],{"type":50,"value":1967}," [",{"type":45,"tag":1097,"props":1969,"children":1970},{"style":1172},[1971],{"type":50,"value":1294},{"type":45,"tag":1097,"props":1973,"children":1974},{"style":1287},[1975],{"type":50,"value":1976},"198.51.100.23",{"type":45,"tag":1097,"props":1978,"children":1979},{"style":1172},[1980],{"type":50,"value":1294},{"type":45,"tag":1097,"props":1982,"children":1983},{"style":1166},[1984],{"type":50,"value":1985},"]",{"type":45,"tag":1097,"props":1987,"children":1988},{"style":1172},[1989],{"type":50,"value":1536},{"type":45,"tag":1071,"props":1991,"children":1993},{"id":1992},"pattern-customer-revenue-or-account-data-in-fixtures",[1994],{"type":50,"value":1995},"Pattern: Customer revenue or account data in fixtures",{"type":45,"tag":46,"props":1997,"children":1998},{},[1999],{"type":45,"tag":177,"props":2000,"children":2001},{},[2002],{"type":50,"value":1084},{"type":45,"tag":1086,"props":2004,"children":2006},{"className":1088,"code":2005,"language":1090,"meta":1091,"style":1091},"# Copied from an account review. Use synthetic data instead.\nfixture = {\n    \"org_slug\": customer_org_slug_from_crm,\n    \"arr_usd\": customer_arr_from_crm,\n    \"renewal_date\": customer_renewal_date_from_crm,\n}\n",[2007],{"type":45,"tag":95,"props":2008,"children":2009},{"__ignoreMap":1091},[2010,2018,2026,2034,2042,2051],{"type":45,"tag":1097,"props":2011,"children":2012},{"class":1099,"line":1100},[2013],{"type":45,"tag":1097,"props":2014,"children":2015},{},[2016],{"type":50,"value":2017},"# Copied from an account review. Use synthetic data instead.\n",{"type":45,"tag":1097,"props":2019,"children":2020},{"class":1099,"line":1109},[2021],{"type":45,"tag":1097,"props":2022,"children":2023},{},[2024],{"type":50,"value":2025},"fixture = {\n",{"type":45,"tag":1097,"props":2027,"children":2028},{"class":1099,"line":31},[2029],{"type":45,"tag":1097,"props":2030,"children":2031},{},[2032],{"type":50,"value":2033},"    \"org_slug\": customer_org_slug_from_crm,\n",{"type":45,"tag":1097,"props":2035,"children":2036},{"class":1099,"line":1228},[2037],{"type":45,"tag":1097,"props":2038,"children":2039},{},[2040],{"type":50,"value":2041},"    \"arr_usd\": customer_arr_from_crm,\n",{"type":45,"tag":1097,"props":2043,"children":2045},{"class":1099,"line":2044},5,[2046],{"type":45,"tag":1097,"props":2047,"children":2048},{},[2049],{"type":50,"value":2050},"    \"renewal_date\": customer_renewal_date_from_crm,\n",{"type":45,"tag":1097,"props":2052,"children":2054},{"class":1099,"line":2053},6,[2055],{"type":45,"tag":1097,"props":2056,"children":2057},{},[2058],{"type":50,"value":2059},"}\n",{"type":45,"tag":46,"props":2061,"children":2062},{},[2063],{"type":45,"tag":177,"props":2064,"children":2065},{},[2066],{"type":50,"value":1123},{"type":45,"tag":1086,"props":2068,"children":2070},{"className":1088,"code":2069,"language":1090,"meta":1091,"style":1091},"fixture = {\n    \"org_slug\": \"org-slug\",\n    \"arr_usd\": 120000,\n    \"renewal_date\": \"2026-01-01\",\n}\n",[2071],{"type":45,"tag":95,"props":2072,"children":2073},{"__ignoreMap":1091},[2074,2081,2089,2097,2105],{"type":45,"tag":1097,"props":2075,"children":2076},{"class":1099,"line":1100},[2077],{"type":45,"tag":1097,"props":2078,"children":2079},{},[2080],{"type":50,"value":2025},{"type":45,"tag":1097,"props":2082,"children":2083},{"class":1099,"line":1109},[2084],{"type":45,"tag":1097,"props":2085,"children":2086},{},[2087],{"type":50,"value":2088},"    \"org_slug\": \"org-slug\",\n",{"type":45,"tag":1097,"props":2090,"children":2091},{"class":1099,"line":31},[2092],{"type":45,"tag":1097,"props":2093,"children":2094},{},[2095],{"type":50,"value":2096},"    \"arr_usd\": 120000,\n",{"type":45,"tag":1097,"props":2098,"children":2099},{"class":1099,"line":1228},[2100],{"type":45,"tag":1097,"props":2101,"children":2102},{},[2103],{"type":50,"value":2104},"    \"renewal_date\": \"2026-01-01\",\n",{"type":45,"tag":1097,"props":2106,"children":2107},{"class":1099,"line":2044},[2108],{"type":45,"tag":1097,"props":2109,"children":2110},{},[2111],{"type":50,"value":2059},{"type":45,"tag":46,"props":2113,"children":2114},{},[2115],{"type":45,"tag":177,"props":2116,"children":2117},{},[2118],{"type":50,"value":1145},{"type":45,"tag":1086,"props":2120,"children":2122},{"className":1148,"code":2121,"language":1150,"meta":1091,"style":1091},"const accountSnapshot = {\n  orgSlug: customerOrgSlugFromBilling,\n  monthlySpendUsd: customerMonthlySpendFromBilling,\n  seatCount: customerSeatCountFromBilling,\n};\n",[2123],{"type":45,"tag":95,"props":2124,"children":2125},{"__ignoreMap":1091},[2126,2146,2166,2187,2208],{"type":45,"tag":1097,"props":2127,"children":2128},{"class":1099,"line":1100},[2129,2133,2138,2142],{"type":45,"tag":1097,"props":2130,"children":2131},{"style":1160},[2132],{"type":50,"value":1163},{"type":45,"tag":1097,"props":2134,"children":2135},{"style":1166},[2136],{"type":50,"value":2137}," accountSnapshot ",{"type":45,"tag":1097,"props":2139,"children":2140},{"style":1172},[2141],{"type":50,"value":1175},{"type":45,"tag":1097,"props":2143,"children":2144},{"style":1172},[2145],{"type":50,"value":1180},{"type":45,"tag":1097,"props":2147,"children":2148},{"class":1099,"line":1109},[2149,2153,2157,2162],{"type":45,"tag":1097,"props":2150,"children":2151},{"style":1186},[2152],{"type":50,"value":1212},{"type":45,"tag":1097,"props":2154,"children":2155},{"style":1172},[2156],{"type":50,"value":1194},{"type":45,"tag":1097,"props":2158,"children":2159},{"style":1166},[2160],{"type":50,"value":2161}," customerOrgSlugFromBilling",{"type":45,"tag":1097,"props":2163,"children":2164},{"style":1172},[2165],{"type":50,"value":1204},{"type":45,"tag":1097,"props":2167,"children":2168},{"class":1099,"line":31},[2169,2174,2178,2183],{"type":45,"tag":1097,"props":2170,"children":2171},{"style":1186},[2172],{"type":50,"value":2173},"  monthlySpendUsd",{"type":45,"tag":1097,"props":2175,"children":2176},{"style":1172},[2177],{"type":50,"value":1194},{"type":45,"tag":1097,"props":2179,"children":2180},{"style":1166},[2181],{"type":50,"value":2182}," customerMonthlySpendFromBilling",{"type":45,"tag":1097,"props":2184,"children":2185},{"style":1172},[2186],{"type":50,"value":1204},{"type":45,"tag":1097,"props":2188,"children":2189},{"class":1099,"line":1228},[2190,2195,2199,2204],{"type":45,"tag":1097,"props":2191,"children":2192},{"style":1186},[2193],{"type":50,"value":2194},"  seatCount",{"type":45,"tag":1097,"props":2196,"children":2197},{"style":1172},[2198],{"type":50,"value":1194},{"type":45,"tag":1097,"props":2200,"children":2201},{"style":1166},[2202],{"type":50,"value":2203}," customerSeatCountFromBilling",{"type":45,"tag":1097,"props":2205,"children":2206},{"style":1172},[2207],{"type":50,"value":1204},{"type":45,"tag":1097,"props":2209,"children":2210},{"class":1099,"line":2044},[2211],{"type":45,"tag":1097,"props":2212,"children":2213},{"style":1172},[2214],{"type":50,"value":1234},{"type":45,"tag":46,"props":2216,"children":2217},{},[2218],{"type":45,"tag":177,"props":2219,"children":2220},{},[2221],{"type":50,"value":1242},{"type":45,"tag":1086,"props":2223,"children":2225},{"className":1148,"code":2224,"language":1150,"meta":1091,"style":1091},"const accountSnapshot = {\n  orgSlug: 'org-slug',\n  monthlySpendUsd: 1000,\n  seatCount: 25,\n};\n",[2226],{"type":45,"tag":95,"props":2227,"children":2228},{"__ignoreMap":1091},[2229,2248,2275,2296,2316],{"type":45,"tag":1097,"props":2230,"children":2231},{"class":1099,"line":1100},[2232,2236,2240,2244],{"type":45,"tag":1097,"props":2233,"children":2234},{"style":1160},[2235],{"type":50,"value":1163},{"type":45,"tag":1097,"props":2237,"children":2238},{"style":1166},[2239],{"type":50,"value":2137},{"type":45,"tag":1097,"props":2241,"children":2242},{"style":1172},[2243],{"type":50,"value":1175},{"type":45,"tag":1097,"props":2245,"children":2246},{"style":1172},[2247],{"type":50,"value":1180},{"type":45,"tag":1097,"props":2249,"children":2250},{"class":1099,"line":1109},[2251,2255,2259,2263,2267,2271],{"type":45,"tag":1097,"props":2252,"children":2253},{"style":1186},[2254],{"type":50,"value":1212},{"type":45,"tag":1097,"props":2256,"children":2257},{"style":1172},[2258],{"type":50,"value":1194},{"type":45,"tag":1097,"props":2260,"children":2261},{"style":1172},[2262],{"type":50,"value":1284},{"type":45,"tag":1097,"props":2264,"children":2265},{"style":1287},[2266],{"type":50,"value":333},{"type":45,"tag":1097,"props":2268,"children":2269},{"style":1172},[2270],{"type":50,"value":1294},{"type":45,"tag":1097,"props":2272,"children":2273},{"style":1172},[2274],{"type":50,"value":1204},{"type":45,"tag":1097,"props":2276,"children":2277},{"class":1099,"line":31},[2278,2282,2286,2292],{"type":45,"tag":1097,"props":2279,"children":2280},{"style":1186},[2281],{"type":50,"value":2173},{"type":45,"tag":1097,"props":2283,"children":2284},{"style":1172},[2285],{"type":50,"value":1194},{"type":45,"tag":1097,"props":2287,"children":2289},{"style":2288},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[2290],{"type":50,"value":2291}," 1000",{"type":45,"tag":1097,"props":2293,"children":2294},{"style":1172},[2295],{"type":50,"value":1204},{"type":45,"tag":1097,"props":2297,"children":2298},{"class":1099,"line":1228},[2299,2303,2307,2312],{"type":45,"tag":1097,"props":2300,"children":2301},{"style":1186},[2302],{"type":50,"value":2194},{"type":45,"tag":1097,"props":2304,"children":2305},{"style":1172},[2306],{"type":50,"value":1194},{"type":45,"tag":1097,"props":2308,"children":2309},{"style":2288},[2310],{"type":50,"value":2311}," 25",{"type":45,"tag":1097,"props":2313,"children":2314},{"style":1172},[2315],{"type":50,"value":1204},{"type":45,"tag":1097,"props":2317,"children":2318},{"class":1099,"line":2044},[2319],{"type":45,"tag":1097,"props":2320,"children":2321},{"style":1172},[2322],{"type":50,"value":1234},{"type":45,"tag":58,"props":2324,"children":2326},{"id":2325},"output-requirements",[2327],{"type":50,"value":2328},"Output Requirements",{"type":45,"tag":46,"props":2330,"children":2331},{},[2332],{"type":50,"value":2333},"For each finding, include:",{"type":45,"tag":70,"props":2335,"children":2336},{},[2337,2342,2347,2352,2357,2362],{"type":45,"tag":74,"props":2338,"children":2339},{},[2340],{"type":50,"value":2341},"Exact file and line.",{"type":45,"tag":74,"props":2343,"children":2344},{},[2345],{"type":50,"value":2346},"The identifier or customer-data class and why it appears real, without repeating the full PII value or customer-confidential value when a partial description is enough.",{"type":45,"tag":74,"props":2348,"children":2349},{},[2350],{"type":50,"value":2351},"The exposure sink and who can see or retain it.",{"type":45,"tag":74,"props":2353,"children":2354},{},[2355],{"type":50,"value":2356},"Why fake\u002Fexample\u002Fauthor exceptions do not apply.",{"type":45,"tag":74,"props":2358,"children":2359},{},[2360],{"type":50,"value":2361},"How to fix: replace with synthetic data, hash\u002FHMAC, redact, remove from URL\u002Flog\u002Ftelemetry, narrow serializer fields, or keep the real identifier in internal tooling outside git.",{"type":45,"tag":74,"props":2363,"children":2364},{},[2365,2367,2372,2374,2379,2380,2385],{"type":50,"value":2366},"Severity (",{"type":45,"tag":95,"props":2368,"children":2370},{"className":2369},[],[2371],{"type":50,"value":600},{"type":50,"value":2373}," \u002F ",{"type":45,"tag":95,"props":2375,"children":2377},{"className":2376},[],[2378],{"type":50,"value":616},{"type":50,"value":2373},{"type":45,"tag":95,"props":2381,"children":2383},{"className":2382},[],[2384],{"type":50,"value":632},{"type":50,"value":2386},") based on impact and retention.",{"type":45,"tag":46,"props":2388,"children":2389},{},[2390],{"type":50,"value":2391},"If there are no findings, say so. Mention any unresolved ambiguity only if it materially limited the review.",{"type":45,"tag":2393,"props":2394,"children":2395},"style",{},[2396],{"type":50,"value":2397},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2399,"total":2493},[2400,2415,2431,2447,2458,2469,2485],{"slug":2401,"name":2401,"fn":2402,"description":2403,"org":2404,"tags":2405,"stars":27,"repoUrl":28,"updatedAt":2414},"vercel-deepsec","scan web applications for security vulnerabilities","Detects broad web application security vulnerabilities using the Vercel DeepSec benchmark prompt. Use when benchmarking security review coverage or running an open-ended appsec scan for auth bypass, missing auth, XSS, RCE, SQL injection, SSRF, path traversal, secrets, weak crypto, unsafe redirects, webhook verification, Next.js Server Actions, Lua\u002FOpenResty, Go, cache poisoning, or header trust bugs.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2406,2409,2410,2411],{"name":2407,"slug":2408,"type":16},"Audit","audit",{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"name":2412,"slug":2413,"type":16},"Vercel","vercel","2026-05-05T05:29:23.090902",{"slug":2416,"name":2416,"fn":2417,"description":2418,"org":2419,"tags":2420,"stars":27,"repoUrl":28,"updatedAt":2430},"wrdn-authz","detect authorization and IDOR flaws","Detects authorization flaws: IDOR, missing ownership or tenant scoping, role checks that fail open, privilege escalation, unauthenticated admin actions, mass assignment, and token\u002Fsession claims trusted for permission decisions. Use when asked to review route handlers, middleware, decorators, resolvers, RBAC\u002FACL logic, serializers, ORM queries, token-derived scopes, or admin surfaces.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2421,2424,2427,2428,2429],{"name":2422,"slug":2423,"type":16},"Access Control","access-control",{"name":2425,"slug":2426,"type":16},"Auth","auth",{"name":22,"slug":23,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},"2026-04-29T05:41:41.218677",{"slug":2432,"name":2432,"fn":2433,"description":2434,"org":2435,"tags":2436,"stars":27,"repoUrl":28,"updatedAt":2446},"wrdn-code-execution","detect code and command execution bugs","Detects bugs where untrusted input reaches a sink that produces code or command execution on the server. Covers command\u002Fshell injection, unsafe deserialization, server-side template injection, eval\u002FFunction\u002Fvm reached by user data, XXE-to-RCE gadgets, and prototype pollution that lands on a code-executing sink. Run on any diff touching subprocess\u002Fexec calls, template rendering, deserialization of bytes, XML parsing, or deep-merge of user-controlled objects.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2437,2440,2441,2444,2445],{"name":2438,"slug":2439,"type":16},"Backend","backend",{"name":22,"slug":23,"type":16},{"name":2442,"slug":2443,"type":16},"Debugging","debugging",{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},"2026-04-29T05:41:39.861655",{"slug":2448,"name":2448,"fn":2449,"description":2450,"org":2451,"tags":2452,"stars":27,"repoUrl":28,"updatedAt":2457},"wrdn-data-exfil","detect data exfiltration and SSRF bugs","Detects bugs where untrusted input reaches a sink that leaks data beyond its intended scope. Covers SSRF (including cloud metadata, internal services, image proxies), path traversal and archive zip-slip, SQL\u002FNoSQL injection enabling bulk reads, XXE file read, response serializers over-exposing internal fields, verbose error pages, logs capturing secrets, and CSV\u002Fformula injection in exports. Run on any diff touching HTTP clients with user URLs, file I\u002FO with user paths, raw queries, XML parsing, response serializers, error handlers, or export pipelines.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2453,2454,2455,2456],{"name":2438,"slug":2439,"type":16},{"name":22,"slug":23,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},"2026-04-29T05:41:42.567486",{"slug":2459,"name":2459,"fn":2460,"description":2461,"org":2462,"tags":2463,"stars":27,"repoUrl":28,"updatedAt":2468},"wrdn-dos-review","identify denial-of-service vulnerabilities in code","Finds availability \u002F denial-of-service bugs reachable from untrusted input — unbounded allocation, uncontrolled recursion, non-terminating loops, decompression bombs, panic\u002Fresource-leak, super-linear output amplification, algorithmic-complexity \u002F ReDoS catastrophic regex backtracking, and bounds that are present but ineffective (wrong dimension, applied too late, under-counting cost, or defaulted off). Use for DoS and resource-exhaustion audits, CPU-complexity and cost-limit \u002F quota-accuracy review, parser\u002Fdecoder\u002Fdeserialization hardening, and crash-safety review of code that processes attacker-controlled bytes.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2464,2465,2466,2467],{"name":22,"slug":23,"type":16},{"name":2442,"slug":2443,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},"2026-07-18T05:47:48.104703",{"slug":2470,"name":2470,"fn":2471,"description":2472,"org":2473,"tags":2474,"stars":27,"repoUrl":28,"updatedAt":2484},"wrdn-gha-workflows","detect GitHub Actions workflow vulnerabilities","Detects exploitable GitHub Actions workflow vulnerabilities, including pull_request_target pwn requests, unsafe PR checkout, expression injection in run steps and actions\u002Fgithub-script blocks, workflow_dispatch and workflow_call input command injection, comment- and discussion-triggered commands, TOCTOU between approval and checkout, secret exposure, broad permissions, reusable workflows that consume undeclared secrets, ArtiPACKED-style token leaks through uploaded artifacts, cache poisoning and eviction-stuffing, supply-chain risk from unpinned third-party actions (tj-actions\u002Fchanged-files class), and self-hosted runner abuse. Run on diffs touching .github\u002Fworkflows, action.yml, action.yaml, repo-local actions, or CI-loaded scripts and config.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2475,2478,2479,2482,2483],{"name":2476,"slug":2477,"type":16},"CI\u002FCD","ci-cd",{"name":22,"slug":23,"type":16},{"name":2480,"slug":2481,"type":16},"GitHub Actions","github-actions",{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},"2026-04-29T05:41:43.93205",{"slug":4,"name":4,"fn":5,"description":6,"org":2486,"tags":2487,"stars":27,"repoUrl":28,"updatedAt":29},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2488,2489,2490,2491,2492],{"name":22,"slug":23,"type":16},{"name":18,"slug":19,"type":16},{"name":25,"slug":26,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},7,{"items":2495,"total":2664},[2496,2519,2533,2548,2562,2579,2593,2607,2615,2626,2636,2651],{"slug":2497,"name":2497,"fn":2498,"description":2499,"org":2500,"tags":2501,"stars":2516,"repoUrl":2517,"updatedAt":2518},"xcodebuildmcp","build and test Apple apps with XcodeBuildMCP","Official skill for XcodeBuildMCP. Use when doing iOS\u002FmacOS\u002FwatchOS\u002FtvOS\u002FvisionOS work (build, test, run, debug, log, UI automation).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2502,2503,2506,2509,2510,2513],{"name":2442,"slug":2443,"type":16},{"name":2504,"slug":2505,"type":16},"iOS","ios",{"name":2507,"slug":2508,"type":16},"macOS","macos",{"name":9,"slug":8,"type":16},{"name":2511,"slug":2512,"type":16},"Testing","testing",{"name":2514,"slug":2515,"type":16},"Xcode","xcode",6176,"https:\u002F\u002Fgithub.com\u002Fgetsentry\u002FXcodeBuildMCP","2026-04-06T18:13:34.8719",{"slug":2520,"name":2520,"fn":2521,"description":2522,"org":2523,"tags":2524,"stars":2516,"repoUrl":2517,"updatedAt":2532},"xcodebuildmcp-cli","build and test Apple apps via CLI","Official skill for the XcodeBuildMCP CLI. Use when doing iOS\u002FmacOS\u002FwatchOS\u002FtvOS\u002FvisionOS work (build, test, run, debug, log, UI automation).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2525,2528,2529,2530,2531],{"name":2526,"slug":2527,"type":16},"CLI","cli",{"name":2504,"slug":2505,"type":16},{"name":2507,"slug":2508,"type":16},{"name":2511,"slug":2512,"type":16},{"name":2514,"slug":2515,"type":16},"2026-04-06T18:13:36.13414",{"slug":2534,"name":2534,"fn":2535,"description":2536,"org":2537,"tags":2538,"stars":2545,"repoUrl":2546,"updatedAt":2547},"agents-md","maintain project instruction files","Creates and maintains concise AGENTS.md and CLAUDE.md project instruction files. Use when asked to create AGENTS.md, update AGENTS.md, maintain agent docs, set up CLAUDE.md, document repository agent conventions, or keep coding-agent instructions minimal and reference-backed.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2539,2542],{"name":2540,"slug":2541,"type":16},"Documentation","documentation",{"name":2543,"slug":2544,"type":16},"Engineering","engineering",861,"https:\u002F\u002Fgithub.com\u002Fgetsentry\u002Fskills","2026-05-15T06:16:29.695991",{"slug":2549,"name":2549,"fn":2550,"description":2551,"org":2552,"tags":2553,"stars":2545,"repoUrl":2546,"updatedAt":2561},"blog-writing-guide","write and review engineering blog posts","Write, review, and improve blog posts for the Sentry engineering blog following Sentry's specific writing standards, voice, and quality bar. Use this skill whenever someone asks to write a blog post, draft a technical article, review blog content, improve a draft, write a product announcement, create an engineering deep-dive, or produce any written content destined for the Sentry blog or developer audience. Also trigger when the user mentions \"blog post,\" \"blog draft,\" \"write-up,\" \"announcement post,\" \"engineering post,\" \"deep dive,\" \"postmortem,\" or asks for help with technical writing for Sentry. Even if the user just says \"help me write about [feature\u002Ftopic]\" — if it sounds like it could become a Sentry blog post, use this skill.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2554,2557,2558],{"name":2555,"slug":2556,"type":16},"Communications","communications",{"name":9,"slug":8,"type":16},{"name":2559,"slug":2560,"type":16},"Technical Writing","technical-writing","2026-05-15T06:16:33.38217",{"slug":2563,"name":2563,"fn":2564,"description":2565,"org":2566,"tags":2567,"stars":2545,"repoUrl":2546,"updatedAt":2578},"brand-guidelines","write copy following Sentry brand guidelines","Write copy following Sentry brand guidelines. Use when writing UI text, error messages, empty states, onboarding flows, 404 pages, documentation, marketing copy, or any user-facing content. Covers both Plain Speech (default) and Sentry Voice tones.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2568,2571,2574,2575],{"name":2569,"slug":2570,"type":16},"Branding","branding",{"name":2572,"slug":2573,"type":16},"Content Creation","content-creation",{"name":9,"slug":8,"type":16},{"name":2576,"slug":2577,"type":16},"UX Copy","ux-copy","2026-05-15T06:16:22.395707",{"slug":2580,"name":2580,"fn":2581,"description":2582,"org":2583,"tags":2584,"stars":2545,"repoUrl":2546,"updatedAt":2592},"claude-settings-audit","generate Claude Code settings permissions","Analyze a repository to generate recommended Claude Code settings.json permissions. Use when setting up a new project, auditing existing settings, or determining which read-only bash commands to allow. Detects tech stack, build tools, and monorepo structure.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2585,2588,2591],{"name":2586,"slug":2587,"type":16},"Claude Code","claude-code",{"name":2589,"slug":2590,"type":16},"Configuration","configuration",{"name":14,"slug":15,"type":16},"2026-05-15T06:16:44.335977",{"slug":2594,"name":2594,"fn":2595,"description":2596,"org":2597,"tags":2598,"stars":2545,"repoUrl":2546,"updatedAt":2606},"code-review","perform code reviews for Sentry projects","Perform code reviews following Sentry engineering practices. Use when reviewing pull requests, examining code changes, or providing feedback on code quality. Covers security, performance, testing, and design review.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2599,2601,2602,2605],{"name":2600,"slug":2594,"type":16},"Code Review",{"name":2543,"slug":2544,"type":16},{"name":2603,"slug":2604,"type":16},"Performance","performance",{"name":14,"slug":15,"type":16},"2026-05-15T06:16:35.824864",{"slug":2608,"name":2608,"fn":2609,"description":2610,"org":2611,"tags":2612,"stars":2545,"repoUrl":2546,"updatedAt":2614},"code-simplifier","simplify and refine source code","Simplifies and refines code for clarity, consistency, and maintainability while preserving all functionality. Use when asked to \"simplify code\", \"clean up code\", \"refactor for clarity\", \"improve readability\", or review recently modified code for elegance. Focuses on project-specific best practices.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2613],{"name":22,"slug":23,"type":16},"2026-05-15T06:16:32.127981",{"slug":2616,"name":2616,"fn":2617,"description":2618,"org":2619,"tags":2620,"stars":2545,"repoUrl":2546,"updatedAt":2625},"commit","create commits with Sentry conventions","Use for every request to commit changes or draft a commit message. Creates Sentry-style conventional commits with issue references.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2621,2624],{"name":2622,"slug":2623,"type":16},"Git","git",{"name":9,"slug":8,"type":16},"2026-07-18T05:15:10.723937",{"slug":2627,"name":2627,"fn":2628,"description":2629,"org":2630,"tags":2631,"stars":2545,"repoUrl":2546,"updatedAt":2635},"create-branch","create git branches for Sentry workflows","Create a git branch following Sentry naming conventions. Use when asked to \"create a branch\", \"new branch\", \"start a branch\", \"make a branch\", \"switch to a new branch\", or when starting new work on the default branch.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2632,2633,2634],{"name":2543,"slug":2544,"type":16},{"name":2622,"slug":2623,"type":16},{"name":9,"slug":8,"type":16},"2026-05-15T06:16:39.458431",{"slug":2637,"name":2637,"fn":2638,"description":2639,"org":2640,"tags":2641,"stars":2545,"repoUrl":2546,"updatedAt":2650},"django-access-review","review Django access control and IDOR","Django access control and IDOR security review. Use when reviewing Django views, DRF viewsets, ORM queries, or any Python\u002FDjango code handling user authorization. Trigger keywords: \"IDOR\", \"access control\", \"authorization\", \"Django permissions\", \"object permissions\", \"tenant isolation\", \"broken access\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2642,2643,2644,2647,2649],{"name":2422,"slug":2423,"type":16},{"name":22,"slug":23,"type":16},{"name":2645,"slug":2646,"type":16},"Django","django",{"name":2648,"slug":1090,"type":16},"Python",{"name":14,"slug":15,"type":16},"2026-05-15T06:16:43.098698",{"slug":2652,"name":2652,"fn":2653,"description":2654,"org":2655,"tags":2656,"stars":2545,"repoUrl":2546,"updatedAt":2663},"django-perf-review","review and optimize Django performance","Django performance code review. Use when asked to \"review Django performance\", \"find N+1 queries\", \"optimize Django\", \"check queryset performance\", \"database performance\", \"Django ORM issues\", or audit Django code for performance problems.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2657,2658,2661,2662],{"name":2600,"slug":2594,"type":16},{"name":2659,"slug":2660,"type":16},"Database","database",{"name":2645,"slug":2646,"type":16},{"name":2603,"slug":2604,"type":16},"2026-05-15T06:16:24.832813",88]