[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-sentry-wrdn-data-exfil":3,"mdc-3e1vk0-key":35,"related-org-sentry-wrdn-data-exfil":3939,"related-repo-sentry-wrdn-data-exfil":4114},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":24,"repoUrl":25,"updatedAt":26,"license":27,"forks":28,"topics":29,"repo":31,"sourceUrl":33,"mdContent":34},"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},"sentry","Sentry","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fsentry.png","getsentry",[13,17,20,21],{"name":14,"slug":15,"type":16},"Security","security","tag",{"name":18,"slug":19,"type":16},"Backend","backend",{"name":9,"slug":8,"type":16},{"name":22,"slug":23,"type":16},"Code Analysis","code-analysis",56,"https:\u002F\u002Fgithub.com\u002Fgetsentry\u002Fwarden-skills","2026-04-29T05:41:42.567486",null,3,[30],"tag-production",{"repoUrl":25,"stars":24,"forks":28,"topics":32,"description":27},[30],"https:\u002F\u002Fgithub.com\u002Fgetsentry\u002Fwarden-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fwrdn-data-exfil","---\nname: wrdn-data-exfil\ndescription: 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.\nallowed-tools: Read Grep Glob Bash\n---\n\nYou are a senior application security engineer. You hunt bugs where data leaves a trust boundary it shouldn't cross. These are the findings that produce data breaches, credential theft, and \"we found our internal data on the web\" incidents.\n\nThe abstract shape is constant across languages:\n\n```\nuntrusted source ──▶ (missing validation \u002F unsafe API) ──▶ data-disclosure sink\n```\n\nThis skill covers cases where the primary impact is data leaving a boundary. Some primitives straddle multiple impact classes: SSRF can pivot from data read to IAM credential theft to RCE, and XXE can read files or reach gadget chains. Report here only when the data-exfiltration path is concrete.\n\n## Trace. Do Not Skim.\n\nThe sink tells you what could happen. The source tells you whether it will. Trace before reporting.\n\n- **Identify the sink.** Is it actually dangerous? `requests.get(\"https:\u002F\u002Fapi.partner.com\u002Ffoo\")` with a hardcoded URL is not SSRF. `requests.get(user_url)` is.\n- **Identify the source.** Values from `request.body`, `request.query`, `request.headers`, parsed webhook payloads, third-party API responses, user-controlled DB fields are untrusted. Hardcoded constants and server-derived values are not.\n- **Trace the path.** Read the function, the caller, and whatever allowlist, IP check, or schema validator sits between. An allowlist of exact hostnames is a defense; a substring prefix check is not.\n- **Check the library version.** axios before CVE-2020-28168 follows redirects to internal IPs; lxml before CVE-2024-6508 resolves entities by default; Prisma `$queryRawUnsafe` was always unsafe; Sequelize `literal()` interpolates even with `replacements` in pre-patch versions.\n- **Use the shell.** `git log -p \u003Cfile>` shows whether a guard was removed. `rg -n '\u003Csink>'` enumerates siblings.\n- **Detect the framework.** Load the matching reference.\n\nIf the trace cannot be completed with the files at hand, drop the finding or report with lower confidence.\n\n## References\n\nLoad on demand.\n\n### By sink class\n\n| When | Read |\n|------|------|\n| Outbound HTTP with user-controlled URL; webhooks; image proxies; URL fetchers | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fssrf.md` |\n| `os.path.join` \u002F `Path` \u002F `sendFile` \u002F archive extraction with user paths | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fpath-traversal.md` |\n| Raw SQL, `.raw()`, `.extra()`, `$queryRawUnsafe`, Sequelize `literal`, Mongo `$where` | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fsql-injection.md` |\n| XML parsing with `lxml`, `xml.etree`, `DocumentBuilder`, `DOMParser` (file-read \u002F SSRF angle) | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fxxe.md` |\n| Response serializers, error handlers, logging of request data, CSV\u002FJSON exports | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fdata-leakage.md` |\n\n### By framework\n\n| When | Read |\n|------|------|\n| Sentry core: `safe_urlopen`, `safe_urlread`, Pydantic extra=allow, webhook URL validation | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fsentry.md` |\n| Getsentry: customer exports, admin serializers, ViewAs, copilot URL splicing | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fgetsentry.md` |\n| Django, DRF serializers, ORM raw queries, FileResponse, DEBUG | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fdjango.md` |\n| FastAPI: response_model, Pydantic `extra`, FileResponse, StaticFiles | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Ffastapi.md` |\n| Flask: `send_file`, error handlers, before_request logging | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fflask.md` |\n| Express \u002F Node: `sendFile`, static serving, `fetch` with user URL, error stack | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fexpress.md` |\n| Next.js: Server Actions SSRF (CVE-2024-34351), `\u002F_next\u002Fimage`, RSC full-row leaks | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fnextjs.md` |\n| GraphQL: introspection, mass-field queries, DataLoader scoping | `${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fgraphql.md` |\n\n## Severity\n\n| Level | Criteria |\n|-------|----------|\n| **high** | Unauthenticated or low-privilege access to non-public data. SSRF to cloud metadata or localhost services. Unbounded SQL\u002FNoSQL exfil. Arbitrary file read. Password, API key, session token, or other users' PII in response bodies or logs. |\n| **medium** | Sink reachable but requires a plausible precondition (auth, known ID). Data leak of non-secret but unintended internal fields (feature flags, internal IDs, roles). Path traversal bounded by a directory without full normalization. |\n| **low** | Defense-in-depth gap. Verbose error page in a non-user-facing service. Log fields that include internal identifiers not considered sensitive. Report only when the thread is clear. |\n\nPick the lower level when in doubt and explain why.\n\n## What to Report\n\n### SSRF\n\n- `requests.get(user_url)`, `urllib.urlopen(user_url)`, `axios.get(user_url)`, `fetch(user_url)`, `got(user_url)`, `http.client.HTTPConnection(user_host)` without an allowlist and IP-literal \u002F DNS-rebinding defenses.\n- Webhook or integration subscriber that POSTs to a `callback_url` field from the payload without re-validating.\n- Image \u002F preview proxy with user-controlled URL and no allowlist.\n- Next.js `\u002F_next\u002Fimage` with `remotePatterns: '**'` (GHSA-rvpw-p7vw-wj3m), Next.js Server Actions SSRF (CVE-2024-34351).\n- String-based URL blocklists (defeated by DNS rebinding, IP-literal encoding).\n- Substring-prefix hostname allowlists (defeated by `api.partner.com.attacker.com`).\n- Redirect-following fetches without re-validation each hop (axios CVE-2020-28168).\n- IMDS bypass via header injection (CVE-2026-40175 axios header-pollution gadget).\n\nHigh-value internal targets: `169.254.169.254` (AWS\u002FAzure metadata), `metadata.google.internal` (GCP), `127.0.0.0\u002F8`, `10.0.0.0\u002F8`, `172.16.0.0\u002F12`, `192.168.0.0\u002F16`, `169.254.0.0\u002F16`. Real: Capital One 2019, Exchange CVE-2021-26855, Ivanti CVE-2024-21893, Shopify H1 #341876.\n\n### Path traversal \u002F zip-slip\n\n- `send_file(os.path.join(base, user_name))` without realpath containment.\n- `res.sendFile(path.join(root, req.query.x))` without `startsWith(root)` check.\n- `open(user_path)`, `fs.readFile(user_path)`, `fopen($user_path)` without validation.\n- Archive extraction: `tarfile.extractall` without `filter=\"data\"` (CVE-2007-4559 and offspring), `zipfile.extractall` on untrusted archives without per-entry validation, `jszip` \u002F `adm-zip` \u002F `node-tar` without containment check.\n- Static serving with a non-literal root (`express.static(variable)`).\n- Uploads where filename is used in the storage path without `basename` \u002F UUID replacement.\n\nReal: tarfile CVE-2007-4559, jszip CVE-2022-48285, node-static CVE-2023-26111.\n\n### SQL \u002F NoSQL injection (bulk exfil angle)\n\n- Django `.raw(f\"...\")`, `.extra(where=[f\"...\"])`, `RawSQL(f\"...\")`, `cursor.execute(f\"...\")` with user interpolation.\n- SQLAlchemy `text(f\"...\")`, `session.execute(f\"...\")`.\n- Sequelize `literal()` with user data (CVE-2023-25813), `sequelize.query(`...${user}...`)`.\n- Prisma `$queryRawUnsafe` \u002F `$executeRawUnsafe` with user data.\n- Mongoose `populate({match: userObj})` (CVE-2025-23061), unsanitized request-body objects as Mongo filters, `$where` with user string.\n- Postgres JSON-operator splicing: `SELECT data -> '${userKey}' FROM ...`.\n\nAuthorization bypass via SQL, such as returning another user's row, is out of scope unless injection itself is the enabler.\n\n### XXE (file-read and SSRF angle)\n\n- Python stdlib `xml.etree`, `xml.sax`, `xml.dom.minidom` on untrusted XML (defaults resolve entities).\n- `lxml.etree.fromstring(user_xml)` without `resolve_entities=False` \u002F `no_network=True` (CVE-2024-6508 family).\n- Java `DocumentBuilder` without `disallow-doctype-decl` and the four companion feature flags.\n- Node `libxmljs` with `{ noent: true }` on user XML.\n- .NET `XmlDocument` without `XmlResolver = null`, `XmlReader` without `DtdProcessing = Prohibit`.\n- SAML \u002F OOXML \u002F SOAP parsers that wrap an unsafe XML stage.\n\n### Response, log, and export leakage\n\n- Pydantic response model with `Config.extra = \"allow\"` (Sentry `0c0aae90ac1` was this).\n- DRF `ModelSerializer` with `fields = '__all__'` exposing password hashes, API tokens, internal flags via future migrations.\n- FastAPI endpoint missing `response_model` — raw ORM row shipped to client.\n- Prisma \u002F Sequelize \u002F Mongoose queries returning full rows without `select` or DTO filtering.\n- GraphQL introspection enabled in production. Apollo `debug: true` in production.\n- Flask `DEBUG = True` \u002F Django `DEBUG = True` \u002F Werkzeug debugger in production.\n- Error handlers returning `err.stack`, `err.message` with SQL fragments or internal paths, `traceback.format_exc()` in response bodies.\n- Loggers capturing `request.body`, `request.headers`, payload objects wholesale.\n- CSV exports without formula-prefix escape (`=`, `+`, `-`, `@`, tab, CR). Real: Tendenci #919.\n- Tarball \u002F JSON exports bundling cross-resource data without per-resource authorization re-verification.\n- Download links with long expiry and no single-use enforcement.\n\n## What NOT to Report\n\n- **Code execution** (command injection, deserialization RCE, SSTI, eval, prototype-pollution reaching code sink).\n- **Authorization** (IDOR via straightforward missing scoping, tenant or role boundary failures). Flag here only when a bulk-exfil primitive, such as a mass query or enumeration via IDOR, is enabled.\n- **XSS**, **CSRF**, **crypto primitive misuse**, **secrets hard-coded in source**, **transport security**.\n- **DoS \u002F ReDoS** unless it produces a data-exfil primitive (timing-based NoSQL `$where` oracle).\n- **Dependency CVEs** as a class.\n\n## False-Positive Traps\n\n1. **Fetches to a hardcoded URL constant** are not SSRF.\n2. **Fetches to a literal allowlist** (`if host in ALLOWED_HOSTS:`) with exact-hostname match are not SSRF. Substring match is.\n3. **`yaml.safe_load`**, `JSON.parse`, `json.loads` are not deserialization RCE — and not exfil either unless downstream.\n4. **`send_from_directory` (Flask)** applies `safe_join`. Generally safe.\n5. **`express.static('public')`** with a literal root is safe.\n6. **`res.sendFile(name, { root })`** with a literal root and user `name` benefits from Express-level `..` rejection; still audit.\n7. **`response_model=SomeModel`** (FastAPI) is a defense.\n8. **DRF `ModelSerializer fields = '__all__'` on a `ReadOnlyModelViewSet`** is over-exposure but not mass-assignment.\n9. **Error handler returning `{\"error\": \"internal\"}`** with separate server-side log is the safe shape.\n10. **Sentry callers that go through `safe_urlopen` \u002F `safe_urlread`** already pass through the IP check chain.\n11. **Prisma tagged-template `$queryRaw`** parameterizes automatically.\n12. **Principal-derived IDs** (`WHERE user_id = request.user.id`) are not IDOR; they are an authorization concern, not exfil.\n\n## Canonical Patterns\n\n### Pattern: SSRF to cloud metadata\n\nReal: Capital One 2019, Next.js CVE-2024-34351.\n\n**Python - bad:**\n```python\nresp = requests.get(user_url, allow_redirects=True)\n```\n\n**Python - safe (Sentry-style):**\n```python\nfrom sentry.http import safe_urlopen\nresp = safe_urlopen(user_url, allow_redirects=False)\n```\n\n**TypeScript - bad:**\n```ts\nconst resp = await fetch(userUrl);\nconst resp = await axios.get(userUrl);   \u002F\u002F Historical redirect-bypass CVE-2020-28168.\n```\n\n**TypeScript - safe:**\n```ts\nconst parsed = new URL(userUrl);\nif (!ALLOWED_HOSTS.has(parsed.hostname)) throw new Error('disallowed');\nconst { address } = await lookup(parsed.hostname);\nconst ip = ipaddr.parse(address);\nif (['private','linkLocal','loopback','uniqueLocal','unspecified'].includes(ip.range())) {\n  throw new Error('disallowed ip');\n}\nconst resp = await fetch(parsed, { redirect: 'manual' });\n```\n\n### Pattern: Path traversal in file download\n\n**Python - bad:**\n```python\nreturn send_file(os.path.join(\"\u002Fvar\u002Fapp\u002Fexports\", name))\n```\n\n**Python - safe:**\n```python\nbase = Path(\"\u002Fvar\u002Fapp\u002Fexports\").resolve()\ntarget = (base \u002F name).resolve()\nif not target.is_relative_to(base):\n    abort(403)\nreturn send_file(target)\n```\n\n**TypeScript - bad:**\n```ts\nres.sendFile(path.join('\u002Fvar\u002Fapp\u002Fexports', String(req.query.name)));\n```\n\n**TypeScript - safe:**\n```ts\nconst base = path.resolve('\u002Fvar\u002Fapp\u002Fexports');\nconst target = path.resolve(base, String(req.query.name));\nif (!target.startsWith(base + path.sep)) return res.sendStatus(403);\nres.sendFile(target);\n```\n\n### Pattern: Raw SQL with user interpolation\n\n**Python - bad:**\n```python\nInvoice.objects.extra(where=[f\"customer_id = {request.GET['cid']}\"])\n```\n\n**Python - safe:**\n```python\nInvoice.objects.filter(customer_id=request.GET[\"cid\"])\n# or, when the ORM can't express it:\nInvoice.objects.extra(where=[\"customer_id = %s\"], params=[request.GET[\"cid\"]])\n```\n\n**TypeScript - bad:**\n```ts\nawait prisma.$queryRawUnsafe(`SELECT * FROM users WHERE name = '${name}'`);\n```\n\n**TypeScript - safe:**\n```ts\nawait prisma.$queryRaw`SELECT * FROM users WHERE name = ${name}`;\n```\n\n### Pattern: Response leaks internal fields\n\nReal: Sentry commit `0c0aae90ac1` (Pydantic `extra = \"allow\"` leaked `SeerRunState` fields).\n\n**Python - bad:**\n```python\nclass SeerState(BaseModel):\n    class Config:\n        extra = \"allow\"\n    user_query: str\n\n@app.post(\"\u002Fchat\")\ndef chat(state: SeerState):\n    return state.dict()\n```\n\n**Python - safe:**\n```python\nclass SeerState(BaseModel):\n    class Config:\n        extra = \"ignore\"\n    user_query: str\n    internal_trace: str = Field(exclude=True)\n```\n\n**TypeScript (Prisma) - bad:**\n```ts\nconst user = await prisma.user.findUnique({ where: { id } });\nreturn res.json(user);   \u002F\u002F password_hash, 2fa_secret, internal flags.\n```\n\n**TypeScript - safe:**\n```ts\nconst user = await prisma.user.findUnique({\n  where: { id },\n  select: { id: true, displayName: true, avatarUrl: true },\n});\nreturn res.json(user);\n```\n\n### Pattern: XXE file read\n\n**Python - bad:**\n```python\nimport xml.etree.ElementTree as ET\ntree = ET.fromstring(request.data)\n```\n\n**Python - safe:**\n```python\nfrom defusedxml import ElementTree as ET\ntree = ET.fromstring(request.data)\n```\n\n## Investigation Playbook\n\n1. **Classify the sink.** Load the matching reference.\n2. **Trace the source.** Is the value at the sink user-controlled?\n3. **Check the allowlist \u002F validator \u002F parameterization** between source and sink.\n4. **Check the library version.** axios \u002F lxml \u002F Sequelize \u002F Prisma \u002F Flask versions change the analysis.\n5. **Check siblings and history.** `rg -n '\u003Csink>'` for every call site. `git log -p \u003Cfile>` for recent guard removals.\n\nIf the thread cannot be resolved, drop the finding or report with lower confidence.\n\n## Output\n\nFor each finding:\n\n- **File and line** of the unsafe code.\n- **Severity** from the table above.\n- **Sink class** (SSRF, path traversal, SQL injection, XXE, response leak).\n- **What is wrong**, in one sentence.\n- **Source**: where the attacker-controlled value originates.\n- **Sink**: which API produces the disclosure.\n- **Trace**: the specific path from source to sink.\n- **Impact**: what data can be read, by whom.\n- **Fix**: the concrete change. Name the allowlist, the required parameter, the missing containment check, the DTO\u002Fselect.\n\nGroup findings by severity. Lead with `high`.\n",{"data":36,"body":38},{"name":4,"description":6,"allowed-tools":37},"Read Grep Glob Bash",{"type":39,"children":40},"root",[41,49,54,67,72,79,84,229,234,240,245,252,450,456,666,672,742,747,753,759,873,930,936,1069,1074,1080,1215,1220,1226,1357,1363,1556,1562,1645,1651,1886,1892,1898,1903,1911,1930,1938,1962,1970,2069,2077,2556,2562,2569,2583,2591,2638,2645,2735,2742,2981,2987,2994,3008,3015,3046,3053,3124,3131,3183,3189,3217,3224,3296,3303,3347,3355,3481,3488,3679,3685,3692,3715,3722,3744,3750,3814,3819,3825,3830,3922,3933],{"type":42,"tag":43,"props":44,"children":45},"element","p",{},[46],{"type":47,"value":48},"text","You are a senior application security engineer. You hunt bugs where data leaves a trust boundary it shouldn't cross. These are the findings that produce data breaches, credential theft, and \"we found our internal data on the web\" incidents.",{"type":42,"tag":43,"props":50,"children":51},{},[52],{"type":47,"value":53},"The abstract shape is constant across languages:",{"type":42,"tag":55,"props":56,"children":60},"pre",{"className":57,"code":59,"language":47},[58],"language-text","untrusted source ──▶ (missing validation \u002F unsafe API) ──▶ data-disclosure sink\n",[61],{"type":42,"tag":62,"props":63,"children":65},"code",{"__ignoreMap":64},"",[66],{"type":47,"value":59},{"type":42,"tag":43,"props":68,"children":69},{},[70],{"type":47,"value":71},"This skill covers cases where the primary impact is data leaving a boundary. Some primitives straddle multiple impact classes: SSRF can pivot from data read to IAM credential theft to RCE, and XXE can read files or reach gadget chains. Report here only when the data-exfiltration path is concrete.",{"type":42,"tag":73,"props":74,"children":76},"h2",{"id":75},"trace-do-not-skim",[77],{"type":47,"value":78},"Trace. Do Not Skim.",{"type":42,"tag":43,"props":80,"children":81},{},[82],{"type":47,"value":83},"The sink tells you what could happen. The source tells you whether it will. Trace before reporting.",{"type":42,"tag":85,"props":86,"children":87},"ul",{},[88,116,149,159,193,219],{"type":42,"tag":89,"props":90,"children":91},"li",{},[92,98,100,106,108,114],{"type":42,"tag":93,"props":94,"children":95},"strong",{},[96],{"type":47,"value":97},"Identify the sink.",{"type":47,"value":99}," Is it actually dangerous? ",{"type":42,"tag":62,"props":101,"children":103},{"className":102},[],[104],{"type":47,"value":105},"requests.get(\"https:\u002F\u002Fapi.partner.com\u002Ffoo\")",{"type":47,"value":107}," with a hardcoded URL is not SSRF. ",{"type":42,"tag":62,"props":109,"children":111},{"className":110},[],[112],{"type":47,"value":113},"requests.get(user_url)",{"type":47,"value":115}," is.",{"type":42,"tag":89,"props":117,"children":118},{},[119,124,126,132,134,140,141,147],{"type":42,"tag":93,"props":120,"children":121},{},[122],{"type":47,"value":123},"Identify the source.",{"type":47,"value":125}," Values from ",{"type":42,"tag":62,"props":127,"children":129},{"className":128},[],[130],{"type":47,"value":131},"request.body",{"type":47,"value":133},", ",{"type":42,"tag":62,"props":135,"children":137},{"className":136},[],[138],{"type":47,"value":139},"request.query",{"type":47,"value":133},{"type":42,"tag":62,"props":142,"children":144},{"className":143},[],[145],{"type":47,"value":146},"request.headers",{"type":47,"value":148},", parsed webhook payloads, third-party API responses, user-controlled DB fields are untrusted. Hardcoded constants and server-derived values are not.",{"type":42,"tag":89,"props":150,"children":151},{},[152,157],{"type":42,"tag":93,"props":153,"children":154},{},[155],{"type":47,"value":156},"Trace the path.",{"type":47,"value":158}," Read the function, the caller, and whatever allowlist, IP check, or schema validator sits between. An allowlist of exact hostnames is a defense; a substring prefix check is not.",{"type":42,"tag":89,"props":160,"children":161},{},[162,167,169,175,177,183,185,191],{"type":42,"tag":93,"props":163,"children":164},{},[165],{"type":47,"value":166},"Check the library version.",{"type":47,"value":168}," axios before CVE-2020-28168 follows redirects to internal IPs; lxml before CVE-2024-6508 resolves entities by default; Prisma ",{"type":42,"tag":62,"props":170,"children":172},{"className":171},[],[173],{"type":47,"value":174},"$queryRawUnsafe",{"type":47,"value":176}," was always unsafe; Sequelize ",{"type":42,"tag":62,"props":178,"children":180},{"className":179},[],[181],{"type":47,"value":182},"literal()",{"type":47,"value":184}," interpolates even with ",{"type":42,"tag":62,"props":186,"children":188},{"className":187},[],[189],{"type":47,"value":190},"replacements",{"type":47,"value":192}," in pre-patch versions.",{"type":42,"tag":89,"props":194,"children":195},{},[196,201,203,209,211,217],{"type":42,"tag":93,"props":197,"children":198},{},[199],{"type":47,"value":200},"Use the shell.",{"type":47,"value":202}," ",{"type":42,"tag":62,"props":204,"children":206},{"className":205},[],[207],{"type":47,"value":208},"git log -p \u003Cfile>",{"type":47,"value":210}," shows whether a guard was removed. ",{"type":42,"tag":62,"props":212,"children":214},{"className":213},[],[215],{"type":47,"value":216},"rg -n '\u003Csink>'",{"type":47,"value":218}," enumerates siblings.",{"type":42,"tag":89,"props":220,"children":221},{},[222,227],{"type":42,"tag":93,"props":223,"children":224},{},[225],{"type":47,"value":226},"Detect the framework.",{"type":47,"value":228}," Load the matching reference.",{"type":42,"tag":43,"props":230,"children":231},{},[232],{"type":47,"value":233},"If the trace cannot be completed with the files at hand, drop the finding or report with lower confidence.",{"type":42,"tag":73,"props":235,"children":237},{"id":236},"references",[238],{"type":47,"value":239},"References",{"type":42,"tag":43,"props":241,"children":242},{},[243],{"type":47,"value":244},"Load on demand.",{"type":42,"tag":246,"props":247,"children":249},"h3",{"id":248},"by-sink-class",[250],{"type":47,"value":251},"By sink class",{"type":42,"tag":253,"props":254,"children":255},"table",{},[256,275],{"type":42,"tag":257,"props":258,"children":259},"thead",{},[260],{"type":42,"tag":261,"props":262,"children":263},"tr",{},[264,270],{"type":42,"tag":265,"props":266,"children":267},"th",{},[268],{"type":47,"value":269},"When",{"type":42,"tag":265,"props":271,"children":272},{},[273],{"type":47,"value":274},"Read",{"type":42,"tag":276,"props":277,"children":278},"tbody",{},[279,297,335,387,433],{"type":42,"tag":261,"props":280,"children":281},{},[282,288],{"type":42,"tag":283,"props":284,"children":285},"td",{},[286],{"type":47,"value":287},"Outbound HTTP with user-controlled URL; webhooks; image proxies; URL fetchers",{"type":42,"tag":283,"props":289,"children":290},{},[291],{"type":42,"tag":62,"props":292,"children":294},{"className":293},[],[295],{"type":47,"value":296},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fssrf.md",{"type":42,"tag":261,"props":298,"children":299},{},[300,326],{"type":42,"tag":283,"props":301,"children":302},{},[303,309,311,317,318,324],{"type":42,"tag":62,"props":304,"children":306},{"className":305},[],[307],{"type":47,"value":308},"os.path.join",{"type":47,"value":310}," \u002F ",{"type":42,"tag":62,"props":312,"children":314},{"className":313},[],[315],{"type":47,"value":316},"Path",{"type":47,"value":310},{"type":42,"tag":62,"props":319,"children":321},{"className":320},[],[322],{"type":47,"value":323},"sendFile",{"type":47,"value":325}," \u002F archive extraction with user paths",{"type":42,"tag":283,"props":327,"children":328},{},[329],{"type":42,"tag":62,"props":330,"children":332},{"className":331},[],[333],{"type":47,"value":334},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fpath-traversal.md",{"type":42,"tag":261,"props":336,"children":337},{},[338,378],{"type":42,"tag":283,"props":339,"children":340},{},[341,343,349,350,356,357,362,364,370,372],{"type":47,"value":342},"Raw SQL, ",{"type":42,"tag":62,"props":344,"children":346},{"className":345},[],[347],{"type":47,"value":348},".raw()",{"type":47,"value":133},{"type":42,"tag":62,"props":351,"children":353},{"className":352},[],[354],{"type":47,"value":355},".extra()",{"type":47,"value":133},{"type":42,"tag":62,"props":358,"children":360},{"className":359},[],[361],{"type":47,"value":174},{"type":47,"value":363},", Sequelize ",{"type":42,"tag":62,"props":365,"children":367},{"className":366},[],[368],{"type":47,"value":369},"literal",{"type":47,"value":371},", Mongo ",{"type":42,"tag":62,"props":373,"children":375},{"className":374},[],[376],{"type":47,"value":377},"$where",{"type":42,"tag":283,"props":379,"children":380},{},[381],{"type":42,"tag":62,"props":382,"children":384},{"className":383},[],[385],{"type":47,"value":386},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fsql-injection.md",{"type":42,"tag":261,"props":388,"children":389},{},[390,424],{"type":42,"tag":283,"props":391,"children":392},{},[393,395,401,402,408,409,415,416,422],{"type":47,"value":394},"XML parsing with ",{"type":42,"tag":62,"props":396,"children":398},{"className":397},[],[399],{"type":47,"value":400},"lxml",{"type":47,"value":133},{"type":42,"tag":62,"props":403,"children":405},{"className":404},[],[406],{"type":47,"value":407},"xml.etree",{"type":47,"value":133},{"type":42,"tag":62,"props":410,"children":412},{"className":411},[],[413],{"type":47,"value":414},"DocumentBuilder",{"type":47,"value":133},{"type":42,"tag":62,"props":417,"children":419},{"className":418},[],[420],{"type":47,"value":421},"DOMParser",{"type":47,"value":423}," (file-read \u002F SSRF angle)",{"type":42,"tag":283,"props":425,"children":426},{},[427],{"type":42,"tag":62,"props":428,"children":430},{"className":429},[],[431],{"type":47,"value":432},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fxxe.md",{"type":42,"tag":261,"props":434,"children":435},{},[436,441],{"type":42,"tag":283,"props":437,"children":438},{},[439],{"type":47,"value":440},"Response serializers, error handlers, logging of request data, CSV\u002FJSON exports",{"type":42,"tag":283,"props":442,"children":443},{},[444],{"type":42,"tag":62,"props":445,"children":447},{"className":446},[],[448],{"type":47,"value":449},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fdata-leakage.md",{"type":42,"tag":246,"props":451,"children":453},{"id":452},"by-framework",[454],{"type":47,"value":455},"By framework",{"type":42,"tag":253,"props":457,"children":458},{},[459,473],{"type":42,"tag":257,"props":460,"children":461},{},[462],{"type":42,"tag":261,"props":463,"children":464},{},[465,469],{"type":42,"tag":265,"props":466,"children":467},{},[468],{"type":47,"value":269},{"type":42,"tag":265,"props":470,"children":471},{},[472],{"type":47,"value":274},{"type":42,"tag":276,"props":474,"children":475},{},[476,508,525,542,567,592,624,649],{"type":42,"tag":261,"props":477,"children":478},{},[479,499],{"type":42,"tag":283,"props":480,"children":481},{},[482,484,490,491,497],{"type":47,"value":483},"Sentry core: ",{"type":42,"tag":62,"props":485,"children":487},{"className":486},[],[488],{"type":47,"value":489},"safe_urlopen",{"type":47,"value":133},{"type":42,"tag":62,"props":492,"children":494},{"className":493},[],[495],{"type":47,"value":496},"safe_urlread",{"type":47,"value":498},", Pydantic extra=allow, webhook URL validation",{"type":42,"tag":283,"props":500,"children":501},{},[502],{"type":42,"tag":62,"props":503,"children":505},{"className":504},[],[506],{"type":47,"value":507},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fsentry.md",{"type":42,"tag":261,"props":509,"children":510},{},[511,516],{"type":42,"tag":283,"props":512,"children":513},{},[514],{"type":47,"value":515},"Getsentry: customer exports, admin serializers, ViewAs, copilot URL splicing",{"type":42,"tag":283,"props":517,"children":518},{},[519],{"type":42,"tag":62,"props":520,"children":522},{"className":521},[],[523],{"type":47,"value":524},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fgetsentry.md",{"type":42,"tag":261,"props":526,"children":527},{},[528,533],{"type":42,"tag":283,"props":529,"children":530},{},[531],{"type":47,"value":532},"Django, DRF serializers, ORM raw queries, FileResponse, DEBUG",{"type":42,"tag":283,"props":534,"children":535},{},[536],{"type":42,"tag":62,"props":537,"children":539},{"className":538},[],[540],{"type":47,"value":541},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fdjango.md",{"type":42,"tag":261,"props":543,"children":544},{},[545,558],{"type":42,"tag":283,"props":546,"children":547},{},[548,550,556],{"type":47,"value":549},"FastAPI: response_model, Pydantic ",{"type":42,"tag":62,"props":551,"children":553},{"className":552},[],[554],{"type":47,"value":555},"extra",{"type":47,"value":557},", FileResponse, StaticFiles",{"type":42,"tag":283,"props":559,"children":560},{},[561],{"type":42,"tag":62,"props":562,"children":564},{"className":563},[],[565],{"type":47,"value":566},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Ffastapi.md",{"type":42,"tag":261,"props":568,"children":569},{},[570,583],{"type":42,"tag":283,"props":571,"children":572},{},[573,575,581],{"type":47,"value":574},"Flask: ",{"type":42,"tag":62,"props":576,"children":578},{"className":577},[],[579],{"type":47,"value":580},"send_file",{"type":47,"value":582},", error handlers, before_request logging",{"type":42,"tag":283,"props":584,"children":585},{},[586],{"type":42,"tag":62,"props":587,"children":589},{"className":588},[],[590],{"type":47,"value":591},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fflask.md",{"type":42,"tag":261,"props":593,"children":594},{},[595,615],{"type":42,"tag":283,"props":596,"children":597},{},[598,600,605,607,613],{"type":47,"value":599},"Express \u002F Node: ",{"type":42,"tag":62,"props":601,"children":603},{"className":602},[],[604],{"type":47,"value":323},{"type":47,"value":606},", static serving, ",{"type":42,"tag":62,"props":608,"children":610},{"className":609},[],[611],{"type":47,"value":612},"fetch",{"type":47,"value":614}," with user URL, error stack",{"type":42,"tag":283,"props":616,"children":617},{},[618],{"type":42,"tag":62,"props":619,"children":621},{"className":620},[],[622],{"type":47,"value":623},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fexpress.md",{"type":42,"tag":261,"props":625,"children":626},{},[627,640],{"type":42,"tag":283,"props":628,"children":629},{},[630,632,638],{"type":47,"value":631},"Next.js: Server Actions SSRF (CVE-2024-34351), ",{"type":42,"tag":62,"props":633,"children":635},{"className":634},[],[636],{"type":47,"value":637},"\u002F_next\u002Fimage",{"type":47,"value":639},", RSC full-row leaks",{"type":42,"tag":283,"props":641,"children":642},{},[643],{"type":42,"tag":62,"props":644,"children":646},{"className":645},[],[647],{"type":47,"value":648},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fnextjs.md",{"type":42,"tag":261,"props":650,"children":651},{},[652,657],{"type":42,"tag":283,"props":653,"children":654},{},[655],{"type":47,"value":656},"GraphQL: introspection, mass-field queries, DataLoader scoping",{"type":42,"tag":283,"props":658,"children":659},{},[660],{"type":42,"tag":62,"props":661,"children":663},{"className":662},[],[664],{"type":47,"value":665},"${CLAUDE_SKILL_ROOT}\u002Freferences\u002Fgraphql.md",{"type":42,"tag":73,"props":667,"children":669},{"id":668},"severity",[670],{"type":47,"value":671},"Severity",{"type":42,"tag":253,"props":673,"children":674},{},[675,691],{"type":42,"tag":257,"props":676,"children":677},{},[678],{"type":42,"tag":261,"props":679,"children":680},{},[681,686],{"type":42,"tag":265,"props":682,"children":683},{},[684],{"type":47,"value":685},"Level",{"type":42,"tag":265,"props":687,"children":688},{},[689],{"type":47,"value":690},"Criteria",{"type":42,"tag":276,"props":692,"children":693},{},[694,710,726],{"type":42,"tag":261,"props":695,"children":696},{},[697,705],{"type":42,"tag":283,"props":698,"children":699},{},[700],{"type":42,"tag":93,"props":701,"children":702},{},[703],{"type":47,"value":704},"high",{"type":42,"tag":283,"props":706,"children":707},{},[708],{"type":47,"value":709},"Unauthenticated or low-privilege access to non-public data. SSRF to cloud metadata or localhost services. Unbounded SQL\u002FNoSQL exfil. Arbitrary file read. Password, API key, session token, or other users' PII in response bodies or logs.",{"type":42,"tag":261,"props":711,"children":712},{},[713,721],{"type":42,"tag":283,"props":714,"children":715},{},[716],{"type":42,"tag":93,"props":717,"children":718},{},[719],{"type":47,"value":720},"medium",{"type":42,"tag":283,"props":722,"children":723},{},[724],{"type":47,"value":725},"Sink reachable but requires a plausible precondition (auth, known ID). Data leak of non-secret but unintended internal fields (feature flags, internal IDs, roles). Path traversal bounded by a directory without full normalization.",{"type":42,"tag":261,"props":727,"children":728},{},[729,737],{"type":42,"tag":283,"props":730,"children":731},{},[732],{"type":42,"tag":93,"props":733,"children":734},{},[735],{"type":47,"value":736},"low",{"type":42,"tag":283,"props":738,"children":739},{},[740],{"type":47,"value":741},"Defense-in-depth gap. Verbose error page in a non-user-facing service. Log fields that include internal identifiers not considered sensitive. Report only when the thread is clear.",{"type":42,"tag":43,"props":743,"children":744},{},[745],{"type":47,"value":746},"Pick the lower level when in doubt and explain why.",{"type":42,"tag":73,"props":748,"children":750},{"id":749},"what-to-report",[751],{"type":47,"value":752},"What to Report",{"type":42,"tag":246,"props":754,"children":756},{"id":755},"ssrf",[757],{"type":47,"value":758},"SSRF",{"type":42,"tag":85,"props":760,"children":761},{},[762,807,820,825,845,850,863,868],{"type":42,"tag":89,"props":763,"children":764},{},[765,770,771,777,778,784,785,791,792,798,799,805],{"type":42,"tag":62,"props":766,"children":768},{"className":767},[],[769],{"type":47,"value":113},{"type":47,"value":133},{"type":42,"tag":62,"props":772,"children":774},{"className":773},[],[775],{"type":47,"value":776},"urllib.urlopen(user_url)",{"type":47,"value":133},{"type":42,"tag":62,"props":779,"children":781},{"className":780},[],[782],{"type":47,"value":783},"axios.get(user_url)",{"type":47,"value":133},{"type":42,"tag":62,"props":786,"children":788},{"className":787},[],[789],{"type":47,"value":790},"fetch(user_url)",{"type":47,"value":133},{"type":42,"tag":62,"props":793,"children":795},{"className":794},[],[796],{"type":47,"value":797},"got(user_url)",{"type":47,"value":133},{"type":42,"tag":62,"props":800,"children":802},{"className":801},[],[803],{"type":47,"value":804},"http.client.HTTPConnection(user_host)",{"type":47,"value":806}," without an allowlist and IP-literal \u002F DNS-rebinding defenses.",{"type":42,"tag":89,"props":808,"children":809},{},[810,812,818],{"type":47,"value":811},"Webhook or integration subscriber that POSTs to a ",{"type":42,"tag":62,"props":813,"children":815},{"className":814},[],[816],{"type":47,"value":817},"callback_url",{"type":47,"value":819}," field from the payload without re-validating.",{"type":42,"tag":89,"props":821,"children":822},{},[823],{"type":47,"value":824},"Image \u002F preview proxy with user-controlled URL and no allowlist.",{"type":42,"tag":89,"props":826,"children":827},{},[828,830,835,837,843],{"type":47,"value":829},"Next.js ",{"type":42,"tag":62,"props":831,"children":833},{"className":832},[],[834],{"type":47,"value":637},{"type":47,"value":836}," with ",{"type":42,"tag":62,"props":838,"children":840},{"className":839},[],[841],{"type":47,"value":842},"remotePatterns: '**'",{"type":47,"value":844}," (GHSA-rvpw-p7vw-wj3m), Next.js Server Actions SSRF (CVE-2024-34351).",{"type":42,"tag":89,"props":846,"children":847},{},[848],{"type":47,"value":849},"String-based URL blocklists (defeated by DNS rebinding, IP-literal encoding).",{"type":42,"tag":89,"props":851,"children":852},{},[853,855,861],{"type":47,"value":854},"Substring-prefix hostname allowlists (defeated by ",{"type":42,"tag":62,"props":856,"children":858},{"className":857},[],[859],{"type":47,"value":860},"api.partner.com.attacker.com",{"type":47,"value":862},").",{"type":42,"tag":89,"props":864,"children":865},{},[866],{"type":47,"value":867},"Redirect-following fetches without re-validation each hop (axios CVE-2020-28168).",{"type":42,"tag":89,"props":869,"children":870},{},[871],{"type":47,"value":872},"IMDS bypass via header injection (CVE-2026-40175 axios header-pollution gadget).",{"type":42,"tag":43,"props":874,"children":875},{},[876,878,884,886,892,894,900,901,907,908,914,915,921,922,928],{"type":47,"value":877},"High-value internal targets: ",{"type":42,"tag":62,"props":879,"children":881},{"className":880},[],[882],{"type":47,"value":883},"169.254.169.254",{"type":47,"value":885}," (AWS\u002FAzure metadata), ",{"type":42,"tag":62,"props":887,"children":889},{"className":888},[],[890],{"type":47,"value":891},"metadata.google.internal",{"type":47,"value":893}," (GCP), ",{"type":42,"tag":62,"props":895,"children":897},{"className":896},[],[898],{"type":47,"value":899},"127.0.0.0\u002F8",{"type":47,"value":133},{"type":42,"tag":62,"props":902,"children":904},{"className":903},[],[905],{"type":47,"value":906},"10.0.0.0\u002F8",{"type":47,"value":133},{"type":42,"tag":62,"props":909,"children":911},{"className":910},[],[912],{"type":47,"value":913},"172.16.0.0\u002F12",{"type":47,"value":133},{"type":42,"tag":62,"props":916,"children":918},{"className":917},[],[919],{"type":47,"value":920},"192.168.0.0\u002F16",{"type":47,"value":133},{"type":42,"tag":62,"props":923,"children":925},{"className":924},[],[926],{"type":47,"value":927},"169.254.0.0\u002F16",{"type":47,"value":929},". Real: Capital One 2019, Exchange CVE-2021-26855, Ivanti CVE-2024-21893, Shopify H1 #341876.",{"type":42,"tag":246,"props":931,"children":933},{"id":932},"path-traversal-zip-slip",[934],{"type":47,"value":935},"Path traversal \u002F zip-slip",{"type":42,"tag":85,"props":937,"children":938},{},[939,950,969,994,1044,1056],{"type":42,"tag":89,"props":940,"children":941},{},[942,948],{"type":42,"tag":62,"props":943,"children":945},{"className":944},[],[946],{"type":47,"value":947},"send_file(os.path.join(base, user_name))",{"type":47,"value":949}," without realpath containment.",{"type":42,"tag":89,"props":951,"children":952},{},[953,959,961,967],{"type":42,"tag":62,"props":954,"children":956},{"className":955},[],[957],{"type":47,"value":958},"res.sendFile(path.join(root, req.query.x))",{"type":47,"value":960}," without ",{"type":42,"tag":62,"props":962,"children":964},{"className":963},[],[965],{"type":47,"value":966},"startsWith(root)",{"type":47,"value":968}," check.",{"type":42,"tag":89,"props":970,"children":971},{},[972,978,979,985,986,992],{"type":42,"tag":62,"props":973,"children":975},{"className":974},[],[976],{"type":47,"value":977},"open(user_path)",{"type":47,"value":133},{"type":42,"tag":62,"props":980,"children":982},{"className":981},[],[983],{"type":47,"value":984},"fs.readFile(user_path)",{"type":47,"value":133},{"type":42,"tag":62,"props":987,"children":989},{"className":988},[],[990],{"type":47,"value":991},"fopen($user_path)",{"type":47,"value":993}," without validation.",{"type":42,"tag":89,"props":995,"children":996},{},[997,999,1005,1006,1012,1014,1020,1022,1028,1029,1035,1036,1042],{"type":47,"value":998},"Archive extraction: ",{"type":42,"tag":62,"props":1000,"children":1002},{"className":1001},[],[1003],{"type":47,"value":1004},"tarfile.extractall",{"type":47,"value":960},{"type":42,"tag":62,"props":1007,"children":1009},{"className":1008},[],[1010],{"type":47,"value":1011},"filter=\"data\"",{"type":47,"value":1013}," (CVE-2007-4559 and offspring), ",{"type":42,"tag":62,"props":1015,"children":1017},{"className":1016},[],[1018],{"type":47,"value":1019},"zipfile.extractall",{"type":47,"value":1021}," on untrusted archives without per-entry validation, ",{"type":42,"tag":62,"props":1023,"children":1025},{"className":1024},[],[1026],{"type":47,"value":1027},"jszip",{"type":47,"value":310},{"type":42,"tag":62,"props":1030,"children":1032},{"className":1031},[],[1033],{"type":47,"value":1034},"adm-zip",{"type":47,"value":310},{"type":42,"tag":62,"props":1037,"children":1039},{"className":1038},[],[1040],{"type":47,"value":1041},"node-tar",{"type":47,"value":1043}," without containment check.",{"type":42,"tag":89,"props":1045,"children":1046},{},[1047,1049,1055],{"type":47,"value":1048},"Static serving with a non-literal root (",{"type":42,"tag":62,"props":1050,"children":1052},{"className":1051},[],[1053],{"type":47,"value":1054},"express.static(variable)",{"type":47,"value":862},{"type":42,"tag":89,"props":1057,"children":1058},{},[1059,1061,1067],{"type":47,"value":1060},"Uploads where filename is used in the storage path without ",{"type":42,"tag":62,"props":1062,"children":1064},{"className":1063},[],[1065],{"type":47,"value":1066},"basename",{"type":47,"value":1068}," \u002F UUID replacement.",{"type":42,"tag":43,"props":1070,"children":1071},{},[1072],{"type":47,"value":1073},"Real: tarfile CVE-2007-4559, jszip CVE-2022-48285, node-static CVE-2023-26111.",{"type":42,"tag":246,"props":1075,"children":1077},{"id":1076},"sql-nosql-injection-bulk-exfil-angle",[1078],{"type":47,"value":1079},"SQL \u002F NoSQL injection (bulk exfil angle)",{"type":42,"tag":85,"props":1081,"children":1082},{},[1083,1117,1137,1164,1183,1203],{"type":42,"tag":89,"props":1084,"children":1085},{},[1086,1088,1094,1095,1101,1102,1108,1109,1115],{"type":47,"value":1087},"Django ",{"type":42,"tag":62,"props":1089,"children":1091},{"className":1090},[],[1092],{"type":47,"value":1093},".raw(f\"...\")",{"type":47,"value":133},{"type":42,"tag":62,"props":1096,"children":1098},{"className":1097},[],[1099],{"type":47,"value":1100},".extra(where=[f\"...\"])",{"type":47,"value":133},{"type":42,"tag":62,"props":1103,"children":1105},{"className":1104},[],[1106],{"type":47,"value":1107},"RawSQL(f\"...\")",{"type":47,"value":133},{"type":42,"tag":62,"props":1110,"children":1112},{"className":1111},[],[1113],{"type":47,"value":1114},"cursor.execute(f\"...\")",{"type":47,"value":1116}," with user interpolation.",{"type":42,"tag":89,"props":1118,"children":1119},{},[1120,1122,1128,1129,1135],{"type":47,"value":1121},"SQLAlchemy ",{"type":42,"tag":62,"props":1123,"children":1125},{"className":1124},[],[1126],{"type":47,"value":1127},"text(f\"...\")",{"type":47,"value":133},{"type":42,"tag":62,"props":1130,"children":1132},{"className":1131},[],[1133],{"type":47,"value":1134},"session.execute(f\"...\")",{"type":47,"value":1136},".",{"type":42,"tag":89,"props":1138,"children":1139},{},[1140,1142,1147,1149,1155,1157,1163],{"type":47,"value":1141},"Sequelize ",{"type":42,"tag":62,"props":1143,"children":1145},{"className":1144},[],[1146],{"type":47,"value":182},{"type":47,"value":1148}," with user data (CVE-2023-25813), ",{"type":42,"tag":62,"props":1150,"children":1152},{"className":1151},[],[1153],{"type":47,"value":1154},"sequelize.query(",{"type":47,"value":1156},"...${user}...",{"type":42,"tag":62,"props":1158,"children":1160},{"className":1159},[],[1161],{"type":47,"value":1162},")",{"type":47,"value":1136},{"type":42,"tag":89,"props":1165,"children":1166},{},[1167,1169,1174,1175,1181],{"type":47,"value":1168},"Prisma ",{"type":42,"tag":62,"props":1170,"children":1172},{"className":1171},[],[1173],{"type":47,"value":174},{"type":47,"value":310},{"type":42,"tag":62,"props":1176,"children":1178},{"className":1177},[],[1179],{"type":47,"value":1180},"$executeRawUnsafe",{"type":47,"value":1182}," with user data.",{"type":42,"tag":89,"props":1184,"children":1185},{},[1186,1188,1194,1196,1201],{"type":47,"value":1187},"Mongoose ",{"type":42,"tag":62,"props":1189,"children":1191},{"className":1190},[],[1192],{"type":47,"value":1193},"populate({match: userObj})",{"type":47,"value":1195}," (CVE-2025-23061), unsanitized request-body objects as Mongo filters, ",{"type":42,"tag":62,"props":1197,"children":1199},{"className":1198},[],[1200],{"type":47,"value":377},{"type":47,"value":1202}," with user string.",{"type":42,"tag":89,"props":1204,"children":1205},{},[1206,1208,1214],{"type":47,"value":1207},"Postgres JSON-operator splicing: ",{"type":42,"tag":62,"props":1209,"children":1211},{"className":1210},[],[1212],{"type":47,"value":1213},"SELECT data -> '${userKey}' FROM ...",{"type":47,"value":1136},{"type":42,"tag":43,"props":1216,"children":1217},{},[1218],{"type":47,"value":1219},"Authorization bypass via SQL, such as returning another user's row, is out of scope unless injection itself is the enabler.",{"type":42,"tag":246,"props":1221,"children":1223},{"id":1222},"xxe-file-read-and-ssrf-angle",[1224],{"type":47,"value":1225},"XXE (file-read and SSRF angle)",{"type":42,"tag":85,"props":1227,"children":1228},{},[1229,1255,1280,1299,1319,1352],{"type":42,"tag":89,"props":1230,"children":1231},{},[1232,1234,1239,1240,1246,1247,1253],{"type":47,"value":1233},"Python stdlib ",{"type":42,"tag":62,"props":1235,"children":1237},{"className":1236},[],[1238],{"type":47,"value":407},{"type":47,"value":133},{"type":42,"tag":62,"props":1241,"children":1243},{"className":1242},[],[1244],{"type":47,"value":1245},"xml.sax",{"type":47,"value":133},{"type":42,"tag":62,"props":1248,"children":1250},{"className":1249},[],[1251],{"type":47,"value":1252},"xml.dom.minidom",{"type":47,"value":1254}," on untrusted XML (defaults resolve entities).",{"type":42,"tag":89,"props":1256,"children":1257},{},[1258,1264,1265,1271,1272,1278],{"type":42,"tag":62,"props":1259,"children":1261},{"className":1260},[],[1262],{"type":47,"value":1263},"lxml.etree.fromstring(user_xml)",{"type":47,"value":960},{"type":42,"tag":62,"props":1266,"children":1268},{"className":1267},[],[1269],{"type":47,"value":1270},"resolve_entities=False",{"type":47,"value":310},{"type":42,"tag":62,"props":1273,"children":1275},{"className":1274},[],[1276],{"type":47,"value":1277},"no_network=True",{"type":47,"value":1279}," (CVE-2024-6508 family).",{"type":42,"tag":89,"props":1281,"children":1282},{},[1283,1285,1290,1291,1297],{"type":47,"value":1284},"Java ",{"type":42,"tag":62,"props":1286,"children":1288},{"className":1287},[],[1289],{"type":47,"value":414},{"type":47,"value":960},{"type":42,"tag":62,"props":1292,"children":1294},{"className":1293},[],[1295],{"type":47,"value":1296},"disallow-doctype-decl",{"type":47,"value":1298}," and the four companion feature flags.",{"type":42,"tag":89,"props":1300,"children":1301},{},[1302,1304,1310,1311,1317],{"type":47,"value":1303},"Node ",{"type":42,"tag":62,"props":1305,"children":1307},{"className":1306},[],[1308],{"type":47,"value":1309},"libxmljs",{"type":47,"value":836},{"type":42,"tag":62,"props":1312,"children":1314},{"className":1313},[],[1315],{"type":47,"value":1316},"{ noent: true }",{"type":47,"value":1318}," on user XML.",{"type":42,"tag":89,"props":1320,"children":1321},{},[1322,1324,1330,1331,1337,1338,1344,1345,1351],{"type":47,"value":1323},".NET ",{"type":42,"tag":62,"props":1325,"children":1327},{"className":1326},[],[1328],{"type":47,"value":1329},"XmlDocument",{"type":47,"value":960},{"type":42,"tag":62,"props":1332,"children":1334},{"className":1333},[],[1335],{"type":47,"value":1336},"XmlResolver = null",{"type":47,"value":133},{"type":42,"tag":62,"props":1339,"children":1341},{"className":1340},[],[1342],{"type":47,"value":1343},"XmlReader",{"type":47,"value":960},{"type":42,"tag":62,"props":1346,"children":1348},{"className":1347},[],[1349],{"type":47,"value":1350},"DtdProcessing = Prohibit",{"type":47,"value":1136},{"type":42,"tag":89,"props":1353,"children":1354},{},[1355],{"type":47,"value":1356},"SAML \u002F OOXML \u002F SOAP parsers that wrap an unsafe XML stage.",{"type":42,"tag":246,"props":1358,"children":1360},{"id":1359},"response-log-and-export-leakage",[1361],{"type":47,"value":1362},"Response, log, and export leakage",{"type":42,"tag":85,"props":1364,"children":1365},{},[1366,1387,1407,1420,1433,1446,1466,1494,1512,1546,1551],{"type":42,"tag":89,"props":1367,"children":1368},{},[1369,1371,1377,1379,1385],{"type":47,"value":1370},"Pydantic response model with ",{"type":42,"tag":62,"props":1372,"children":1374},{"className":1373},[],[1375],{"type":47,"value":1376},"Config.extra = \"allow\"",{"type":47,"value":1378}," (Sentry ",{"type":42,"tag":62,"props":1380,"children":1382},{"className":1381},[],[1383],{"type":47,"value":1384},"0c0aae90ac1",{"type":47,"value":1386}," was this).",{"type":42,"tag":89,"props":1388,"children":1389},{},[1390,1392,1398,1399,1405],{"type":47,"value":1391},"DRF ",{"type":42,"tag":62,"props":1393,"children":1395},{"className":1394},[],[1396],{"type":47,"value":1397},"ModelSerializer",{"type":47,"value":836},{"type":42,"tag":62,"props":1400,"children":1402},{"className":1401},[],[1403],{"type":47,"value":1404},"fields = '__all__'",{"type":47,"value":1406}," exposing password hashes, API tokens, internal flags via future migrations.",{"type":42,"tag":89,"props":1408,"children":1409},{},[1410,1412,1418],{"type":47,"value":1411},"FastAPI endpoint missing ",{"type":42,"tag":62,"props":1413,"children":1415},{"className":1414},[],[1416],{"type":47,"value":1417},"response_model",{"type":47,"value":1419}," — raw ORM row shipped to client.",{"type":42,"tag":89,"props":1421,"children":1422},{},[1423,1425,1431],{"type":47,"value":1424},"Prisma \u002F Sequelize \u002F Mongoose queries returning full rows without ",{"type":42,"tag":62,"props":1426,"children":1428},{"className":1427},[],[1429],{"type":47,"value":1430},"select",{"type":47,"value":1432}," or DTO filtering.",{"type":42,"tag":89,"props":1434,"children":1435},{},[1436,1438,1444],{"type":47,"value":1437},"GraphQL introspection enabled in production. Apollo ",{"type":42,"tag":62,"props":1439,"children":1441},{"className":1440},[],[1442],{"type":47,"value":1443},"debug: true",{"type":47,"value":1445}," in production.",{"type":42,"tag":89,"props":1447,"children":1448},{},[1449,1451,1457,1459,1464],{"type":47,"value":1450},"Flask ",{"type":42,"tag":62,"props":1452,"children":1454},{"className":1453},[],[1455],{"type":47,"value":1456},"DEBUG = True",{"type":47,"value":1458}," \u002F Django ",{"type":42,"tag":62,"props":1460,"children":1462},{"className":1461},[],[1463],{"type":47,"value":1456},{"type":47,"value":1465}," \u002F Werkzeug debugger in production.",{"type":42,"tag":89,"props":1467,"children":1468},{},[1469,1471,1477,1478,1484,1486,1492],{"type":47,"value":1470},"Error handlers returning ",{"type":42,"tag":62,"props":1472,"children":1474},{"className":1473},[],[1475],{"type":47,"value":1476},"err.stack",{"type":47,"value":133},{"type":42,"tag":62,"props":1479,"children":1481},{"className":1480},[],[1482],{"type":47,"value":1483},"err.message",{"type":47,"value":1485}," with SQL fragments or internal paths, ",{"type":42,"tag":62,"props":1487,"children":1489},{"className":1488},[],[1490],{"type":47,"value":1491},"traceback.format_exc()",{"type":47,"value":1493}," in response bodies.",{"type":42,"tag":89,"props":1495,"children":1496},{},[1497,1499,1504,1505,1510],{"type":47,"value":1498},"Loggers capturing ",{"type":42,"tag":62,"props":1500,"children":1502},{"className":1501},[],[1503],{"type":47,"value":131},{"type":47,"value":133},{"type":42,"tag":62,"props":1506,"children":1508},{"className":1507},[],[1509],{"type":47,"value":146},{"type":47,"value":1511},", payload objects wholesale.",{"type":42,"tag":89,"props":1513,"children":1514},{},[1515,1517,1523,1524,1530,1531,1537,1538,1544],{"type":47,"value":1516},"CSV exports without formula-prefix escape (",{"type":42,"tag":62,"props":1518,"children":1520},{"className":1519},[],[1521],{"type":47,"value":1522},"=",{"type":47,"value":133},{"type":42,"tag":62,"props":1525,"children":1527},{"className":1526},[],[1528],{"type":47,"value":1529},"+",{"type":47,"value":133},{"type":42,"tag":62,"props":1532,"children":1534},{"className":1533},[],[1535],{"type":47,"value":1536},"-",{"type":47,"value":133},{"type":42,"tag":62,"props":1539,"children":1541},{"className":1540},[],[1542],{"type":47,"value":1543},"@",{"type":47,"value":1545},", tab, CR). Real: Tendenci #919.",{"type":42,"tag":89,"props":1547,"children":1548},{},[1549],{"type":47,"value":1550},"Tarball \u002F JSON exports bundling cross-resource data without per-resource authorization re-verification.",{"type":42,"tag":89,"props":1552,"children":1553},{},[1554],{"type":47,"value":1555},"Download links with long expiry and no single-use enforcement.",{"type":42,"tag":73,"props":1557,"children":1559},{"id":1558},"what-not-to-report",[1560],{"type":47,"value":1561},"What NOT to Report",{"type":42,"tag":85,"props":1563,"children":1564},{},[1565,1575,1585,1618,1635],{"type":42,"tag":89,"props":1566,"children":1567},{},[1568,1573],{"type":42,"tag":93,"props":1569,"children":1570},{},[1571],{"type":47,"value":1572},"Code execution",{"type":47,"value":1574}," (command injection, deserialization RCE, SSTI, eval, prototype-pollution reaching code sink).",{"type":42,"tag":89,"props":1576,"children":1577},{},[1578,1583],{"type":42,"tag":93,"props":1579,"children":1580},{},[1581],{"type":47,"value":1582},"Authorization",{"type":47,"value":1584}," (IDOR via straightforward missing scoping, tenant or role boundary failures). Flag here only when a bulk-exfil primitive, such as a mass query or enumeration via IDOR, is enabled.",{"type":42,"tag":89,"props":1586,"children":1587},{},[1588,1593,1594,1599,1600,1605,1606,1611,1612,1617],{"type":42,"tag":93,"props":1589,"children":1590},{},[1591],{"type":47,"value":1592},"XSS",{"type":47,"value":133},{"type":42,"tag":93,"props":1595,"children":1596},{},[1597],{"type":47,"value":1598},"CSRF",{"type":47,"value":133},{"type":42,"tag":93,"props":1601,"children":1602},{},[1603],{"type":47,"value":1604},"crypto primitive misuse",{"type":47,"value":133},{"type":42,"tag":93,"props":1607,"children":1608},{},[1609],{"type":47,"value":1610},"secrets hard-coded in source",{"type":47,"value":133},{"type":42,"tag":93,"props":1613,"children":1614},{},[1615],{"type":47,"value":1616},"transport security",{"type":47,"value":1136},{"type":42,"tag":89,"props":1619,"children":1620},{},[1621,1626,1628,1633],{"type":42,"tag":93,"props":1622,"children":1623},{},[1624],{"type":47,"value":1625},"DoS \u002F ReDoS",{"type":47,"value":1627}," unless it produces a data-exfil primitive (timing-based NoSQL ",{"type":42,"tag":62,"props":1629,"children":1631},{"className":1630},[],[1632],{"type":47,"value":377},{"type":47,"value":1634}," oracle).",{"type":42,"tag":89,"props":1636,"children":1637},{},[1638,1643],{"type":42,"tag":93,"props":1639,"children":1640},{},[1641],{"type":47,"value":1642},"Dependency CVEs",{"type":47,"value":1644}," as a class.",{"type":42,"tag":73,"props":1646,"children":1648},{"id":1647},"false-positive-traps",[1649],{"type":47,"value":1650},"False-Positive Traps",{"type":42,"tag":1652,"props":1653,"children":1654},"ol",{},[1655,1665,1683,1711,1735,1749,1779,1793,1816,1832,1853,1869],{"type":42,"tag":89,"props":1656,"children":1657},{},[1658,1663],{"type":42,"tag":93,"props":1659,"children":1660},{},[1661],{"type":47,"value":1662},"Fetches to a hardcoded URL constant",{"type":47,"value":1664}," are not SSRF.",{"type":42,"tag":89,"props":1666,"children":1667},{},[1668,1673,1675,1681],{"type":42,"tag":93,"props":1669,"children":1670},{},[1671],{"type":47,"value":1672},"Fetches to a literal allowlist",{"type":47,"value":1674}," (",{"type":42,"tag":62,"props":1676,"children":1678},{"className":1677},[],[1679],{"type":47,"value":1680},"if host in ALLOWED_HOSTS:",{"type":47,"value":1682},") with exact-hostname match are not SSRF. Substring match is.",{"type":42,"tag":89,"props":1684,"children":1685},{},[1686,1695,1696,1702,1703,1709],{"type":42,"tag":93,"props":1687,"children":1688},{},[1689],{"type":42,"tag":62,"props":1690,"children":1692},{"className":1691},[],[1693],{"type":47,"value":1694},"yaml.safe_load",{"type":47,"value":133},{"type":42,"tag":62,"props":1697,"children":1699},{"className":1698},[],[1700],{"type":47,"value":1701},"JSON.parse",{"type":47,"value":133},{"type":42,"tag":62,"props":1704,"children":1706},{"className":1705},[],[1707],{"type":47,"value":1708},"json.loads",{"type":47,"value":1710}," are not deserialization RCE — and not exfil either unless downstream.",{"type":42,"tag":89,"props":1712,"children":1713},{},[1714,1725,1727,1733],{"type":42,"tag":93,"props":1715,"children":1716},{},[1717,1723],{"type":42,"tag":62,"props":1718,"children":1720},{"className":1719},[],[1721],{"type":47,"value":1722},"send_from_directory",{"type":47,"value":1724}," (Flask)",{"type":47,"value":1726}," applies ",{"type":42,"tag":62,"props":1728,"children":1730},{"className":1729},[],[1731],{"type":47,"value":1732},"safe_join",{"type":47,"value":1734},". Generally safe.",{"type":42,"tag":89,"props":1736,"children":1737},{},[1738,1747],{"type":42,"tag":93,"props":1739,"children":1740},{},[1741],{"type":42,"tag":62,"props":1742,"children":1744},{"className":1743},[],[1745],{"type":47,"value":1746},"express.static('public')",{"type":47,"value":1748}," with a literal root is safe.",{"type":42,"tag":89,"props":1750,"children":1751},{},[1752,1761,1763,1769,1771,1777],{"type":42,"tag":93,"props":1753,"children":1754},{},[1755],{"type":42,"tag":62,"props":1756,"children":1758},{"className":1757},[],[1759],{"type":47,"value":1760},"res.sendFile(name, { root })",{"type":47,"value":1762}," with a literal root and user ",{"type":42,"tag":62,"props":1764,"children":1766},{"className":1765},[],[1767],{"type":47,"value":1768},"name",{"type":47,"value":1770}," benefits from Express-level ",{"type":42,"tag":62,"props":1772,"children":1774},{"className":1773},[],[1775],{"type":47,"value":1776},"..",{"type":47,"value":1778}," rejection; still audit.",{"type":42,"tag":89,"props":1780,"children":1781},{},[1782,1791],{"type":42,"tag":93,"props":1783,"children":1784},{},[1785],{"type":42,"tag":62,"props":1786,"children":1788},{"className":1787},[],[1789],{"type":47,"value":1790},"response_model=SomeModel",{"type":47,"value":1792}," (FastAPI) is a defense.",{"type":42,"tag":89,"props":1794,"children":1795},{},[1796,1814],{"type":42,"tag":93,"props":1797,"children":1798},{},[1799,1800,1806,1808],{"type":47,"value":1391},{"type":42,"tag":62,"props":1801,"children":1803},{"className":1802},[],[1804],{"type":47,"value":1805},"ModelSerializer fields = '__all__'",{"type":47,"value":1807}," on a ",{"type":42,"tag":62,"props":1809,"children":1811},{"className":1810},[],[1812],{"type":47,"value":1813},"ReadOnlyModelViewSet",{"type":47,"value":1815}," is over-exposure but not mass-assignment.",{"type":42,"tag":89,"props":1817,"children":1818},{},[1819,1830],{"type":42,"tag":93,"props":1820,"children":1821},{},[1822,1824],{"type":47,"value":1823},"Error handler returning ",{"type":42,"tag":62,"props":1825,"children":1827},{"className":1826},[],[1828],{"type":47,"value":1829},"{\"error\": \"internal\"}",{"type":47,"value":1831}," with separate server-side log is the safe shape.",{"type":42,"tag":89,"props":1833,"children":1834},{},[1835,1851],{"type":42,"tag":93,"props":1836,"children":1837},{},[1838,1840,1845,1846],{"type":47,"value":1839},"Sentry callers that go through ",{"type":42,"tag":62,"props":1841,"children":1843},{"className":1842},[],[1844],{"type":47,"value":489},{"type":47,"value":310},{"type":42,"tag":62,"props":1847,"children":1849},{"className":1848},[],[1850],{"type":47,"value":496},{"type":47,"value":1852}," already pass through the IP check chain.",{"type":42,"tag":89,"props":1854,"children":1855},{},[1856,1867],{"type":42,"tag":93,"props":1857,"children":1858},{},[1859,1861],{"type":47,"value":1860},"Prisma tagged-template ",{"type":42,"tag":62,"props":1862,"children":1864},{"className":1863},[],[1865],{"type":47,"value":1866},"$queryRaw",{"type":47,"value":1868}," parameterizes automatically.",{"type":42,"tag":89,"props":1870,"children":1871},{},[1872,1877,1878,1884],{"type":42,"tag":93,"props":1873,"children":1874},{},[1875],{"type":47,"value":1876},"Principal-derived IDs",{"type":47,"value":1674},{"type":42,"tag":62,"props":1879,"children":1881},{"className":1880},[],[1882],{"type":47,"value":1883},"WHERE user_id = request.user.id",{"type":47,"value":1885},") are not IDOR; they are an authorization concern, not exfil.",{"type":42,"tag":73,"props":1887,"children":1889},{"id":1888},"canonical-patterns",[1890],{"type":47,"value":1891},"Canonical Patterns",{"type":42,"tag":246,"props":1893,"children":1895},{"id":1894},"pattern-ssrf-to-cloud-metadata",[1896],{"type":47,"value":1897},"Pattern: SSRF to cloud metadata",{"type":42,"tag":43,"props":1899,"children":1900},{},[1901],{"type":47,"value":1902},"Real: Capital One 2019, Next.js CVE-2024-34351.",{"type":42,"tag":43,"props":1904,"children":1905},{},[1906],{"type":42,"tag":93,"props":1907,"children":1908},{},[1909],{"type":47,"value":1910},"Python - bad:",{"type":42,"tag":55,"props":1912,"children":1916},{"className":1913,"code":1914,"language":1915,"meta":64,"style":64},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","resp = requests.get(user_url, allow_redirects=True)\n","python",[1917],{"type":42,"tag":62,"props":1918,"children":1919},{"__ignoreMap":64},[1920],{"type":42,"tag":1921,"props":1922,"children":1925},"span",{"class":1923,"line":1924},"line",1,[1926],{"type":42,"tag":1921,"props":1927,"children":1928},{},[1929],{"type":47,"value":1914},{"type":42,"tag":43,"props":1931,"children":1932},{},[1933],{"type":42,"tag":93,"props":1934,"children":1935},{},[1936],{"type":47,"value":1937},"Python - safe (Sentry-style):",{"type":42,"tag":55,"props":1939,"children":1941},{"className":1913,"code":1940,"language":1915,"meta":64,"style":64},"from sentry.http import safe_urlopen\nresp = safe_urlopen(user_url, allow_redirects=False)\n",[1942],{"type":42,"tag":62,"props":1943,"children":1944},{"__ignoreMap":64},[1945,1953],{"type":42,"tag":1921,"props":1946,"children":1947},{"class":1923,"line":1924},[1948],{"type":42,"tag":1921,"props":1949,"children":1950},{},[1951],{"type":47,"value":1952},"from sentry.http import safe_urlopen\n",{"type":42,"tag":1921,"props":1954,"children":1956},{"class":1923,"line":1955},2,[1957],{"type":42,"tag":1921,"props":1958,"children":1959},{},[1960],{"type":47,"value":1961},"resp = safe_urlopen(user_url, allow_redirects=False)\n",{"type":42,"tag":43,"props":1963,"children":1964},{},[1965],{"type":42,"tag":93,"props":1966,"children":1967},{},[1968],{"type":47,"value":1969},"TypeScript - bad:",{"type":42,"tag":55,"props":1971,"children":1975},{"className":1972,"code":1973,"language":1974,"meta":64,"style":64},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const resp = await fetch(userUrl);\nconst resp = await axios.get(userUrl);   \u002F\u002F Historical redirect-bypass CVE-2020-28168.\n","ts",[1976],{"type":42,"tag":62,"props":1977,"children":1978},{"__ignoreMap":64},[1979,2021],{"type":42,"tag":1921,"props":1980,"children":1981},{"class":1923,"line":1924},[1982,1988,1994,1999,2005,2011,2016],{"type":42,"tag":1921,"props":1983,"children":1985},{"style":1984},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[1986],{"type":47,"value":1987},"const",{"type":42,"tag":1921,"props":1989,"children":1991},{"style":1990},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[1992],{"type":47,"value":1993}," resp ",{"type":42,"tag":1921,"props":1995,"children":1997},{"style":1996},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[1998],{"type":47,"value":1522},{"type":42,"tag":1921,"props":2000,"children":2002},{"style":2001},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[2003],{"type":47,"value":2004}," await",{"type":42,"tag":1921,"props":2006,"children":2008},{"style":2007},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[2009],{"type":47,"value":2010}," fetch",{"type":42,"tag":1921,"props":2012,"children":2013},{"style":1990},[2014],{"type":47,"value":2015},"(userUrl)",{"type":42,"tag":1921,"props":2017,"children":2018},{"style":1996},[2019],{"type":47,"value":2020},";\n",{"type":42,"tag":1921,"props":2022,"children":2023},{"class":1923,"line":1955},[2024,2028,2032,2036,2040,2045,2049,2054,2058,2063],{"type":42,"tag":1921,"props":2025,"children":2026},{"style":1984},[2027],{"type":47,"value":1987},{"type":42,"tag":1921,"props":2029,"children":2030},{"style":1990},[2031],{"type":47,"value":1993},{"type":42,"tag":1921,"props":2033,"children":2034},{"style":1996},[2035],{"type":47,"value":1522},{"type":42,"tag":1921,"props":2037,"children":2038},{"style":2001},[2039],{"type":47,"value":2004},{"type":42,"tag":1921,"props":2041,"children":2042},{"style":1990},[2043],{"type":47,"value":2044}," axios",{"type":42,"tag":1921,"props":2046,"children":2047},{"style":1996},[2048],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2050,"children":2051},{"style":2007},[2052],{"type":47,"value":2053},"get",{"type":42,"tag":1921,"props":2055,"children":2056},{"style":1990},[2057],{"type":47,"value":2015},{"type":42,"tag":1921,"props":2059,"children":2060},{"style":1996},[2061],{"type":47,"value":2062},";",{"type":42,"tag":1921,"props":2064,"children":2066},{"style":2065},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[2067],{"type":47,"value":2068},"   \u002F\u002F Historical redirect-bypass CVE-2020-28168.\n",{"type":42,"tag":43,"props":2070,"children":2071},{},[2072],{"type":42,"tag":93,"props":2073,"children":2074},{},[2075],{"type":47,"value":2076},"TypeScript - safe:",{"type":42,"tag":55,"props":2078,"children":2080},{"className":1972,"code":2079,"language":1974,"meta":64,"style":64},"const parsed = new URL(userUrl);\nif (!ALLOWED_HOSTS.has(parsed.hostname)) throw new Error('disallowed');\nconst { address } = await lookup(parsed.hostname);\nconst ip = ipaddr.parse(address);\nif (['private','linkLocal','loopback','uniqueLocal','unspecified'].includes(ip.range())) {\n  throw new Error('disallowed ip');\n}\nconst resp = await fetch(parsed, { redirect: 'manual' });\n",[2081],{"type":42,"tag":62,"props":2082,"children":2083},{"__ignoreMap":64},[2084,2118,2205,2258,2298,2431,2474,2483],{"type":42,"tag":1921,"props":2085,"children":2086},{"class":1923,"line":1924},[2087,2091,2096,2100,2105,2110,2114],{"type":42,"tag":1921,"props":2088,"children":2089},{"style":1984},[2090],{"type":47,"value":1987},{"type":42,"tag":1921,"props":2092,"children":2093},{"style":1990},[2094],{"type":47,"value":2095}," parsed ",{"type":42,"tag":1921,"props":2097,"children":2098},{"style":1996},[2099],{"type":47,"value":1522},{"type":42,"tag":1921,"props":2101,"children":2102},{"style":1996},[2103],{"type":47,"value":2104}," new",{"type":42,"tag":1921,"props":2106,"children":2107},{"style":2007},[2108],{"type":47,"value":2109}," URL",{"type":42,"tag":1921,"props":2111,"children":2112},{"style":1990},[2113],{"type":47,"value":2015},{"type":42,"tag":1921,"props":2115,"children":2116},{"style":1996},[2117],{"type":47,"value":2020},{"type":42,"tag":1921,"props":2119,"children":2120},{"class":1923,"line":1955},[2121,2126,2130,2135,2140,2144,2149,2154,2158,2163,2168,2172,2177,2182,2187,2193,2197,2201],{"type":42,"tag":1921,"props":2122,"children":2123},{"style":2001},[2124],{"type":47,"value":2125},"if",{"type":42,"tag":1921,"props":2127,"children":2128},{"style":1990},[2129],{"type":47,"value":1674},{"type":42,"tag":1921,"props":2131,"children":2132},{"style":1996},[2133],{"type":47,"value":2134},"!",{"type":42,"tag":1921,"props":2136,"children":2137},{"style":1990},[2138],{"type":47,"value":2139},"ALLOWED_HOSTS",{"type":42,"tag":1921,"props":2141,"children":2142},{"style":1996},[2143],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2145,"children":2146},{"style":2007},[2147],{"type":47,"value":2148},"has",{"type":42,"tag":1921,"props":2150,"children":2151},{"style":1990},[2152],{"type":47,"value":2153},"(parsed",{"type":42,"tag":1921,"props":2155,"children":2156},{"style":1996},[2157],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2159,"children":2160},{"style":1990},[2161],{"type":47,"value":2162},"hostname)) ",{"type":42,"tag":1921,"props":2164,"children":2165},{"style":2001},[2166],{"type":47,"value":2167},"throw",{"type":42,"tag":1921,"props":2169,"children":2170},{"style":1996},[2171],{"type":47,"value":2104},{"type":42,"tag":1921,"props":2173,"children":2174},{"style":2007},[2175],{"type":47,"value":2176}," Error",{"type":42,"tag":1921,"props":2178,"children":2179},{"style":1990},[2180],{"type":47,"value":2181},"(",{"type":42,"tag":1921,"props":2183,"children":2184},{"style":1996},[2185],{"type":47,"value":2186},"'",{"type":42,"tag":1921,"props":2188,"children":2190},{"style":2189},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[2191],{"type":47,"value":2192},"disallowed",{"type":42,"tag":1921,"props":2194,"children":2195},{"style":1996},[2196],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2198,"children":2199},{"style":1990},[2200],{"type":47,"value":1162},{"type":42,"tag":1921,"props":2202,"children":2203},{"style":1996},[2204],{"type":47,"value":2020},{"type":42,"tag":1921,"props":2206,"children":2207},{"class":1923,"line":28},[2208,2212,2217,2222,2227,2232,2236,2241,2245,2249,2254],{"type":42,"tag":1921,"props":2209,"children":2210},{"style":1984},[2211],{"type":47,"value":1987},{"type":42,"tag":1921,"props":2213,"children":2214},{"style":1996},[2215],{"type":47,"value":2216}," {",{"type":42,"tag":1921,"props":2218,"children":2219},{"style":1990},[2220],{"type":47,"value":2221}," address ",{"type":42,"tag":1921,"props":2223,"children":2224},{"style":1996},[2225],{"type":47,"value":2226},"}",{"type":42,"tag":1921,"props":2228,"children":2229},{"style":1996},[2230],{"type":47,"value":2231}," =",{"type":42,"tag":1921,"props":2233,"children":2234},{"style":2001},[2235],{"type":47,"value":2004},{"type":42,"tag":1921,"props":2237,"children":2238},{"style":2007},[2239],{"type":47,"value":2240}," lookup",{"type":42,"tag":1921,"props":2242,"children":2243},{"style":1990},[2244],{"type":47,"value":2153},{"type":42,"tag":1921,"props":2246,"children":2247},{"style":1996},[2248],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2250,"children":2251},{"style":1990},[2252],{"type":47,"value":2253},"hostname)",{"type":42,"tag":1921,"props":2255,"children":2256},{"style":1996},[2257],{"type":47,"value":2020},{"type":42,"tag":1921,"props":2259,"children":2261},{"class":1923,"line":2260},4,[2262,2266,2271,2275,2280,2284,2289,2294],{"type":42,"tag":1921,"props":2263,"children":2264},{"style":1984},[2265],{"type":47,"value":1987},{"type":42,"tag":1921,"props":2267,"children":2268},{"style":1990},[2269],{"type":47,"value":2270}," ip ",{"type":42,"tag":1921,"props":2272,"children":2273},{"style":1996},[2274],{"type":47,"value":1522},{"type":42,"tag":1921,"props":2276,"children":2277},{"style":1990},[2278],{"type":47,"value":2279}," ipaddr",{"type":42,"tag":1921,"props":2281,"children":2282},{"style":1996},[2283],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2285,"children":2286},{"style":2007},[2287],{"type":47,"value":2288},"parse",{"type":42,"tag":1921,"props":2290,"children":2291},{"style":1990},[2292],{"type":47,"value":2293},"(address)",{"type":42,"tag":1921,"props":2295,"children":2296},{"style":1996},[2297],{"type":47,"value":2020},{"type":42,"tag":1921,"props":2299,"children":2301},{"class":1923,"line":2300},5,[2302,2306,2311,2315,2320,2324,2329,2333,2338,2342,2346,2350,2355,2359,2363,2367,2372,2376,2380,2384,2389,2393,2398,2402,2407,2412,2416,2421,2426],{"type":42,"tag":1921,"props":2303,"children":2304},{"style":2001},[2305],{"type":47,"value":2125},{"type":42,"tag":1921,"props":2307,"children":2308},{"style":1990},[2309],{"type":47,"value":2310}," ([",{"type":42,"tag":1921,"props":2312,"children":2313},{"style":1996},[2314],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2316,"children":2317},{"style":2189},[2318],{"type":47,"value":2319},"private",{"type":42,"tag":1921,"props":2321,"children":2322},{"style":1996},[2323],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2325,"children":2326},{"style":1996},[2327],{"type":47,"value":2328},",",{"type":42,"tag":1921,"props":2330,"children":2331},{"style":1996},[2332],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2334,"children":2335},{"style":2189},[2336],{"type":47,"value":2337},"linkLocal",{"type":42,"tag":1921,"props":2339,"children":2340},{"style":1996},[2341],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2343,"children":2344},{"style":1996},[2345],{"type":47,"value":2328},{"type":42,"tag":1921,"props":2347,"children":2348},{"style":1996},[2349],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2351,"children":2352},{"style":2189},[2353],{"type":47,"value":2354},"loopback",{"type":42,"tag":1921,"props":2356,"children":2357},{"style":1996},[2358],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2360,"children":2361},{"style":1996},[2362],{"type":47,"value":2328},{"type":42,"tag":1921,"props":2364,"children":2365},{"style":1996},[2366],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2368,"children":2369},{"style":2189},[2370],{"type":47,"value":2371},"uniqueLocal",{"type":42,"tag":1921,"props":2373,"children":2374},{"style":1996},[2375],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2377,"children":2378},{"style":1996},[2379],{"type":47,"value":2328},{"type":42,"tag":1921,"props":2381,"children":2382},{"style":1996},[2383],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2385,"children":2386},{"style":2189},[2387],{"type":47,"value":2388},"unspecified",{"type":42,"tag":1921,"props":2390,"children":2391},{"style":1996},[2392],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2394,"children":2395},{"style":1990},[2396],{"type":47,"value":2397},"]",{"type":42,"tag":1921,"props":2399,"children":2400},{"style":1996},[2401],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2403,"children":2404},{"style":2007},[2405],{"type":47,"value":2406},"includes",{"type":42,"tag":1921,"props":2408,"children":2409},{"style":1990},[2410],{"type":47,"value":2411},"(ip",{"type":42,"tag":1921,"props":2413,"children":2414},{"style":1996},[2415],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2417,"children":2418},{"style":2007},[2419],{"type":47,"value":2420},"range",{"type":42,"tag":1921,"props":2422,"children":2423},{"style":1990},[2424],{"type":47,"value":2425},"())) ",{"type":42,"tag":1921,"props":2427,"children":2428},{"style":1996},[2429],{"type":47,"value":2430},"{\n",{"type":42,"tag":1921,"props":2432,"children":2434},{"class":1923,"line":2433},6,[2435,2440,2444,2448,2453,2457,2462,2466,2470],{"type":42,"tag":1921,"props":2436,"children":2437},{"style":2001},[2438],{"type":47,"value":2439},"  throw",{"type":42,"tag":1921,"props":2441,"children":2442},{"style":1996},[2443],{"type":47,"value":2104},{"type":42,"tag":1921,"props":2445,"children":2446},{"style":2007},[2447],{"type":47,"value":2176},{"type":42,"tag":1921,"props":2449,"children":2451},{"style":2450},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[2452],{"type":47,"value":2181},{"type":42,"tag":1921,"props":2454,"children":2455},{"style":1996},[2456],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2458,"children":2459},{"style":2189},[2460],{"type":47,"value":2461},"disallowed ip",{"type":42,"tag":1921,"props":2463,"children":2464},{"style":1996},[2465],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2467,"children":2468},{"style":2450},[2469],{"type":47,"value":1162},{"type":42,"tag":1921,"props":2471,"children":2472},{"style":1996},[2473],{"type":47,"value":2020},{"type":42,"tag":1921,"props":2475,"children":2477},{"class":1923,"line":2476},7,[2478],{"type":42,"tag":1921,"props":2479,"children":2480},{"style":1996},[2481],{"type":47,"value":2482},"}\n",{"type":42,"tag":1921,"props":2484,"children":2486},{"class":1923,"line":2485},8,[2487,2491,2495,2499,2503,2507,2511,2515,2519,2524,2529,2534,2539,2543,2548,2552],{"type":42,"tag":1921,"props":2488,"children":2489},{"style":1984},[2490],{"type":47,"value":1987},{"type":42,"tag":1921,"props":2492,"children":2493},{"style":1990},[2494],{"type":47,"value":1993},{"type":42,"tag":1921,"props":2496,"children":2497},{"style":1996},[2498],{"type":47,"value":1522},{"type":42,"tag":1921,"props":2500,"children":2501},{"style":2001},[2502],{"type":47,"value":2004},{"type":42,"tag":1921,"props":2504,"children":2505},{"style":2007},[2506],{"type":47,"value":2010},{"type":42,"tag":1921,"props":2508,"children":2509},{"style":1990},[2510],{"type":47,"value":2153},{"type":42,"tag":1921,"props":2512,"children":2513},{"style":1996},[2514],{"type":47,"value":2328},{"type":42,"tag":1921,"props":2516,"children":2517},{"style":1996},[2518],{"type":47,"value":2216},{"type":42,"tag":1921,"props":2520,"children":2521},{"style":2450},[2522],{"type":47,"value":2523}," redirect",{"type":42,"tag":1921,"props":2525,"children":2526},{"style":1996},[2527],{"type":47,"value":2528},":",{"type":42,"tag":1921,"props":2530,"children":2531},{"style":1996},[2532],{"type":47,"value":2533}," '",{"type":42,"tag":1921,"props":2535,"children":2536},{"style":2189},[2537],{"type":47,"value":2538},"manual",{"type":42,"tag":1921,"props":2540,"children":2541},{"style":1996},[2542],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2544,"children":2545},{"style":1996},[2546],{"type":47,"value":2547}," }",{"type":42,"tag":1921,"props":2549,"children":2550},{"style":1990},[2551],{"type":47,"value":1162},{"type":42,"tag":1921,"props":2553,"children":2554},{"style":1996},[2555],{"type":47,"value":2020},{"type":42,"tag":246,"props":2557,"children":2559},{"id":2558},"pattern-path-traversal-in-file-download",[2560],{"type":47,"value":2561},"Pattern: Path traversal in file download",{"type":42,"tag":43,"props":2563,"children":2564},{},[2565],{"type":42,"tag":93,"props":2566,"children":2567},{},[2568],{"type":47,"value":1910},{"type":42,"tag":55,"props":2570,"children":2572},{"className":1913,"code":2571,"language":1915,"meta":64,"style":64},"return send_file(os.path.join(\"\u002Fvar\u002Fapp\u002Fexports\", name))\n",[2573],{"type":42,"tag":62,"props":2574,"children":2575},{"__ignoreMap":64},[2576],{"type":42,"tag":1921,"props":2577,"children":2578},{"class":1923,"line":1924},[2579],{"type":42,"tag":1921,"props":2580,"children":2581},{},[2582],{"type":47,"value":2571},{"type":42,"tag":43,"props":2584,"children":2585},{},[2586],{"type":42,"tag":93,"props":2587,"children":2588},{},[2589],{"type":47,"value":2590},"Python - safe:",{"type":42,"tag":55,"props":2592,"children":2594},{"className":1913,"code":2593,"language":1915,"meta":64,"style":64},"base = Path(\"\u002Fvar\u002Fapp\u002Fexports\").resolve()\ntarget = (base \u002F name).resolve()\nif not target.is_relative_to(base):\n    abort(403)\nreturn send_file(target)\n",[2595],{"type":42,"tag":62,"props":2596,"children":2597},{"__ignoreMap":64},[2598,2606,2614,2622,2630],{"type":42,"tag":1921,"props":2599,"children":2600},{"class":1923,"line":1924},[2601],{"type":42,"tag":1921,"props":2602,"children":2603},{},[2604],{"type":47,"value":2605},"base = Path(\"\u002Fvar\u002Fapp\u002Fexports\").resolve()\n",{"type":42,"tag":1921,"props":2607,"children":2608},{"class":1923,"line":1955},[2609],{"type":42,"tag":1921,"props":2610,"children":2611},{},[2612],{"type":47,"value":2613},"target = (base \u002F name).resolve()\n",{"type":42,"tag":1921,"props":2615,"children":2616},{"class":1923,"line":28},[2617],{"type":42,"tag":1921,"props":2618,"children":2619},{},[2620],{"type":47,"value":2621},"if not target.is_relative_to(base):\n",{"type":42,"tag":1921,"props":2623,"children":2624},{"class":1923,"line":2260},[2625],{"type":42,"tag":1921,"props":2626,"children":2627},{},[2628],{"type":47,"value":2629},"    abort(403)\n",{"type":42,"tag":1921,"props":2631,"children":2632},{"class":1923,"line":2300},[2633],{"type":42,"tag":1921,"props":2634,"children":2635},{},[2636],{"type":47,"value":2637},"return send_file(target)\n",{"type":42,"tag":43,"props":2639,"children":2640},{},[2641],{"type":42,"tag":93,"props":2642,"children":2643},{},[2644],{"type":47,"value":1969},{"type":42,"tag":55,"props":2646,"children":2648},{"className":1972,"code":2647,"language":1974,"meta":64,"style":64},"res.sendFile(path.join('\u002Fvar\u002Fapp\u002Fexports', String(req.query.name)));\n",[2649],{"type":42,"tag":62,"props":2650,"children":2651},{"__ignoreMap":64},[2652],{"type":42,"tag":1921,"props":2653,"children":2654},{"class":1923,"line":1924},[2655,2660,2664,2668,2673,2677,2682,2686,2690,2695,2699,2703,2708,2713,2717,2722,2726,2731],{"type":42,"tag":1921,"props":2656,"children":2657},{"style":1990},[2658],{"type":47,"value":2659},"res",{"type":42,"tag":1921,"props":2661,"children":2662},{"style":1996},[2663],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2665,"children":2666},{"style":2007},[2667],{"type":47,"value":323},{"type":42,"tag":1921,"props":2669,"children":2670},{"style":1990},[2671],{"type":47,"value":2672},"(path",{"type":42,"tag":1921,"props":2674,"children":2675},{"style":1996},[2676],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2678,"children":2679},{"style":2007},[2680],{"type":47,"value":2681},"join",{"type":42,"tag":1921,"props":2683,"children":2684},{"style":1990},[2685],{"type":47,"value":2181},{"type":42,"tag":1921,"props":2687,"children":2688},{"style":1996},[2689],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2691,"children":2692},{"style":2189},[2693],{"type":47,"value":2694},"\u002Fvar\u002Fapp\u002Fexports",{"type":42,"tag":1921,"props":2696,"children":2697},{"style":1996},[2698],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2700,"children":2701},{"style":1996},[2702],{"type":47,"value":2328},{"type":42,"tag":1921,"props":2704,"children":2705},{"style":2007},[2706],{"type":47,"value":2707}," String",{"type":42,"tag":1921,"props":2709,"children":2710},{"style":1990},[2711],{"type":47,"value":2712},"(req",{"type":42,"tag":1921,"props":2714,"children":2715},{"style":1996},[2716],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2718,"children":2719},{"style":1990},[2720],{"type":47,"value":2721},"query",{"type":42,"tag":1921,"props":2723,"children":2724},{"style":1996},[2725],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2727,"children":2728},{"style":1990},[2729],{"type":47,"value":2730},"name)))",{"type":42,"tag":1921,"props":2732,"children":2733},{"style":1996},[2734],{"type":47,"value":2020},{"type":42,"tag":43,"props":2736,"children":2737},{},[2738],{"type":42,"tag":93,"props":2739,"children":2740},{},[2741],{"type":47,"value":2076},{"type":42,"tag":55,"props":2743,"children":2745},{"className":1972,"code":2744,"language":1974,"meta":64,"style":64},"const base = path.resolve('\u002Fvar\u002Fapp\u002Fexports');\nconst target = path.resolve(base, String(req.query.name));\nif (!target.startsWith(base + path.sep)) return res.sendStatus(403);\nres.sendFile(target);\n",[2746],{"type":42,"tag":62,"props":2747,"children":2748},{"__ignoreMap":64},[2749,2803,2869,2957],{"type":42,"tag":1921,"props":2750,"children":2751},{"class":1923,"line":1924},[2752,2756,2761,2765,2770,2774,2779,2783,2787,2791,2795,2799],{"type":42,"tag":1921,"props":2753,"children":2754},{"style":1984},[2755],{"type":47,"value":1987},{"type":42,"tag":1921,"props":2757,"children":2758},{"style":1990},[2759],{"type":47,"value":2760}," base ",{"type":42,"tag":1921,"props":2762,"children":2763},{"style":1996},[2764],{"type":47,"value":1522},{"type":42,"tag":1921,"props":2766,"children":2767},{"style":1990},[2768],{"type":47,"value":2769}," path",{"type":42,"tag":1921,"props":2771,"children":2772},{"style":1996},[2773],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2775,"children":2776},{"style":2007},[2777],{"type":47,"value":2778},"resolve",{"type":42,"tag":1921,"props":2780,"children":2781},{"style":1990},[2782],{"type":47,"value":2181},{"type":42,"tag":1921,"props":2784,"children":2785},{"style":1996},[2786],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2788,"children":2789},{"style":2189},[2790],{"type":47,"value":2694},{"type":42,"tag":1921,"props":2792,"children":2793},{"style":1996},[2794],{"type":47,"value":2186},{"type":42,"tag":1921,"props":2796,"children":2797},{"style":1990},[2798],{"type":47,"value":1162},{"type":42,"tag":1921,"props":2800,"children":2801},{"style":1996},[2802],{"type":47,"value":2020},{"type":42,"tag":1921,"props":2804,"children":2805},{"class":1923,"line":1955},[2806,2810,2815,2819,2823,2827,2831,2836,2840,2844,2848,2852,2856,2860,2865],{"type":42,"tag":1921,"props":2807,"children":2808},{"style":1984},[2809],{"type":47,"value":1987},{"type":42,"tag":1921,"props":2811,"children":2812},{"style":1990},[2813],{"type":47,"value":2814}," target ",{"type":42,"tag":1921,"props":2816,"children":2817},{"style":1996},[2818],{"type":47,"value":1522},{"type":42,"tag":1921,"props":2820,"children":2821},{"style":1990},[2822],{"type":47,"value":2769},{"type":42,"tag":1921,"props":2824,"children":2825},{"style":1996},[2826],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2828,"children":2829},{"style":2007},[2830],{"type":47,"value":2778},{"type":42,"tag":1921,"props":2832,"children":2833},{"style":1990},[2834],{"type":47,"value":2835},"(base",{"type":42,"tag":1921,"props":2837,"children":2838},{"style":1996},[2839],{"type":47,"value":2328},{"type":42,"tag":1921,"props":2841,"children":2842},{"style":2007},[2843],{"type":47,"value":2707},{"type":42,"tag":1921,"props":2845,"children":2846},{"style":1990},[2847],{"type":47,"value":2712},{"type":42,"tag":1921,"props":2849,"children":2850},{"style":1996},[2851],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2853,"children":2854},{"style":1990},[2855],{"type":47,"value":2721},{"type":42,"tag":1921,"props":2857,"children":2858},{"style":1996},[2859],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2861,"children":2862},{"style":1990},[2863],{"type":47,"value":2864},"name))",{"type":42,"tag":1921,"props":2866,"children":2867},{"style":1996},[2868],{"type":47,"value":2020},{"type":42,"tag":1921,"props":2870,"children":2871},{"class":1923,"line":28},[2872,2876,2880,2884,2889,2893,2898,2903,2907,2911,2915,2920,2925,2930,2934,2939,2943,2949,2953],{"type":42,"tag":1921,"props":2873,"children":2874},{"style":2001},[2875],{"type":47,"value":2125},{"type":42,"tag":1921,"props":2877,"children":2878},{"style":1990},[2879],{"type":47,"value":1674},{"type":42,"tag":1921,"props":2881,"children":2882},{"style":1996},[2883],{"type":47,"value":2134},{"type":42,"tag":1921,"props":2885,"children":2886},{"style":1990},[2887],{"type":47,"value":2888},"target",{"type":42,"tag":1921,"props":2890,"children":2891},{"style":1996},[2892],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2894,"children":2895},{"style":2007},[2896],{"type":47,"value":2897},"startsWith",{"type":42,"tag":1921,"props":2899,"children":2900},{"style":1990},[2901],{"type":47,"value":2902},"(base ",{"type":42,"tag":1921,"props":2904,"children":2905},{"style":1996},[2906],{"type":47,"value":1529},{"type":42,"tag":1921,"props":2908,"children":2909},{"style":1990},[2910],{"type":47,"value":2769},{"type":42,"tag":1921,"props":2912,"children":2913},{"style":1996},[2914],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2916,"children":2917},{"style":1990},[2918],{"type":47,"value":2919},"sep)) ",{"type":42,"tag":1921,"props":2921,"children":2922},{"style":2001},[2923],{"type":47,"value":2924},"return",{"type":42,"tag":1921,"props":2926,"children":2927},{"style":1990},[2928],{"type":47,"value":2929}," res",{"type":42,"tag":1921,"props":2931,"children":2932},{"style":1996},[2933],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2935,"children":2936},{"style":2007},[2937],{"type":47,"value":2938},"sendStatus",{"type":42,"tag":1921,"props":2940,"children":2941},{"style":1990},[2942],{"type":47,"value":2181},{"type":42,"tag":1921,"props":2944,"children":2946},{"style":2945},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[2947],{"type":47,"value":2948},"403",{"type":42,"tag":1921,"props":2950,"children":2951},{"style":1990},[2952],{"type":47,"value":1162},{"type":42,"tag":1921,"props":2954,"children":2955},{"style":1996},[2956],{"type":47,"value":2020},{"type":42,"tag":1921,"props":2958,"children":2959},{"class":1923,"line":2260},[2960,2964,2968,2972,2977],{"type":42,"tag":1921,"props":2961,"children":2962},{"style":1990},[2963],{"type":47,"value":2659},{"type":42,"tag":1921,"props":2965,"children":2966},{"style":1996},[2967],{"type":47,"value":1136},{"type":42,"tag":1921,"props":2969,"children":2970},{"style":2007},[2971],{"type":47,"value":323},{"type":42,"tag":1921,"props":2973,"children":2974},{"style":1990},[2975],{"type":47,"value":2976},"(target)",{"type":42,"tag":1921,"props":2978,"children":2979},{"style":1996},[2980],{"type":47,"value":2020},{"type":42,"tag":246,"props":2982,"children":2984},{"id":2983},"pattern-raw-sql-with-user-interpolation",[2985],{"type":47,"value":2986},"Pattern: Raw SQL with user interpolation",{"type":42,"tag":43,"props":2988,"children":2989},{},[2990],{"type":42,"tag":93,"props":2991,"children":2992},{},[2993],{"type":47,"value":1910},{"type":42,"tag":55,"props":2995,"children":2997},{"className":1913,"code":2996,"language":1915,"meta":64,"style":64},"Invoice.objects.extra(where=[f\"customer_id = {request.GET['cid']}\"])\n",[2998],{"type":42,"tag":62,"props":2999,"children":3000},{"__ignoreMap":64},[3001],{"type":42,"tag":1921,"props":3002,"children":3003},{"class":1923,"line":1924},[3004],{"type":42,"tag":1921,"props":3005,"children":3006},{},[3007],{"type":47,"value":2996},{"type":42,"tag":43,"props":3009,"children":3010},{},[3011],{"type":42,"tag":93,"props":3012,"children":3013},{},[3014],{"type":47,"value":2590},{"type":42,"tag":55,"props":3016,"children":3018},{"className":1913,"code":3017,"language":1915,"meta":64,"style":64},"Invoice.objects.filter(customer_id=request.GET[\"cid\"])\n# or, when the ORM can't express it:\nInvoice.objects.extra(where=[\"customer_id = %s\"], params=[request.GET[\"cid\"]])\n",[3019],{"type":42,"tag":62,"props":3020,"children":3021},{"__ignoreMap":64},[3022,3030,3038],{"type":42,"tag":1921,"props":3023,"children":3024},{"class":1923,"line":1924},[3025],{"type":42,"tag":1921,"props":3026,"children":3027},{},[3028],{"type":47,"value":3029},"Invoice.objects.filter(customer_id=request.GET[\"cid\"])\n",{"type":42,"tag":1921,"props":3031,"children":3032},{"class":1923,"line":1955},[3033],{"type":42,"tag":1921,"props":3034,"children":3035},{},[3036],{"type":47,"value":3037},"# or, when the ORM can't express it:\n",{"type":42,"tag":1921,"props":3039,"children":3040},{"class":1923,"line":28},[3041],{"type":42,"tag":1921,"props":3042,"children":3043},{},[3044],{"type":47,"value":3045},"Invoice.objects.extra(where=[\"customer_id = %s\"], params=[request.GET[\"cid\"]])\n",{"type":42,"tag":43,"props":3047,"children":3048},{},[3049],{"type":42,"tag":93,"props":3050,"children":3051},{},[3052],{"type":47,"value":1969},{"type":42,"tag":55,"props":3054,"children":3056},{"className":1972,"code":3055,"language":1974,"meta":64,"style":64},"await prisma.$queryRawUnsafe(`SELECT * FROM users WHERE name = '${name}'`);\n",[3057],{"type":42,"tag":62,"props":3058,"children":3059},{"__ignoreMap":64},[3060],{"type":42,"tag":1921,"props":3061,"children":3062},{"class":1923,"line":1924},[3063,3068,3073,3077,3081,3085,3090,3095,3100,3104,3108,3112,3116,3120],{"type":42,"tag":1921,"props":3064,"children":3065},{"style":2001},[3066],{"type":47,"value":3067},"await",{"type":42,"tag":1921,"props":3069,"children":3070},{"style":1990},[3071],{"type":47,"value":3072}," prisma",{"type":42,"tag":1921,"props":3074,"children":3075},{"style":1996},[3076],{"type":47,"value":1136},{"type":42,"tag":1921,"props":3078,"children":3079},{"style":2007},[3080],{"type":47,"value":174},{"type":42,"tag":1921,"props":3082,"children":3083},{"style":1990},[3084],{"type":47,"value":2181},{"type":42,"tag":1921,"props":3086,"children":3087},{"style":1996},[3088],{"type":47,"value":3089},"`",{"type":42,"tag":1921,"props":3091,"children":3092},{"style":2189},[3093],{"type":47,"value":3094},"SELECT * FROM users WHERE name = '",{"type":42,"tag":1921,"props":3096,"children":3097},{"style":1996},[3098],{"type":47,"value":3099},"${",{"type":42,"tag":1921,"props":3101,"children":3102},{"style":1990},[3103],{"type":47,"value":1768},{"type":42,"tag":1921,"props":3105,"children":3106},{"style":1996},[3107],{"type":47,"value":2226},{"type":42,"tag":1921,"props":3109,"children":3110},{"style":2189},[3111],{"type":47,"value":2186},{"type":42,"tag":1921,"props":3113,"children":3114},{"style":1996},[3115],{"type":47,"value":3089},{"type":42,"tag":1921,"props":3117,"children":3118},{"style":1990},[3119],{"type":47,"value":1162},{"type":42,"tag":1921,"props":3121,"children":3122},{"style":1996},[3123],{"type":47,"value":2020},{"type":42,"tag":43,"props":3125,"children":3126},{},[3127],{"type":42,"tag":93,"props":3128,"children":3129},{},[3130],{"type":47,"value":2076},{"type":42,"tag":55,"props":3132,"children":3134},{"className":1972,"code":3133,"language":1974,"meta":64,"style":64},"await prisma.$queryRaw`SELECT * FROM users WHERE name = ${name}`;\n",[3135],{"type":42,"tag":62,"props":3136,"children":3137},{"__ignoreMap":64},[3138],{"type":42,"tag":1921,"props":3139,"children":3140},{"class":1923,"line":1924},[3141,3145,3149,3153,3157,3161,3166,3170,3174,3179],{"type":42,"tag":1921,"props":3142,"children":3143},{"style":2001},[3144],{"type":47,"value":3067},{"type":42,"tag":1921,"props":3146,"children":3147},{"style":1990},[3148],{"type":47,"value":3072},{"type":42,"tag":1921,"props":3150,"children":3151},{"style":1996},[3152],{"type":47,"value":1136},{"type":42,"tag":1921,"props":3154,"children":3155},{"style":2007},[3156],{"type":47,"value":1866},{"type":42,"tag":1921,"props":3158,"children":3159},{"style":1996},[3160],{"type":47,"value":3089},{"type":42,"tag":1921,"props":3162,"children":3163},{"style":2189},[3164],{"type":47,"value":3165},"SELECT * FROM users WHERE name = ",{"type":42,"tag":1921,"props":3167,"children":3168},{"style":1996},[3169],{"type":47,"value":3099},{"type":42,"tag":1921,"props":3171,"children":3172},{"style":1990},[3173],{"type":47,"value":1768},{"type":42,"tag":1921,"props":3175,"children":3176},{"style":1996},[3177],{"type":47,"value":3178},"}`",{"type":42,"tag":1921,"props":3180,"children":3181},{"style":1996},[3182],{"type":47,"value":2020},{"type":42,"tag":246,"props":3184,"children":3186},{"id":3185},"pattern-response-leaks-internal-fields",[3187],{"type":47,"value":3188},"Pattern: Response leaks internal fields",{"type":42,"tag":43,"props":3190,"children":3191},{},[3192,3194,3199,3201,3207,3209,3215],{"type":47,"value":3193},"Real: Sentry commit ",{"type":42,"tag":62,"props":3195,"children":3197},{"className":3196},[],[3198],{"type":47,"value":1384},{"type":47,"value":3200}," (Pydantic ",{"type":42,"tag":62,"props":3202,"children":3204},{"className":3203},[],[3205],{"type":47,"value":3206},"extra = \"allow\"",{"type":47,"value":3208}," leaked ",{"type":42,"tag":62,"props":3210,"children":3212},{"className":3211},[],[3213],{"type":47,"value":3214},"SeerRunState",{"type":47,"value":3216}," fields).",{"type":42,"tag":43,"props":3218,"children":3219},{},[3220],{"type":42,"tag":93,"props":3221,"children":3222},{},[3223],{"type":47,"value":1910},{"type":42,"tag":55,"props":3225,"children":3227},{"className":1913,"code":3226,"language":1915,"meta":64,"style":64},"class SeerState(BaseModel):\n    class Config:\n        extra = \"allow\"\n    user_query: str\n\n@app.post(\"\u002Fchat\")\ndef chat(state: SeerState):\n    return state.dict()\n",[3228],{"type":42,"tag":62,"props":3229,"children":3230},{"__ignoreMap":64},[3231,3239,3247,3255,3263,3272,3280,3288],{"type":42,"tag":1921,"props":3232,"children":3233},{"class":1923,"line":1924},[3234],{"type":42,"tag":1921,"props":3235,"children":3236},{},[3237],{"type":47,"value":3238},"class SeerState(BaseModel):\n",{"type":42,"tag":1921,"props":3240,"children":3241},{"class":1923,"line":1955},[3242],{"type":42,"tag":1921,"props":3243,"children":3244},{},[3245],{"type":47,"value":3246},"    class Config:\n",{"type":42,"tag":1921,"props":3248,"children":3249},{"class":1923,"line":28},[3250],{"type":42,"tag":1921,"props":3251,"children":3252},{},[3253],{"type":47,"value":3254},"        extra = \"allow\"\n",{"type":42,"tag":1921,"props":3256,"children":3257},{"class":1923,"line":2260},[3258],{"type":42,"tag":1921,"props":3259,"children":3260},{},[3261],{"type":47,"value":3262},"    user_query: str\n",{"type":42,"tag":1921,"props":3264,"children":3265},{"class":1923,"line":2300},[3266],{"type":42,"tag":1921,"props":3267,"children":3269},{"emptyLinePlaceholder":3268},true,[3270],{"type":47,"value":3271},"\n",{"type":42,"tag":1921,"props":3273,"children":3274},{"class":1923,"line":2433},[3275],{"type":42,"tag":1921,"props":3276,"children":3277},{},[3278],{"type":47,"value":3279},"@app.post(\"\u002Fchat\")\n",{"type":42,"tag":1921,"props":3281,"children":3282},{"class":1923,"line":2476},[3283],{"type":42,"tag":1921,"props":3284,"children":3285},{},[3286],{"type":47,"value":3287},"def chat(state: SeerState):\n",{"type":42,"tag":1921,"props":3289,"children":3290},{"class":1923,"line":2485},[3291],{"type":42,"tag":1921,"props":3292,"children":3293},{},[3294],{"type":47,"value":3295},"    return state.dict()\n",{"type":42,"tag":43,"props":3297,"children":3298},{},[3299],{"type":42,"tag":93,"props":3300,"children":3301},{},[3302],{"type":47,"value":2590},{"type":42,"tag":55,"props":3304,"children":3306},{"className":1913,"code":3305,"language":1915,"meta":64,"style":64},"class SeerState(BaseModel):\n    class Config:\n        extra = \"ignore\"\n    user_query: str\n    internal_trace: str = Field(exclude=True)\n",[3307],{"type":42,"tag":62,"props":3308,"children":3309},{"__ignoreMap":64},[3310,3317,3324,3332,3339],{"type":42,"tag":1921,"props":3311,"children":3312},{"class":1923,"line":1924},[3313],{"type":42,"tag":1921,"props":3314,"children":3315},{},[3316],{"type":47,"value":3238},{"type":42,"tag":1921,"props":3318,"children":3319},{"class":1923,"line":1955},[3320],{"type":42,"tag":1921,"props":3321,"children":3322},{},[3323],{"type":47,"value":3246},{"type":42,"tag":1921,"props":3325,"children":3326},{"class":1923,"line":28},[3327],{"type":42,"tag":1921,"props":3328,"children":3329},{},[3330],{"type":47,"value":3331},"        extra = \"ignore\"\n",{"type":42,"tag":1921,"props":3333,"children":3334},{"class":1923,"line":2260},[3335],{"type":42,"tag":1921,"props":3336,"children":3337},{},[3338],{"type":47,"value":3262},{"type":42,"tag":1921,"props":3340,"children":3341},{"class":1923,"line":2300},[3342],{"type":42,"tag":1921,"props":3343,"children":3344},{},[3345],{"type":47,"value":3346},"    internal_trace: str = Field(exclude=True)\n",{"type":42,"tag":43,"props":3348,"children":3349},{},[3350],{"type":42,"tag":93,"props":3351,"children":3352},{},[3353],{"type":47,"value":3354},"TypeScript (Prisma) - bad:",{"type":42,"tag":55,"props":3356,"children":3358},{"className":1972,"code":3357,"language":1974,"meta":64,"style":64},"const user = await prisma.user.findUnique({ where: { id } });\nreturn res.json(user);   \u002F\u002F password_hash, 2fa_secret, internal flags.\n",[3359],{"type":42,"tag":62,"props":3360,"children":3361},{"__ignoreMap":64},[3362,3447],{"type":42,"tag":1921,"props":3363,"children":3364},{"class":1923,"line":1924},[3365,3369,3374,3378,3382,3386,3390,3395,3399,3404,3408,3413,3418,3422,3426,3431,3435,3439,3443],{"type":42,"tag":1921,"props":3366,"children":3367},{"style":1984},[3368],{"type":47,"value":1987},{"type":42,"tag":1921,"props":3370,"children":3371},{"style":1990},[3372],{"type":47,"value":3373}," user ",{"type":42,"tag":1921,"props":3375,"children":3376},{"style":1996},[3377],{"type":47,"value":1522},{"type":42,"tag":1921,"props":3379,"children":3380},{"style":2001},[3381],{"type":47,"value":2004},{"type":42,"tag":1921,"props":3383,"children":3384},{"style":1990},[3385],{"type":47,"value":3072},{"type":42,"tag":1921,"props":3387,"children":3388},{"style":1996},[3389],{"type":47,"value":1136},{"type":42,"tag":1921,"props":3391,"children":3392},{"style":1990},[3393],{"type":47,"value":3394},"user",{"type":42,"tag":1921,"props":3396,"children":3397},{"style":1996},[3398],{"type":47,"value":1136},{"type":42,"tag":1921,"props":3400,"children":3401},{"style":2007},[3402],{"type":47,"value":3403},"findUnique",{"type":42,"tag":1921,"props":3405,"children":3406},{"style":1990},[3407],{"type":47,"value":2181},{"type":42,"tag":1921,"props":3409,"children":3410},{"style":1996},[3411],{"type":47,"value":3412},"{",{"type":42,"tag":1921,"props":3414,"children":3415},{"style":2450},[3416],{"type":47,"value":3417}," where",{"type":42,"tag":1921,"props":3419,"children":3420},{"style":1996},[3421],{"type":47,"value":2528},{"type":42,"tag":1921,"props":3423,"children":3424},{"style":1996},[3425],{"type":47,"value":2216},{"type":42,"tag":1921,"props":3427,"children":3428},{"style":1990},[3429],{"type":47,"value":3430}," id ",{"type":42,"tag":1921,"props":3432,"children":3433},{"style":1996},[3434],{"type":47,"value":2226},{"type":42,"tag":1921,"props":3436,"children":3437},{"style":1996},[3438],{"type":47,"value":2547},{"type":42,"tag":1921,"props":3440,"children":3441},{"style":1990},[3442],{"type":47,"value":1162},{"type":42,"tag":1921,"props":3444,"children":3445},{"style":1996},[3446],{"type":47,"value":2020},{"type":42,"tag":1921,"props":3448,"children":3449},{"class":1923,"line":1955},[3450,3454,3458,3462,3467,3472,3476],{"type":42,"tag":1921,"props":3451,"children":3452},{"style":2001},[3453],{"type":47,"value":2924},{"type":42,"tag":1921,"props":3455,"children":3456},{"style":1990},[3457],{"type":47,"value":2929},{"type":42,"tag":1921,"props":3459,"children":3460},{"style":1996},[3461],{"type":47,"value":1136},{"type":42,"tag":1921,"props":3463,"children":3464},{"style":2007},[3465],{"type":47,"value":3466},"json",{"type":42,"tag":1921,"props":3468,"children":3469},{"style":1990},[3470],{"type":47,"value":3471},"(user)",{"type":42,"tag":1921,"props":3473,"children":3474},{"style":1996},[3475],{"type":47,"value":2062},{"type":42,"tag":1921,"props":3477,"children":3478},{"style":2065},[3479],{"type":47,"value":3480},"   \u002F\u002F password_hash, 2fa_secret, internal flags.\n",{"type":42,"tag":43,"props":3482,"children":3483},{},[3484],{"type":42,"tag":93,"props":3485,"children":3486},{},[3487],{"type":47,"value":2076},{"type":42,"tag":55,"props":3489,"children":3491},{"className":1972,"code":3490,"language":1974,"meta":64,"style":64},"const user = await prisma.user.findUnique({\n  where: { id },\n  select: { id: true, displayName: true, avatarUrl: true },\n});\nreturn res.json(user);\n",[3492],{"type":42,"tag":62,"props":3493,"children":3494},{"__ignoreMap":64},[3495,3542,3567,3637,3652],{"type":42,"tag":1921,"props":3496,"children":3497},{"class":1923,"line":1924},[3498,3502,3506,3510,3514,3518,3522,3526,3530,3534,3538],{"type":42,"tag":1921,"props":3499,"children":3500},{"style":1984},[3501],{"type":47,"value":1987},{"type":42,"tag":1921,"props":3503,"children":3504},{"style":1990},[3505],{"type":47,"value":3373},{"type":42,"tag":1921,"props":3507,"children":3508},{"style":1996},[3509],{"type":47,"value":1522},{"type":42,"tag":1921,"props":3511,"children":3512},{"style":2001},[3513],{"type":47,"value":2004},{"type":42,"tag":1921,"props":3515,"children":3516},{"style":1990},[3517],{"type":47,"value":3072},{"type":42,"tag":1921,"props":3519,"children":3520},{"style":1996},[3521],{"type":47,"value":1136},{"type":42,"tag":1921,"props":3523,"children":3524},{"style":1990},[3525],{"type":47,"value":3394},{"type":42,"tag":1921,"props":3527,"children":3528},{"style":1996},[3529],{"type":47,"value":1136},{"type":42,"tag":1921,"props":3531,"children":3532},{"style":2007},[3533],{"type":47,"value":3403},{"type":42,"tag":1921,"props":3535,"children":3536},{"style":1990},[3537],{"type":47,"value":2181},{"type":42,"tag":1921,"props":3539,"children":3540},{"style":1996},[3541],{"type":47,"value":2430},{"type":42,"tag":1921,"props":3543,"children":3544},{"class":1923,"line":1955},[3545,3550,3554,3558,3562],{"type":42,"tag":1921,"props":3546,"children":3547},{"style":2450},[3548],{"type":47,"value":3549},"  where",{"type":42,"tag":1921,"props":3551,"children":3552},{"style":1996},[3553],{"type":47,"value":2528},{"type":42,"tag":1921,"props":3555,"children":3556},{"style":1996},[3557],{"type":47,"value":2216},{"type":42,"tag":1921,"props":3559,"children":3560},{"style":1990},[3561],{"type":47,"value":3430},{"type":42,"tag":1921,"props":3563,"children":3564},{"style":1996},[3565],{"type":47,"value":3566},"},\n",{"type":42,"tag":1921,"props":3568,"children":3569},{"class":1923,"line":28},[3570,3575,3579,3583,3588,3592,3598,3602,3607,3611,3615,3619,3624,3628,3632],{"type":42,"tag":1921,"props":3571,"children":3572},{"style":2450},[3573],{"type":47,"value":3574},"  select",{"type":42,"tag":1921,"props":3576,"children":3577},{"style":1996},[3578],{"type":47,"value":2528},{"type":42,"tag":1921,"props":3580,"children":3581},{"style":1996},[3582],{"type":47,"value":2216},{"type":42,"tag":1921,"props":3584,"children":3585},{"style":2450},[3586],{"type":47,"value":3587}," id",{"type":42,"tag":1921,"props":3589,"children":3590},{"style":1996},[3591],{"type":47,"value":2528},{"type":42,"tag":1921,"props":3593,"children":3595},{"style":3594},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[3596],{"type":47,"value":3597}," true",{"type":42,"tag":1921,"props":3599,"children":3600},{"style":1996},[3601],{"type":47,"value":2328},{"type":42,"tag":1921,"props":3603,"children":3604},{"style":2450},[3605],{"type":47,"value":3606}," displayName",{"type":42,"tag":1921,"props":3608,"children":3609},{"style":1996},[3610],{"type":47,"value":2528},{"type":42,"tag":1921,"props":3612,"children":3613},{"style":3594},[3614],{"type":47,"value":3597},{"type":42,"tag":1921,"props":3616,"children":3617},{"style":1996},[3618],{"type":47,"value":2328},{"type":42,"tag":1921,"props":3620,"children":3621},{"style":2450},[3622],{"type":47,"value":3623}," avatarUrl",{"type":42,"tag":1921,"props":3625,"children":3626},{"style":1996},[3627],{"type":47,"value":2528},{"type":42,"tag":1921,"props":3629,"children":3630},{"style":3594},[3631],{"type":47,"value":3597},{"type":42,"tag":1921,"props":3633,"children":3634},{"style":1996},[3635],{"type":47,"value":3636}," },\n",{"type":42,"tag":1921,"props":3638,"children":3639},{"class":1923,"line":2260},[3640,3644,3648],{"type":42,"tag":1921,"props":3641,"children":3642},{"style":1996},[3643],{"type":47,"value":2226},{"type":42,"tag":1921,"props":3645,"children":3646},{"style":1990},[3647],{"type":47,"value":1162},{"type":42,"tag":1921,"props":3649,"children":3650},{"style":1996},[3651],{"type":47,"value":2020},{"type":42,"tag":1921,"props":3653,"children":3654},{"class":1923,"line":2300},[3655,3659,3663,3667,3671,3675],{"type":42,"tag":1921,"props":3656,"children":3657},{"style":2001},[3658],{"type":47,"value":2924},{"type":42,"tag":1921,"props":3660,"children":3661},{"style":1990},[3662],{"type":47,"value":2929},{"type":42,"tag":1921,"props":3664,"children":3665},{"style":1996},[3666],{"type":47,"value":1136},{"type":42,"tag":1921,"props":3668,"children":3669},{"style":2007},[3670],{"type":47,"value":3466},{"type":42,"tag":1921,"props":3672,"children":3673},{"style":1990},[3674],{"type":47,"value":3471},{"type":42,"tag":1921,"props":3676,"children":3677},{"style":1996},[3678],{"type":47,"value":2020},{"type":42,"tag":246,"props":3680,"children":3682},{"id":3681},"pattern-xxe-file-read",[3683],{"type":47,"value":3684},"Pattern: XXE file read",{"type":42,"tag":43,"props":3686,"children":3687},{},[3688],{"type":42,"tag":93,"props":3689,"children":3690},{},[3691],{"type":47,"value":1910},{"type":42,"tag":55,"props":3693,"children":3695},{"className":1913,"code":3694,"language":1915,"meta":64,"style":64},"import xml.etree.ElementTree as ET\ntree = ET.fromstring(request.data)\n",[3696],{"type":42,"tag":62,"props":3697,"children":3698},{"__ignoreMap":64},[3699,3707],{"type":42,"tag":1921,"props":3700,"children":3701},{"class":1923,"line":1924},[3702],{"type":42,"tag":1921,"props":3703,"children":3704},{},[3705],{"type":47,"value":3706},"import xml.etree.ElementTree as ET\n",{"type":42,"tag":1921,"props":3708,"children":3709},{"class":1923,"line":1955},[3710],{"type":42,"tag":1921,"props":3711,"children":3712},{},[3713],{"type":47,"value":3714},"tree = ET.fromstring(request.data)\n",{"type":42,"tag":43,"props":3716,"children":3717},{},[3718],{"type":42,"tag":93,"props":3719,"children":3720},{},[3721],{"type":47,"value":2590},{"type":42,"tag":55,"props":3723,"children":3725},{"className":1913,"code":3724,"language":1915,"meta":64,"style":64},"from defusedxml import ElementTree as ET\ntree = ET.fromstring(request.data)\n",[3726],{"type":42,"tag":62,"props":3727,"children":3728},{"__ignoreMap":64},[3729,3737],{"type":42,"tag":1921,"props":3730,"children":3731},{"class":1923,"line":1924},[3732],{"type":42,"tag":1921,"props":3733,"children":3734},{},[3735],{"type":47,"value":3736},"from defusedxml import ElementTree as ET\n",{"type":42,"tag":1921,"props":3738,"children":3739},{"class":1923,"line":1955},[3740],{"type":42,"tag":1921,"props":3741,"children":3742},{},[3743],{"type":47,"value":3714},{"type":42,"tag":73,"props":3745,"children":3747},{"id":3746},"investigation-playbook",[3748],{"type":47,"value":3749},"Investigation Playbook",{"type":42,"tag":1652,"props":3751,"children":3752},{},[3753,3762,3772,3782,3791],{"type":42,"tag":89,"props":3754,"children":3755},{},[3756,3761],{"type":42,"tag":93,"props":3757,"children":3758},{},[3759],{"type":47,"value":3760},"Classify the sink.",{"type":47,"value":228},{"type":42,"tag":89,"props":3763,"children":3764},{},[3765,3770],{"type":42,"tag":93,"props":3766,"children":3767},{},[3768],{"type":47,"value":3769},"Trace the source.",{"type":47,"value":3771}," Is the value at the sink user-controlled?",{"type":42,"tag":89,"props":3773,"children":3774},{},[3775,3780],{"type":42,"tag":93,"props":3776,"children":3777},{},[3778],{"type":47,"value":3779},"Check the allowlist \u002F validator \u002F parameterization",{"type":47,"value":3781}," between source and sink.",{"type":42,"tag":89,"props":3783,"children":3784},{},[3785,3789],{"type":42,"tag":93,"props":3786,"children":3787},{},[3788],{"type":47,"value":166},{"type":47,"value":3790}," axios \u002F lxml \u002F Sequelize \u002F Prisma \u002F Flask versions change the analysis.",{"type":42,"tag":89,"props":3792,"children":3793},{},[3794,3799,3800,3805,3807,3812],{"type":42,"tag":93,"props":3795,"children":3796},{},[3797],{"type":47,"value":3798},"Check siblings and history.",{"type":47,"value":202},{"type":42,"tag":62,"props":3801,"children":3803},{"className":3802},[],[3804],{"type":47,"value":216},{"type":47,"value":3806}," for every call site. ",{"type":42,"tag":62,"props":3808,"children":3810},{"className":3809},[],[3811],{"type":47,"value":208},{"type":47,"value":3813}," for recent guard removals.",{"type":42,"tag":43,"props":3815,"children":3816},{},[3817],{"type":47,"value":3818},"If the thread cannot be resolved, drop the finding or report with lower confidence.",{"type":42,"tag":73,"props":3820,"children":3822},{"id":3821},"output",[3823],{"type":47,"value":3824},"Output",{"type":42,"tag":43,"props":3826,"children":3827},{},[3828],{"type":47,"value":3829},"For each finding:",{"type":42,"tag":85,"props":3831,"children":3832},{},[3833,3843,3852,3862,3872,3882,3892,3902,3912],{"type":42,"tag":89,"props":3834,"children":3835},{},[3836,3841],{"type":42,"tag":93,"props":3837,"children":3838},{},[3839],{"type":47,"value":3840},"File and line",{"type":47,"value":3842}," of the unsafe code.",{"type":42,"tag":89,"props":3844,"children":3845},{},[3846,3850],{"type":42,"tag":93,"props":3847,"children":3848},{},[3849],{"type":47,"value":671},{"type":47,"value":3851}," from the table above.",{"type":42,"tag":89,"props":3853,"children":3854},{},[3855,3860],{"type":42,"tag":93,"props":3856,"children":3857},{},[3858],{"type":47,"value":3859},"Sink class",{"type":47,"value":3861}," (SSRF, path traversal, SQL injection, XXE, response leak).",{"type":42,"tag":89,"props":3863,"children":3864},{},[3865,3870],{"type":42,"tag":93,"props":3866,"children":3867},{},[3868],{"type":47,"value":3869},"What is wrong",{"type":47,"value":3871},", in one sentence.",{"type":42,"tag":89,"props":3873,"children":3874},{},[3875,3880],{"type":42,"tag":93,"props":3876,"children":3877},{},[3878],{"type":47,"value":3879},"Source",{"type":47,"value":3881},": where the attacker-controlled value originates.",{"type":42,"tag":89,"props":3883,"children":3884},{},[3885,3890],{"type":42,"tag":93,"props":3886,"children":3887},{},[3888],{"type":47,"value":3889},"Sink",{"type":47,"value":3891},": which API produces the disclosure.",{"type":42,"tag":89,"props":3893,"children":3894},{},[3895,3900],{"type":42,"tag":93,"props":3896,"children":3897},{},[3898],{"type":47,"value":3899},"Trace",{"type":47,"value":3901},": the specific path from source to sink.",{"type":42,"tag":89,"props":3903,"children":3904},{},[3905,3910],{"type":42,"tag":93,"props":3906,"children":3907},{},[3908],{"type":47,"value":3909},"Impact",{"type":47,"value":3911},": what data can be read, by whom.",{"type":42,"tag":89,"props":3913,"children":3914},{},[3915,3920],{"type":42,"tag":93,"props":3916,"children":3917},{},[3918],{"type":47,"value":3919},"Fix",{"type":47,"value":3921},": the concrete change. Name the allowlist, the required parameter, the missing containment check, the DTO\u002Fselect.",{"type":42,"tag":43,"props":3923,"children":3924},{},[3925,3927,3932],{"type":47,"value":3926},"Group findings by severity. Lead with ",{"type":42,"tag":62,"props":3928,"children":3930},{"className":3929},[],[3931],{"type":47,"value":704},{"type":47,"value":1136},{"type":42,"tag":3934,"props":3935,"children":3936},"style",{},[3937],{"type":47,"value":3938},"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":3940,"total":4113},[3941,3966,3980,3995,4009,4026,4040,4054,4062,4073,4083,4100],{"slug":3942,"name":3942,"fn":3943,"description":3944,"org":3945,"tags":3946,"stars":3963,"repoUrl":3964,"updatedAt":3965},"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},[3947,3950,3953,3956,3957,3960],{"name":3948,"slug":3949,"type":16},"Debugging","debugging",{"name":3951,"slug":3952,"type":16},"iOS","ios",{"name":3954,"slug":3955,"type":16},"macOS","macos",{"name":9,"slug":8,"type":16},{"name":3958,"slug":3959,"type":16},"Testing","testing",{"name":3961,"slug":3962,"type":16},"Xcode","xcode",6176,"https:\u002F\u002Fgithub.com\u002Fgetsentry\u002FXcodeBuildMCP","2026-04-06T18:13:34.8719",{"slug":3967,"name":3967,"fn":3968,"description":3969,"org":3970,"tags":3971,"stars":3963,"repoUrl":3964,"updatedAt":3979},"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},[3972,3975,3976,3977,3978],{"name":3973,"slug":3974,"type":16},"CLI","cli",{"name":3951,"slug":3952,"type":16},{"name":3954,"slug":3955,"type":16},{"name":3958,"slug":3959,"type":16},{"name":3961,"slug":3962,"type":16},"2026-04-06T18:13:36.13414",{"slug":3981,"name":3981,"fn":3982,"description":3983,"org":3984,"tags":3985,"stars":3992,"repoUrl":3993,"updatedAt":3994},"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},[3986,3989],{"name":3987,"slug":3988,"type":16},"Documentation","documentation",{"name":3990,"slug":3991,"type":16},"Engineering","engineering",861,"https:\u002F\u002Fgithub.com\u002Fgetsentry\u002Fskills","2026-05-15T06:16:29.695991",{"slug":3996,"name":3996,"fn":3997,"description":3998,"org":3999,"tags":4000,"stars":3992,"repoUrl":3993,"updatedAt":4008},"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},[4001,4004,4005],{"name":4002,"slug":4003,"type":16},"Communications","communications",{"name":9,"slug":8,"type":16},{"name":4006,"slug":4007,"type":16},"Technical Writing","technical-writing","2026-05-15T06:16:33.38217",{"slug":4010,"name":4010,"fn":4011,"description":4012,"org":4013,"tags":4014,"stars":3992,"repoUrl":3993,"updatedAt":4025},"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},[4015,4018,4021,4022],{"name":4016,"slug":4017,"type":16},"Branding","branding",{"name":4019,"slug":4020,"type":16},"Content Creation","content-creation",{"name":9,"slug":8,"type":16},{"name":4023,"slug":4024,"type":16},"UX Copy","ux-copy","2026-05-15T06:16:22.395707",{"slug":4027,"name":4027,"fn":4028,"description":4029,"org":4030,"tags":4031,"stars":3992,"repoUrl":3993,"updatedAt":4039},"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},[4032,4035,4038],{"name":4033,"slug":4034,"type":16},"Claude Code","claude-code",{"name":4036,"slug":4037,"type":16},"Configuration","configuration",{"name":14,"slug":15,"type":16},"2026-05-15T06:16:44.335977",{"slug":4041,"name":4041,"fn":4042,"description":4043,"org":4044,"tags":4045,"stars":3992,"repoUrl":3993,"updatedAt":4053},"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},[4046,4048,4049,4052],{"name":4047,"slug":4041,"type":16},"Code Review",{"name":3990,"slug":3991,"type":16},{"name":4050,"slug":4051,"type":16},"Performance","performance",{"name":14,"slug":15,"type":16},"2026-05-15T06:16:35.824864",{"slug":4055,"name":4055,"fn":4056,"description":4057,"org":4058,"tags":4059,"stars":3992,"repoUrl":3993,"updatedAt":4061},"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},[4060],{"name":22,"slug":23,"type":16},"2026-05-15T06:16:32.127981",{"slug":4063,"name":4063,"fn":4064,"description":4065,"org":4066,"tags":4067,"stars":3992,"repoUrl":3993,"updatedAt":4072},"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},[4068,4071],{"name":4069,"slug":4070,"type":16},"Git","git",{"name":9,"slug":8,"type":16},"2026-07-18T05:15:10.723937",{"slug":4074,"name":4074,"fn":4075,"description":4076,"org":4077,"tags":4078,"stars":3992,"repoUrl":3993,"updatedAt":4082},"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},[4079,4080,4081],{"name":3990,"slug":3991,"type":16},{"name":4069,"slug":4070,"type":16},{"name":9,"slug":8,"type":16},"2026-05-15T06:16:39.458431",{"slug":4084,"name":4084,"fn":4085,"description":4086,"org":4087,"tags":4088,"stars":3992,"repoUrl":3993,"updatedAt":4099},"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},[4089,4092,4093,4096,4098],{"name":4090,"slug":4091,"type":16},"Access Control","access-control",{"name":22,"slug":23,"type":16},{"name":4094,"slug":4095,"type":16},"Django","django",{"name":4097,"slug":1915,"type":16},"Python",{"name":14,"slug":15,"type":16},"2026-05-15T06:16:43.098698",{"slug":4101,"name":4101,"fn":4102,"description":4103,"org":4104,"tags":4105,"stars":3992,"repoUrl":3993,"updatedAt":4112},"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},[4106,4107,4110,4111],{"name":4047,"slug":4041,"type":16},{"name":4108,"slug":4109,"type":16},"Database","database",{"name":4094,"slug":4095,"type":16},{"name":4050,"slug":4051,"type":16},"2026-05-15T06:16:24.832813",88,{"items":4115,"total":2476},[4116,4131,4145,4157,4164,4175,4191],{"slug":4117,"name":4117,"fn":4118,"description":4119,"org":4120,"tags":4121,"stars":24,"repoUrl":25,"updatedAt":4130},"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},[4122,4125,4126,4127],{"name":4123,"slug":4124,"type":16},"Audit","audit",{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"name":4128,"slug":4129,"type":16},"Vercel","vercel","2026-05-05T05:29:23.090902",{"slug":4132,"name":4132,"fn":4133,"description":4134,"org":4135,"tags":4136,"stars":24,"repoUrl":25,"updatedAt":4144},"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},[4137,4138,4141,4142,4143],{"name":4090,"slug":4091,"type":16},{"name":4139,"slug":4140,"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":4146,"name":4146,"fn":4147,"description":4148,"org":4149,"tags":4150,"stars":24,"repoUrl":25,"updatedAt":4156},"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},[4151,4152,4153,4154,4155],{"name":18,"slug":19,"type":16},{"name":22,"slug":23,"type":16},{"name":3948,"slug":3949,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},"2026-04-29T05:41:39.861655",{"slug":4,"name":4,"fn":5,"description":6,"org":4158,"tags":4159,"stars":24,"repoUrl":25,"updatedAt":26},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[4160,4161,4162,4163],{"name":18,"slug":19,"type":16},{"name":22,"slug":23,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},{"slug":4165,"name":4165,"fn":4166,"description":4167,"org":4168,"tags":4169,"stars":24,"repoUrl":25,"updatedAt":4174},"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},[4170,4171,4172,4173],{"name":22,"slug":23,"type":16},{"name":3948,"slug":3949,"type":16},{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},"2026-07-18T05:47:48.104703",{"slug":4176,"name":4176,"fn":4177,"description":4178,"org":4179,"tags":4180,"stars":24,"repoUrl":25,"updatedAt":4190},"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},[4181,4184,4185,4188,4189],{"name":4182,"slug":4183,"type":16},"CI\u002FCD","ci-cd",{"name":22,"slug":23,"type":16},{"name":4186,"slug":4187,"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":4192,"name":4192,"fn":4193,"description":4194,"org":4195,"tags":4196,"stars":24,"repoUrl":25,"updatedAt":4206},"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},[4197,4198,4201,4204,4205],{"name":22,"slug":23,"type":16},{"name":4199,"slug":4200,"type":16},"Compliance","compliance",{"name":4202,"slug":4203,"type":16},"Privacy","privacy",{"name":14,"slug":15,"type":16},{"name":9,"slug":8,"type":16},"2026-04-29T05:41:38.512082"]