{"owner":"qazbnm456","repo":"awesome-web-security","hasSkills":true,"totalSkillsCount":3,"totalTokensCount":4883,"categories":["anthropic-skill","marketplace","claude-rule"],"hasMcp":false,"mcpConfig":null,"found":["skills/awesome-web-security/SKILL.md",".claude-plugin/marketplace.json","CLAUDE.md"],"skills":{"skills/awesome-web-security/SKILL.md":"---\nname: awesome-web-security\ndescription: \"Looks up curated web security learning resources (XSS, SQLi, CSRF, SSRF, OAuth/JWT, deserialization, SAML, recon, evasion, defensive tooling, CTF). Filters by topic, difficulty, language, and resource type. Returns top references with archive fallbacks. Defensive and educational use only.\"\nwhen_to_use: \"XSS, SQL injection, CSRF, SSRF, XXE, OAuth, JWT, prototype pollution, deserialization, SAML, file upload, web cache poisoning, WAF evasion, CSP bypass, browser exploitation, subdomain enumeration, OSINT, web security, penetration testing references, bug bounty resources, CTF web challenges, payload list, security cheatsheet, awesome list, 资安, 渗透, 学习资源, 安全, 漏洞, セキュリティ, ペンテスト, 脆弱性\"\nmetadata:\n  version: \"1.0.0\"\n---\n\n# /awesome-web-security\n\nCurated lookup over [qazbnm456/awesome-web-security](https://github.com/qazbnm456/awesome-web-security).\nAlways fetches the latest index from `raw.githubusercontent.com` — no stale snapshot.\n\n## When to use\n\nA user asks for resources, references, learning paths, or tools related to web\nsecurity topics: XSS, SQLi, CSRF, SSRF, XXE, OAuth/JWT, prototype pollution,\ndeserialization, SAML, file upload, web cache poisoning, WAF / CSP evasion,\nbrowser exploitation, recon (subdomain enumeration, OSINT), DNS rebinding,\nCTF write-ups, bug bounty methodology, defensive tooling, payload lists,\ncheatsheets, or related blogs.\n\n## When NOT to use\n\n- The user wants to attack a target they do not own and have not been\n  authorized to test. Decline and ask for scope: own system, CTF,\n  authorized pentest, academic research, or defensive analysis.\n- The user is asking for malware authoring, mass scanning of unowned\n  infrastructure, or detection-evasion guidance for offensive purposes.\n- The question has no security framing — it's general programming or\n  framework usage. Hand off to a non-security skill.\n\n## How\n\n1. Fetch the index with WebFetch:\n   `https://raw.githubusercontent.com/qazbnm456/awesome-web-security/master/data/index.json`\n2. Parse the JSON. Schema:\n   ```\n   {\n     \"schema_version\": \"1\",\n     \"categories\": [{\"key\": \"xss\", \"title\": \"...\", \"h_level\": 3, \"parent\": \"intro\", \"anchor\": \"xss\"}],\n     \"entries\": [{\n       \"id\": \"xss-google-app-security\",\n       \"url\": \"...\",\n       \"title\": \"...\",\n       \"author\": {\"name\": \"...\", \"url\": \"...\"},\n       \"category\": \"xss\",\n       \"type\": \"article|tool|cheatsheet|video|book|community|payload-list\",\n       \"languages\": [\"en\", \"zh\", \"jp\"],\n       \"difficulty\": \"intro|intermediate|advanced\",\n       \"date_added\": \"YYYY-MM-DD\",\n       \"archive_url\": \"...|null\",\n       \"last_checked\": \"YYYY-MM-DD|null\",\n       \"status\": \"active|dead|archived-only|quarantined\"\n     }]\n   }\n   ```\n3. Filter by:\n   - `category` matching the user's topic (a topic may map to several\n     categories — for \"XSS\" check `xss`, `tools-xss`, `tricks-xss`,\n     `practices-xss`, `evasions-csp` as relevant).\n   - `languages`: default to the user's language; fall back to `en`.\n   - `difficulty`: include all unless the user asked for \"intro\" or \"deep\".\n   - `type`: filter by what the user wants — articles, tools, cheatsheets,\n     payload lists, etc.\n4. Rank by:\n   - \"Latest\" requests → `date_added` DESC.\n   - \"Deep dive\" requests → prefer `difficulty: advanced`, then by depth\n     signals (long titles, payload-list type, presence of author URL).\n   - \"Tools\" requests → `type: tool` only.\n5. Return 5–7 entries; for each include title, URL, archive_url fallback if\n   `status != active`, and a one-line value statement explaining what this\n   entry teaches.\n\n## Safety guardrails\n\n- Refuse to assist with unauthorized targeting. Ask for scope.\n- Frame all results defensively / educationally.\n- For `payload-list` entries, append: \"Test payloads only against systems\n  you own or have written authorization to test.\"\n- Do not chain entries into an attack playbook against a named real target.\n\n## Output format\n\nFor each result:\n\n> **[Title](url)** — *author* • *difficulty* • *type*\n> One line on what this teaches and why it matters.\n> *(Archive fallback: archive_url)* — included only when `status != active`.\n\nEnd with:\n\n> Cited from [qazbnm456/awesome-web-security](https://github.com/qazbnm456/awesome-web-security). Full list and categories at the README.\n\n## Failure handling\n\n- JSON fetch fails (network, 404, parse error) → respond:\n  \"The awesome-web-security index is temporarily unreachable. Try again\n  shortly, or visit https://github.com/qazbnm456/awesome-web-security\n  directly.\" Do NOT fabricate entries.\n- No matches in the requested category → say so explicitly. Offer adjacent\n  categories from `categories[].parent` chain.\n\n## Examples\n\nUser: \"I'm learning XSS, give me intermediate-level resources in English.\"\n→ Filter `category` matching `xss`, `tools-xss`, `tricks-xss`, `evasions-csp`;\n  `languages` contains `en`; `difficulty` in `intermediate` or `advanced`;\n  rank by `date_added` DESC; return top 5–7.\n\nUser: \"我想找最新的 SSRF 文章。\"\n→ Filter `category` matching `ssrf`, `tricks-ssrf`, `tools-ssrf`;\n  `languages` contains `zh`; rank by `date_added` DESC; return in Chinese.\n\nUser: \"What's a good XSS payload list?\"\n→ Filter `category: xss` AND `type: payload-list`; rank by depth signals.\n  Append the unauthorized-testing reminder.\n",".claude-plugin/marketplace.json":"{\n  \"$schema\": \"https://anthropic.com/claude-code/marketplace.schema.json\",\n  \"name\": \"awesome-web-security\",\n  \"description\": \"Curated, always-fresh web security learning resources for AI agents and security researchers.\",\n  \"owner\": {\n    \"name\": \"qazbnm456\",\n    \"email\": \"qazbnm456@gmail.com\"\n  },\n  \"plugins\": [\n    {\n      \"name\": \"awesome-web-security\",\n      \"description\": \"Looks up curated web security learning resources (XSS, SQLi, CSRF, SSRF, OAuth/JWT, recon, evasion, tools, CTF). Filters by topic, difficulty, language, and resource type. Returns top references with archive fallbacks. Defensive use only; refuses unauthorized targeting.\",\n      \"version\": \"1.0.0\",\n      \"category\": \"development\",\n      \"source\": \"./\",\n      \"homepage\": \"https://github.com/qazbnm456/awesome-web-security\",\n      \"skills\": [\"./skills/awesome-web-security\"],\n      \"strict\": false\n    }\n  ]\n}\n","CLAUDE.md":"# CLAUDE.md\n\nGuidance for Claude Code working in this repository.\n\n## What this repo is\n\nA curated knowledge base of web security learning resources. Data lives in\n`data/categories.yml` and `data/entries/*.yml`; the three language READMEs\n(`README.md`, `README-zh.md`, `README-jp.md`) and `data/index.json` are\n**generated** from that data by `scripts/generate.py`. The same data backs a\nClaude Skill at `skills/awesome-web-security/` so AI agents can query the\nlist at runtime.\n\nNo build, no test suite, no application runtime. Every change is either\nYAML data, Python tooling, or Markdown docs.\n\n## Files of note\n\n- `data/categories.yml` — section tree, anchors, ToC. Edit carefully.\n- `data/entries/*.yml` — one file per section. Source of truth for entries.\n- `data/templates/preamble.md` / `postamble.md` — verbatim header/footer in\n  the generated READMEs.\n- `scripts/generate.py` — YAML → README.md / README-zh.md / README-jp.md /\n  data/index.json.\n- `scripts/migrate.py` — one-shot importer that originally produced the YAML\n  from the old hand-edited READMEs. Kept for reference; do not re-run on a\n  populated `data/`.\n- `scripts/verify_schema.py` — entry schema validation; CI gate.\n- `scripts/verify_anchors.py` — ensures no anchor used by external links is\n  removed; CI gate.\n- `scripts/verify_skill.sh` — lints `marketplace.json` and `SKILL.md`.\n- `scripts/ci/pr_review.py` — auto-review bot. **The LLM half is currently\n  dead**: it called GitHub Models, which GitHub retired on 2026-07-30, so the\n  bot has been running deterministic-only (reachability + format + local\n  dedup) and reports Depth/Fit as \"skipped\". Choosing a replacement backend\n  is deliberately deferred. Contributor language is detected\n  deterministically (Han / Kana regex on PR body) and passed to the LLM\n  as a directive; the LLM never owns language detection.\n- `scripts/ci/publish_review.py` — the privileged half of the review pair.\n  Reads the artifact `pr_review.py` produced, validates it (head SHA must\n  match both the producing run and the PR's current head, labels filtered\n  against an allowlist, body capped) and upserts one marked comment.\n- `scripts/ci/templates/comment.{en,zh,jp}.md` — localized review comments.\n- `.github/workflows/pr-review.yml` — grades a PR; never posts. Two jobs:\n  `verify` runs the PR's own code, `grade` runs the trusted base-branch\n  scripts over the PR's files as data and uploads the result as an artifact.\n- `.github/workflows/pr-review-publish.yml` — posts that artifact from\n  `workflow_run` (base-repo context, write token, never checks out the PR).\n  This split exists because fork PRs get a read-only `GITHUB_TOKEN`, so the\n  old single-workflow bot silently 403'd on every fork PR — which is nearly\n  all of them.\n- `.github/workflows/diff-sentry.yml` — `qazbnm456/diff-sentry` scan of the PR\n  diff for obfuscated payloads, exfiltration sinks, bidi/zero-width evasion\n  and workflow misconfigurations. Fails on `high` and above.\n- `.github/workflows/pr-review-backlog.yml` — dry-run over open PRs (manual,\n  workflow_dispatch). Stashes trusted scripts to `/tmp/awsec-trusted/` before\n  iterating PR refs, so `pr_review.py` always runs from the base branch even\n  when an attacker-controlled PR is checked out.\n- `.github/workflows/health-link-check.yml` — daily lychee scan over the\n  generated READMEs and `data/index.json`; surfaces broken links via a single\n  rolling issue labelled `health/link-check`. Replaces the previous\n  `validate.yml`.\n- `.github/workflows/post-merge-archive.yml` — after merges that touch\n  `data/entries/**`, submits eligible entries (active, no `archive_url` yet,\n  not opted out) to Wayback Machine and commits the resulting `archive_url`\n  back to the YAML with `[skip ci]`. Driven by `scripts/ci/archive.py`.\n- `.github/ISSUE_TEMPLATE/propose-resource.yml` — GitHub Form for proposals.\n- `.github/PULL_REQUEST_TEMPLATE.md` — self-checklist mirroring RUBRIC.md.\n- `.claude-plugin/marketplace.json` — declares the Claude plugin / Skill\n  package distributed via this repo.\n- `skills/awesome-web-security/SKILL.md` — the Skill body. Lives here so the\n  same repo serves humans and AI agents.\n- `RUBRIC.md` — the five-dimension scoring rubric the bot applies; also the\n  contributor self-check reference.\n- `CONTRIBUTING.md` — contributor flow. Treat as authoritative for PR\n  procedure; do not duplicate its contents here.\n\n## Editing rules\n\n- **Never edit `README.md`, `README-zh.md`, or `README-jp.md` directly.**\n  They are regenerated from `data/` by `scripts/generate.py`. Edits will be\n  blown away on the next regeneration.\n- To add or modify an entry, edit `data/entries/<category>.yml`.\n- To add a new category, edit `data/categories.yml` first, then add a new\n  `data/entries/<category-key>.yml`. Run `scripts/verify_anchors.py`\n  afterwards to confirm no external-facing anchor was lost.\n- After any data change, run `python3 scripts/generate.py` to refresh the\n  generated files locally before committing. CI will reject divergence.\n\n## Entry schema\n\n```yaml\n- id: xss-google-app-security                   # kebab-case, unique\n  url: https://www.google.com/...               # required, https preferred\n  title: Cross-Site Scripting – Application Security – Google\n  author:\n    name: Google                                # required if author exists\n    url: https://www.google.com/                # optional\n  category: xss                                 # must exist in categories.yml\n  type: article                                 # article|tool|cheatsheet|video|book|community|payload-list\n  languages: [en]                               # subset of: en|zh|jp|tr|universal\n  difficulty: intro                             # intro|intermediate|advanced\n  date_added: 2017-01-29                        # ISO date\n  archive_url: null                             # filled by post-merge-archive workflow\n  last_checked: null                            # filled by weekly-health workflow\n  fingerprint: null                             # content fingerprint, filled by health\n  status: active                                # active|dead|archived-only|quarantined\n```\n\nOptional fields:\n\n- `raw_rest` is the README description text that follows the title link\n  (the generator emits `- [Title](url) - {raw_rest}.`). It is **public-facing,\n  third-party-readable** content; treat it like user-facing copy.\n  - DO include: a one-sentence factual description of what the resource is,\n    optionally followed by a `Written by [Author](url)` byline.\n  - DO NOT include: references to this project, issue/PR numbers, phrases\n    like \"originally proposed by\", or any internal metadata. Git history\n    already preserves attribution; a third-party reader of the README must\n    not infer that the entry has any historical relationship to this repo.\n  - Leave migrator-written values as-is; only rewrite when the original is\n    wrong or stale.\n- `archive_opt_out: true` skips Wayback Machine archiving for this entry.\n  Set this only when the original author has explicitly asked not to be\n  archived (paywalled content, takedown requests). Defaults to false.\n- `languages: [universal]` is a wildcard meaning \"render this entry in\n  every language README\". Use sparingly; prefer explicit `[en, zh, jp]` when\n  you know the audience exactly.\n\n## Anchor preservation\n\nExternal sites and the ToC both link to `#some-anchor` targets. Renaming or\nremoving an existing anchor silently breaks those links. The CI guard\n`scripts/verify_anchors.py` compares the working tree's anchor set against\nmaster and fails the build if any baseline anchor is missing. Never rename\nan existing anchor; always add new ones for new sections.\n\n## Language policy\n\nProject-authored content is English. Exceptions, where multi-language is\nintrinsic to the artifact:\n\n- `README-zh.md`, `README-jp.md` — translated versions of `README.md`.\n- `data/categories.yml` `title_zh` / `title_jp` overrides, if any are added\n  later (currently the section titles are uniform across languages).\n- `data/entries/*.yml` `title` and `notes` fields preserve the resource's\n  original language (e.g. a Chinese article keeps its Chinese title).\n- `skills/awesome-web-security/SKILL.md` `when_to_use` trigger phrases use\n  multi-lingual keywords so the skill activates on non-English prompts.\n  The SKILL.md body itself remains English.\n- `scripts/ci/templates/comment.{en,zh,jp}.md` — the auto-review bot replies\n  in the contributor's language when detected with high confidence, falling\n  back to English otherwise. Dimension names (`Reachability`, `Format`,\n  `Depth`, `Fit`, `Dedup`) stay in English; they are keys into RUBRIC.md.\n\nEverything else — code, comments, schema field names, templates, CI output,\nlabels, commit messages — is English.\n\n## Multi-language entry routing\n\nA single entry can appear in multiple READMEs. The `languages` field\ncontrols where it shows up:\n\n- New entry, no language hint from the contributor → put it in `[en]` only;\n  ask the contributor if they want it in `zh` / `jp` too.\n- Locale-specific resource (Chinese-language article, Japanese-only forum) →\n  use `[zh]` / `[jp]` only.\n- Truly cross-cultural canonical resource → `[en, zh, jp]` or `[universal]`.\n- Do not force-translate or force-mirror an entry across languages to\n  \"match\" the structure. Each README is allowed to have entries the others\n  don't.\n\n## Handling new resource requests\n\nTwo kinds of inbound requests, both ported into the YAML data model\nthe same way the 2026 backlog was cleared:\n\n**Issue Form submission** (`.github/ISSUE_TEMPLATE/propose-resource.yml`)\n— the contributor filed an issue, not a PR. Port it directly: add the\nentry to `data/entries/<category>.yml`, run `python3\nscripts/generate.py` and the verify scripts, commit to `master` with\n`Closes #<n>` and a `Co-authored-by:` trailer crediting the submitter.\nThey never had a branch, so the co-author trailer is their credit.\n\n**Direct pull request** (contributor edited `README.md` or the YAML\ndirectly) — port on *their* branch so their PR merges with full\nattribution. See CONTRIBUTING.md \"Maintainer notes\" for the six-step\nPath B playbook. Never route a direct PR through Copilot: Copilot\nopens its own PR and closes the contributor's unmerged, destroying\ntheir merged-PR credit.\n\n### Copilot as async fallback\n\nCopilot is the fallback for **Issue Form submissions only**, when the\nmaintainer is unavailable for an extended period and the queue needs\nto keep moving. It is not the standard workflow — the manual port\nabove is. The maintainer still reviews the resulting Copilot PR before\nmerge; Copilot saves the typing, not the judgment. Prompt shape:\n\n```\n@copilot please port this resource into the new YAML data model.\n\nAdd it to `data/entries/<TARGET>.yml` with:\n- url, title, author.name, author.url (from the issue fields)\n- type: <article|tool|cheatsheet|video|book|community|payload-list>\n- difficulty: <intro|intermediate|advanced>\n- languages: [en, zh, jp] unless the resource is locale-specific\n  (then [zh] or [jp]); never [universal] as the sole value without\n  confirming with the maintainer\n- status: active\n\nSet `raw_rest` to a one-sentence factual description of the resource\nitself, optionally followed by a `Written by [Author](url)` byline. Do\nNOT mention this project, the issue number, the PR number, or any\ninternal metadata in `raw_rest`.\n\nEnd the PR body with both:\n  Closes #<n>\n  Co-authored-by: <issue-author> <ID+login@users.noreply.github.com>\n\nRun `python3 scripts/generate.py` and `python3 scripts/verify_schema.py`\nbefore opening the PR.\n```\n\nAdjust `<TARGET>`, `type`, `difficulty`, `languages`, the issue\nnumber, and the co-author identity per case.\n\n## Things not to do\n\n- Do not edit the generated `README*.md` files directly.\n- Do not rename or remove existing anchors in `data/categories.yml`.\n- Do not introduce HTML tags in `data/templates/*.md` beyond `a, b, br, p,\n  img` (the project's markdownlint config).\n- Do not bulk-reorder existing entries — the generator sorts by\n  `date_added`, then by title. To move an entry up, change its\n  `date_added`.\n- Do not commit `data/index.json` edits by hand. It is fully regenerated by\n  `scripts/generate.py`.\n- Do not edit `CONTRIBUTING.md`, `code-of-conduct.md`, or workflow files\n  unless the user explicitly asks.\n- Do not create commits or push unless explicitly asked.\n\n## CI behavior\n\nOn every PR touching `data/**`, a generated README, or the generator\nscripts:\n\n1. Runs `verify_schema.py` and `verify_anchors.py`.\n2. Re-runs `generate.py` and warns if the working tree diverges from the\n   generated output (contributor forgot to regenerate).\n3. Grades each new entry against RUBRIC.md and writes the verdict to an\n   artifact. A PR that only edited a generated README is graded too: the bot\n   reports link reachability plus the YAML-first explanation, in the\n   contributor's language.\n4. `pr-review-publish.yml` picks that artifact up on `workflow_run` and posts\n   a single structured comment, replacing its own previous one, then syncs\n   the advisory labels.\n\nEvery PR, path-filtered or not, is also scanned by diff-sentry.\n\nThe bot never auto-merges and never auto-rejects.\n\n## When in doubt\n\nMatch the spirit of CONTRIBUTING.md and RUBRIC.md. Ask the user if a change\ncrosses into territory not described here (new language version, new entry\nschema field, new section taxonomy).\n"},"files":{"skills/awesome-web-security/SKILL.md":"---\nname: awesome-web-security\ndescription: \"Looks up curated web security learning resources (XSS, SQLi, CSRF, SSRF, OAuth/JWT, deserialization, SAML, recon, evasion, defensive tooling, CTF). Filters by topic, difficulty, language, and resource type. Returns top references with archive fallbacks. Defensive and educational use only.\"\nwhen_to_use: \"XSS, SQL injection, CSRF, SSRF, XXE, OAuth, JWT, prototype pollution, deserialization, SAML, file upload, web cache poisoning, WAF evasion, CSP bypass, browser exploitation, subdomain enumeration, OSINT, web security, penetration testing references, bug bounty resources, CTF web challenges, payload list, security cheatsheet, awesome list, 资安, 渗透, 学习资源, 安全, 漏洞, セキュリティ, ペンテスト, 脆弱性\"\nmetadata:\n  version: \"1.0.0\"\n---\n\n# /awesome-web-security\n\nCurated lookup over [qazbnm456/awesome-web-security](https://github.com/qazbnm456/awesome-web-security).\nAlways fetches the latest index from `raw.githubusercontent.com` — no stale snapshot.\n\n## When to use\n\nA user asks for resources, references, learning paths, or tools related to web\nsecurity topics: XSS, SQLi, CSRF, SSRF, XXE, OAuth/JWT, prototype pollution,\ndeserialization, SAML, file upload, web cache poisoning, WAF / CSP evasion,\nbrowser exploitation, recon (subdomain enumeration, OSINT), DNS rebinding,\nCTF write-ups, bug bounty methodology, defensive tooling, payload lists,\ncheatsheets, or related blogs.\n\n## When NOT to use\n\n- The user wants to attack a target they do not own and have not been\n  authorized to test. Decline and ask for scope: own system, CTF,\n  authorized pentest, academic research, or defensive analysis.\n- The user is asking for malware authoring, mass scanning of unowned\n  infrastructure, or detection-evasion guidance for offensive purposes.\n- The question has no security framing — it's general programming or\n  framework usage. Hand off to a non-security skill.\n\n## How\n\n1. Fetch the index with WebFetch:\n   `https://raw.githubusercontent.com/qazbnm456/awesome-web-security/master/data/index.json`\n2. Parse the JSON. Schema:\n   ```\n   {\n     \"schema_version\": \"1\",\n     \"categories\": [{\"key\": \"xss\", \"title\": \"...\", \"h_level\": 3, \"parent\": \"intro\", \"anchor\": \"xss\"}],\n     \"entries\": [{\n       \"id\": \"xss-google-app-security\",\n       \"url\": \"...\",\n       \"title\": \"...\",\n       \"author\": {\"name\": \"...\", \"url\": \"...\"},\n       \"category\": \"xss\",\n       \"type\": \"article|tool|cheatsheet|video|book|community|payload-list\",\n       \"languages\": [\"en\", \"zh\", \"jp\"],\n       \"difficulty\": \"intro|intermediate|advanced\",\n       \"date_added\": \"YYYY-MM-DD\",\n       \"archive_url\": \"...|null\",\n       \"last_checked\": \"YYYY-MM-DD|null\",\n       \"status\": \"active|dead|archived-only|quarantined\"\n     }]\n   }\n   ```\n3. Filter by:\n   - `category` matching the user's topic (a topic may map to several\n     categories — for \"XSS\" check `xss`, `tools-xss`, `tricks-xss`,\n     `practices-xss`, `evasions-csp` as relevant).\n   - `languages`: default to the user's language; fall back to `en`.\n   - `difficulty`: include all unless the user asked for \"intro\" or \"deep\".\n   - `type`: filter by what the user wants — articles, tools, cheatsheets,\n     payload lists, etc.\n4. Rank by:\n   - \"Latest\" requests → `date_added` DESC.\n   - \"Deep dive\" requests → prefer `difficulty: advanced`, then by depth\n     signals (long titles, payload-list type, presence of author URL).\n   - \"Tools\" requests → `type: tool` only.\n5. Return 5–7 entries; for each include title, URL, archive_url fallback if\n   `status != active`, and a one-line value statement explaining what this\n   entry teaches.\n\n## Safety guardrails\n\n- Refuse to assist with unauthorized targeting. Ask for scope.\n- Frame all results defensively / educationally.\n- For `payload-list` entries, append: \"Test payloads only against systems\n  you own or have written authorization to test.\"\n- Do not chain entries into an attack playbook against a named real target.\n\n## Output format\n\nFor each result:\n\n> **[Title](url)** — *author* • *difficulty* • *type*\n> One line on what this teaches and why it matters.\n> *(Archive fallback: archive_url)* — included only when `status != active`.\n\nEnd with:\n\n> Cited from [qazbnm456/awesome-web-security](https://github.com/qazbnm456/awesome-web-security). Full list and categories at the README.\n\n## Failure handling\n\n- JSON fetch fails (network, 404, parse error) → respond:\n  \"The awesome-web-security index is temporarily unreachable. Try again\n  shortly, or visit https://github.com/qazbnm456/awesome-web-security\n  directly.\" Do NOT fabricate entries.\n- No matches in the requested category → say so explicitly. Offer adjacent\n  categories from `categories[].parent` chain.\n\n## Examples\n\nUser: \"I'm learning XSS, give me intermediate-level resources in English.\"\n→ Filter `category` matching `xss`, `tools-xss`, `tricks-xss`, `evasions-csp`;\n  `languages` contains `en`; `difficulty` in `intermediate` or `advanced`;\n  rank by `date_added` DESC; return top 5–7.\n\nUser: \"我想找最新的 SSRF 文章。\"\n→ Filter `category` matching `ssrf`, `tricks-ssrf`, `tools-ssrf`;\n  `languages` contains `zh`; rank by `date_added` DESC; return in Chinese.\n\nUser: \"What's a good XSS payload list?\"\n→ Filter `category: xss` AND `type: payload-list`; rank by depth signals.\n  Append the unauthorized-testing reminder.\n",".claude-plugin/marketplace.json":"{\n  \"$schema\": \"https://anthropic.com/claude-code/marketplace.schema.json\",\n  \"name\": \"awesome-web-security\",\n  \"description\": \"Curated, always-fresh web security learning resources for AI agents and security researchers.\",\n  \"owner\": {\n    \"name\": \"qazbnm456\",\n    \"email\": \"qazbnm456@gmail.com\"\n  },\n  \"plugins\": [\n    {\n      \"name\": \"awesome-web-security\",\n      \"description\": \"Looks up curated web security learning resources (XSS, SQLi, CSRF, SSRF, OAuth/JWT, recon, evasion, tools, CTF). Filters by topic, difficulty, language, and resource type. Returns top references with archive fallbacks. Defensive use only; refuses unauthorized targeting.\",\n      \"version\": \"1.0.0\",\n      \"category\": \"development\",\n      \"source\": \"./\",\n      \"homepage\": \"https://github.com/qazbnm456/awesome-web-security\",\n      \"skills\": [\"./skills/awesome-web-security\"],\n      \"strict\": false\n    }\n  ]\n}\n","CLAUDE.md":"# CLAUDE.md\n\nGuidance for Claude Code working in this repository.\n\n## What this repo is\n\nA curated knowledge base of web security learning resources. Data lives in\n`data/categories.yml` and `data/entries/*.yml`; the three language READMEs\n(`README.md`, `README-zh.md`, `README-jp.md`) and `data/index.json` are\n**generated** from that data by `scripts/generate.py`. The same data backs a\nClaude Skill at `skills/awesome-web-security/` so AI agents can query the\nlist at runtime.\n\nNo build, no test suite, no application runtime. Every change is either\nYAML data, Python tooling, or Markdown docs.\n\n## Files of note\n\n- `data/categories.yml` — section tree, anchors, ToC. Edit carefully.\n- `data/entries/*.yml` — one file per section. Source of truth for entries.\n- `data/templates/preamble.md` / `postamble.md` — verbatim header/footer in\n  the generated READMEs.\n- `scripts/generate.py` — YAML → README.md / README-zh.md / README-jp.md /\n  data/index.json.\n- `scripts/migrate.py` — one-shot importer that originally produced the YAML\n  from the old hand-edited READMEs. Kept for reference; do not re-run on a\n  populated `data/`.\n- `scripts/verify_schema.py` — entry schema validation; CI gate.\n- `scripts/verify_anchors.py` — ensures no anchor used by external links is\n  removed; CI gate.\n- `scripts/verify_skill.sh` — lints `marketplace.json` and `SKILL.md`.\n- `scripts/ci/pr_review.py` — auto-review bot. **The LLM half is currently\n  dead**: it called GitHub Models, which GitHub retired on 2026-07-30, so the\n  bot has been running deterministic-only (reachability + format + local\n  dedup) and reports Depth/Fit as \"skipped\". Choosing a replacement backend\n  is deliberately deferred. Contributor language is detected\n  deterministically (Han / Kana regex on PR body) and passed to the LLM\n  as a directive; the LLM never owns language detection.\n- `scripts/ci/publish_review.py` — the privileged half of the review pair.\n  Reads the artifact `pr_review.py` produced, validates it (head SHA must\n  match both the producing run and the PR's current head, labels filtered\n  against an allowlist, body capped) and upserts one marked comment.\n- `scripts/ci/templates/comment.{en,zh,jp}.md` — localized review comments.\n- `.github/workflows/pr-review.yml` — grades a PR; never posts. Two jobs:\n  `verify` runs the PR's own code, `grade` runs the trusted base-branch\n  scripts over the PR's files as data and uploads the result as an artifact.\n- `.github/workflows/pr-review-publish.yml` — posts that artifact from\n  `workflow_run` (base-repo context, write token, never checks out the PR).\n  This split exists because fork PRs get a read-only `GITHUB_TOKEN`, so the\n  old single-workflow bot silently 403'd on every fork PR — which is nearly\n  all of them.\n- `.github/workflows/diff-sentry.yml` — `qazbnm456/diff-sentry` scan of the PR\n  diff for obfuscated payloads, exfiltration sinks, bidi/zero-width evasion\n  and workflow misconfigurations. Fails on `high` and above.\n- `.github/workflows/pr-review-backlog.yml` — dry-run over open PRs (manual,\n  workflow_dispatch). Stashes trusted scripts to `/tmp/awsec-trusted/` before\n  iterating PR refs, so `pr_review.py` always runs from the base branch even\n  when an attacker-controlled PR is checked out.\n- `.github/workflows/health-link-check.yml` — daily lychee scan over the\n  generated READMEs and `data/index.json`; surfaces broken links via a single\n  rolling issue labelled `health/link-check`. Replaces the previous\n  `validate.yml`.\n- `.github/workflows/post-merge-archive.yml` — after merges that touch\n  `data/entries/**`, submits eligible entries (active, no `archive_url` yet,\n  not opted out) to Wayback Machine and commits the resulting `archive_url`\n  back to the YAML with `[skip ci]`. Driven by `scripts/ci/archive.py`.\n- `.github/ISSUE_TEMPLATE/propose-resource.yml` — GitHub Form for proposals.\n- `.github/PULL_REQUEST_TEMPLATE.md` — self-checklist mirroring RUBRIC.md.\n- `.claude-plugin/marketplace.json` — declares the Claude plugin / Skill\n  package distributed via this repo.\n- `skills/awesome-web-security/SKILL.md` — the Skill body. Lives here so the\n  same repo serves humans and AI agents.\n- `RUBRIC.md` — the five-dimension scoring rubric the bot applies; also the\n  contributor self-check reference.\n- `CONTRIBUTING.md` — contributor flow. Treat as authoritative for PR\n  procedure; do not duplicate its contents here.\n\n## Editing rules\n\n- **Never edit `README.md`, `README-zh.md`, or `README-jp.md` directly.**\n  They are regenerated from `data/` by `scripts/generate.py`. Edits will be\n  blown away on the next regeneration.\n- To add or modify an entry, edit `data/entries/<category>.yml`.\n- To add a new category, edit `data/categories.yml` first, then add a new\n  `data/entries/<category-key>.yml`. Run `scripts/verify_anchors.py`\n  afterwards to confirm no external-facing anchor was lost.\n- After any data change, run `python3 scripts/generate.py` to refresh the\n  generated files locally before committing. CI will reject divergence.\n\n## Entry schema\n\n```yaml\n- id: xss-google-app-security                   # kebab-case, unique\n  url: https://www.google.com/...               # required, https preferred\n  title: Cross-Site Scripting – Application Security – Google\n  author:\n    name: Google                                # required if author exists\n    url: https://www.google.com/                # optional\n  category: xss                                 # must exist in categories.yml\n  type: article                                 # article|tool|cheatsheet|video|book|community|payload-list\n  languages: [en]                               # subset of: en|zh|jp|tr|universal\n  difficulty: intro                             # intro|intermediate|advanced\n  date_added: 2017-01-29                        # ISO date\n  archive_url: null                             # filled by post-merge-archive workflow\n  last_checked: null                            # filled by weekly-health workflow\n  fingerprint: null                             # content fingerprint, filled by health\n  status: active                                # active|dead|archived-only|quarantined\n```\n\nOptional fields:\n\n- `raw_rest` is the README description text that follows the title link\n  (the generator emits `- [Title](url) - {raw_rest}.`). It is **public-facing,\n  third-party-readable** content; treat it like user-facing copy.\n  - DO include: a one-sentence factual description of what the resource is,\n    optionally followed by a `Written by [Author](url)` byline.\n  - DO NOT include: references to this project, issue/PR numbers, phrases\n    like \"originally proposed by\", or any internal metadata. Git history\n    already preserves attribution; a third-party reader of the README must\n    not infer that the entry has any historical relationship to this repo.\n  - Leave migrator-written values as-is; only rewrite when the original is\n    wrong or stale.\n- `archive_opt_out: true` skips Wayback Machine archiving for this entry.\n  Set this only when the original author has explicitly asked not to be\n  archived (paywalled content, takedown requests). Defaults to false.\n- `languages: [universal]` is a wildcard meaning \"render this entry in\n  every language README\". Use sparingly; prefer explicit `[en, zh, jp]` when\n  you know the audience exactly.\n\n## Anchor preservation\n\nExternal sites and the ToC both link to `#some-anchor` targets. Renaming or\nremoving an existing anchor silently breaks those links. The CI guard\n`scripts/verify_anchors.py` compares the working tree's anchor set against\nmaster and fails the build if any baseline anchor is missing. Never rename\nan existing anchor; always add new ones for new sections.\n\n## Language policy\n\nProject-authored content is English. Exceptions, where multi-language is\nintrinsic to the artifact:\n\n- `README-zh.md`, `README-jp.md` — translated versions of `README.md`.\n- `data/categories.yml` `title_zh` / `title_jp` overrides, if any are added\n  later (currently the section titles are uniform across languages).\n- `data/entries/*.yml` `title` and `notes` fields preserve the resource's\n  original language (e.g. a Chinese article keeps its Chinese title).\n- `skills/awesome-web-security/SKILL.md` `when_to_use` trigger phrases use\n  multi-lingual keywords so the skill activates on non-English prompts.\n  The SKILL.md body itself remains English.\n- `scripts/ci/templates/comment.{en,zh,jp}.md` — the auto-review bot replies\n  in the contributor's language when detected with high confidence, falling\n  back to English otherwise. Dimension names (`Reachability`, `Format`,\n  `Depth`, `Fit`, `Dedup`) stay in English; they are keys into RUBRIC.md.\n\nEverything else — code, comments, schema field names, templates, CI output,\nlabels, commit messages — is English.\n\n## Multi-language entry routing\n\nA single entry can appear in multiple READMEs. The `languages` field\ncontrols where it shows up:\n\n- New entry, no language hint from the contributor → put it in `[en]` only;\n  ask the contributor if they want it in `zh` / `jp` too.\n- Locale-specific resource (Chinese-language article, Japanese-only forum) →\n  use `[zh]` / `[jp]` only.\n- Truly cross-cultural canonical resource → `[en, zh, jp]` or `[universal]`.\n- Do not force-translate or force-mirror an entry across languages to\n  \"match\" the structure. Each README is allowed to have entries the others\n  don't.\n\n## Handling new resource requests\n\nTwo kinds of inbound requests, both ported into the YAML data model\nthe same way the 2026 backlog was cleared:\n\n**Issue Form submission** (`.github/ISSUE_TEMPLATE/propose-resource.yml`)\n— the contributor filed an issue, not a PR. Port it directly: add the\nentry to `data/entries/<category>.yml`, run `python3\nscripts/generate.py` and the verify scripts, commit to `master` with\n`Closes #<n>` and a `Co-authored-by:` trailer crediting the submitter.\nThey never had a branch, so the co-author trailer is their credit.\n\n**Direct pull request** (contributor edited `README.md` or the YAML\ndirectly) — port on *their* branch so their PR merges with full\nattribution. See CONTRIBUTING.md \"Maintainer notes\" for the six-step\nPath B playbook. Never route a direct PR through Copilot: Copilot\nopens its own PR and closes the contributor's unmerged, destroying\ntheir merged-PR credit.\n\n### Copilot as async fallback\n\nCopilot is the fallback for **Issue Form submissions only**, when the\nmaintainer is unavailable for an extended period and the queue needs\nto keep moving. It is not the standard workflow — the manual port\nabove is. The maintainer still reviews the resulting Copilot PR before\nmerge; Copilot saves the typing, not the judgment. Prompt shape:\n\n```\n@copilot please port this resource into the new YAML data model.\n\nAdd it to `data/entries/<TARGET>.yml` with:\n- url, title, author.name, author.url (from the issue fields)\n- type: <article|tool|cheatsheet|video|book|community|payload-list>\n- difficulty: <intro|intermediate|advanced>\n- languages: [en, zh, jp] unless the resource is locale-specific\n  (then [zh] or [jp]); never [universal] as the sole value without\n  confirming with the maintainer\n- status: active\n\nSet `raw_rest` to a one-sentence factual description of the resource\nitself, optionally followed by a `Written by [Author](url)` byline. Do\nNOT mention this project, the issue number, the PR number, or any\ninternal metadata in `raw_rest`.\n\nEnd the PR body with both:\n  Closes #<n>\n  Co-authored-by: <issue-author> <ID+login@users.noreply.github.com>\n\nRun `python3 scripts/generate.py` and `python3 scripts/verify_schema.py`\nbefore opening the PR.\n```\n\nAdjust `<TARGET>`, `type`, `difficulty`, `languages`, the issue\nnumber, and the co-author identity per case.\n\n## Things not to do\n\n- Do not edit the generated `README*.md` files directly.\n- Do not rename or remove existing anchors in `data/categories.yml`.\n- Do not introduce HTML tags in `data/templates/*.md` beyond `a, b, br, p,\n  img` (the project's markdownlint config).\n- Do not bulk-reorder existing entries — the generator sorts by\n  `date_added`, then by title. To move an entry up, change its\n  `date_added`.\n- Do not commit `data/index.json` edits by hand. It is fully regenerated by\n  `scripts/generate.py`.\n- Do not edit `CONTRIBUTING.md`, `code-of-conduct.md`, or workflow files\n  unless the user explicitly asks.\n- Do not create commits or push unless explicitly asked.\n\n## CI behavior\n\nOn every PR touching `data/**`, a generated README, or the generator\nscripts:\n\n1. Runs `verify_schema.py` and `verify_anchors.py`.\n2. Re-runs `generate.py` and warns if the working tree diverges from the\n   generated output (contributor forgot to regenerate).\n3. Grades each new entry against RUBRIC.md and writes the verdict to an\n   artifact. A PR that only edited a generated README is graded too: the bot\n   reports link reachability plus the YAML-first explanation, in the\n   contributor's language.\n4. `pr-review-publish.yml` picks that artifact up on `workflow_run` and posts\n   a single structured comment, replacing its own previous one, then syncs\n   the advisory labels.\n\nEvery PR, path-filtered or not, is also scanned by diff-sentry.\n\nThe bot never auto-merges and never auto-rejects.\n\n## When in doubt\n\nMatch the spirit of CONTRIBUTING.md and RUBRIC.md. Ask the user if a change\ncrosses into territory not described here (new language version, new entry\nschema field, new section taxonomy).\n"},"items":[{"name":"SKILL.md","path":"skills/awesome-web-security/SKILL.md","rawUrl":"https://raw.githubusercontent.com/qazbnm456/awesome-web-security/HEAD/skills/awesome-web-security/SKILL.md","title":"awesome-web-security","category":"anthropic-skill","format":"markdown","content":"---\nname: awesome-web-security\ndescription: \"Looks up curated web security learning resources (XSS, SQLi, CSRF, SSRF, OAuth/JWT, deserialization, SAML, recon, evasion, defensive tooling, CTF). Filters by topic, difficulty, language, and resource type. Returns top references with archive fallbacks. Defensive and educational use only.\"\nwhen_to_use: \"XSS, SQL injection, CSRF, SSRF, XXE, OAuth, JWT, prototype pollution, deserialization, SAML, file upload, web cache poisoning, WAF evasion, CSP bypass, browser exploitation, subdomain enumeration, OSINT, web security, penetration testing references, bug bounty resources, CTF web challenges, payload list, security cheatsheet, awesome list, 资安, 渗透, 学习资源, 安全, 漏洞, セキュリティ, ペンテスト, 脆弱性\"\nmetadata:\n  version: \"1.0.0\"\n---\n\n# /awesome-web-security\n\nCurated lookup over [qazbnm456/awesome-web-security](https://github.com/qazbnm456/awesome-web-security).\nAlways fetches the latest index from `raw.githubusercontent.com` — no stale snapshot.\n\n## When to use\n\nA user asks for resources, references, learning paths, or tools related to web\nsecurity topics: XSS, SQLi, CSRF, SSRF, XXE, OAuth/JWT, prototype pollution,\ndeserialization, SAML, file upload, web cache poisoning, WAF / CSP evasion,\nbrowser exploitation, recon (subdomain enumeration, OSINT), DNS rebinding,\nCTF write-ups, bug bounty methodology, defensive tooling, payload lists,\ncheatsheets, or related blogs.\n\n## When NOT to use\n\n- The user wants to attack a target they do not own and have not been\n  authorized to test. Decline and ask for scope: own system, CTF,\n  authorized pentest, academic research, or defensive analysis.\n- The user is asking for malware authoring, mass scanning of unowned\n  infrastructure, or detection-evasion guidance for offensive purposes.\n- The question has no security framing — it's general programming or\n  framework usage. Hand off to a non-security skill.\n\n## How\n\n1. Fetch the index with WebFetch:\n   `https://raw.githubusercontent.com/qazbnm456/awesome-web-security/master/data/index.json`\n2. Parse the JSON. Schema:\n   ```\n   {\n     \"schema_version\": \"1\",\n     \"categories\": [{\"key\": \"xss\", \"title\": \"...\", \"h_level\": 3, \"parent\": \"intro\", \"anchor\": \"xss\"}],\n     \"entries\": [{\n       \"id\": \"xss-google-app-security\",\n       \"url\": \"...\",\n       \"title\": \"...\",\n       \"author\": {\"name\": \"...\", \"url\": \"...\"},\n       \"category\": \"xss\",\n       \"type\": \"article|tool|cheatsheet|video|book|community|payload-list\",\n       \"languages\": [\"en\", \"zh\", \"jp\"],\n       \"difficulty\": \"intro|intermediate|advanced\",\n       \"date_added\": \"YYYY-MM-DD\",\n       \"archive_url\": \"...|null\",\n       \"last_checked\": \"YYYY-MM-DD|null\",\n       \"status\": \"active|dead|archived-only|quarantined\"\n     }]\n   }\n   ```\n3. Filter by:\n   - `category` matching the user's topic (a topic may map to several\n     categories — for \"XSS\" check `xss`, `tools-xss`, `tricks-xss`,\n     `practices-xss`, `evasions-csp` as relevant).\n   - `languages`: default to the user's language; fall back to `en`.\n   - `difficulty`: include all unless the user asked for \"intro\" or \"deep\".\n   - `type`: filter by what the user wants — articles, tools, cheatsheets,\n     payload lists, etc.\n4. Rank by:\n   - \"Latest\" requests → `date_added` DESC.\n   - \"Deep dive\" requests → prefer `difficulty: advanced`, then by depth\n     signals (long titles, payload-list type, presence of author URL).\n   - \"Tools\" requests → `type: tool` only.\n5. Return 5–7 entries; for each include title, URL, archive_url fallback if\n   `status != active`, and a one-line value statement explaining what this\n   entry teaches.\n\n## Safety guardrails\n\n- Refuse to assist with unauthorized targeting. Ask for scope.\n- Frame all results defensively / educationally.\n- For `payload-list` entries, append: \"Test payloads only against systems\n  you own or have written authorization to test.\"\n- Do not chain entries into an attack playbook against a named real target.\n\n## Output format\n\nFor each result:\n\n> **[Title](url)** — *author* • *difficulty* • *type*\n> One line on what this teaches and why it matters.\n> *(Archive fallback: archive_url)* — included only when `status != active`.\n\nEnd with:\n\n> Cited from [qazbnm456/awesome-web-security](https://github.com/qazbnm456/awesome-web-security). Full list and categories at the README.\n\n## Failure handling\n\n- JSON fetch fails (network, 404, parse error) → respond:\n  \"The awesome-web-security index is temporarily unreachable. Try again\n  shortly, or visit https://github.com/qazbnm456/awesome-web-security\n  directly.\" Do NOT fabricate entries.\n- No matches in the requested category → say so explicitly. Offer adjacent\n  categories from `categories[].parent` chain.\n\n## Examples\n\nUser: \"I'm learning XSS, give me intermediate-level resources in English.\"\n→ Filter `category` matching `xss`, `tools-xss`, `tricks-xss`, `evasions-csp`;\n  `languages` contains `en`; `difficulty` in `intermediate` or `advanced`;\n  rank by `date_added` DESC; return top 5–7.\n\nUser: \"我想找最新的 SSRF 文章。\"\n→ Filter `category` matching `ssrf`, `tricks-ssrf`, `tools-ssrf`;\n  `languages` contains `zh`; rank by `date_added` DESC; return in Chinese.\n\nUser: \"What's a good XSS payload list?\"\n→ Filter `category: xss` AND `type: payload-list`; rank by depth signals.\n  Append the unauthorized-testing reminder.\n","frontmatter":{"name":"awesome-web-security","description":"Looks up curated web security learning resources (XSS, SQLi, CSRF, SSRF, OAuth/JWT, deserialization, SAML, recon, evasion, defensive tooling, CTF). Filters by topic, difficulty, language, and resource type. Returns top references with archive fallbacks. Defensive and educational use only.","when_to_use":"XSS, SQL injection, CSRF, SSRF, XXE, OAuth, JWT, prototype pollution, deserialization, SAML, file upload, web cache poisoning, WAF evasion, CSP bypass, browser exploitation, subdomain enumeration, OSINT, web security, penetration testing references, bug bounty resources, CTF web challenges, payload list, security cheatsheet, awesome list, 资安, 渗透, 学习资源, 安全, 漏洞, セキュリティ, ペンテスト, 脆弱性","metadata":{"version":"1.0.0"}},"isInternal":false,"tokens":1386,"sizeBytes":5401},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/qazbnm456/awesome-web-security/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# CLAUDE.md\n\nGuidance for Claude Code working in this repository.\n\n## What this repo is\n\nA curated knowledge base of web security learning resources. Data lives in\n`data/categories.yml` and `data/entries/*.yml`; the three language READMEs\n(`README.md`, `README-zh.md`, `README-jp.md`) and `data/index.json` are\n**generated** from that data by `scripts/generate.py`. The same data backs a\nClaude Skill at `skills/awesome-web-security/` so AI agents can query the\nlist at runtime.\n\nNo build, no test suite, no application runtime. Every change is either\nYAML data, Python tooling, or Markdown docs.\n\n## Files of note\n\n- `data/categories.yml` — section tree, anchors, ToC. Edit carefully.\n- `data/entries/*.yml` — one file per section. Source of truth for entries.\n- `data/templates/preamble.md` / `postamble.md` — verbatim header/footer in\n  the generated READMEs.\n- `scripts/generate.py` — YAML → README.md / README-zh.md / README-jp.md /\n  data/index.json.\n- `scripts/migrate.py` — one-shot importer that originally produced the YAML\n  from the old hand-edited READMEs. Kept for reference; do not re-run on a\n  populated `data/`.\n- `scripts/verify_schema.py` — entry schema validation; CI gate.\n- `scripts/verify_anchors.py` — ensures no anchor used by external links is\n  removed; CI gate.\n- `scripts/verify_skill.sh` — lints `marketplace.json` and `SKILL.md`.\n- `scripts/ci/pr_review.py` — auto-review bot. **The LLM half is currently\n  dead**: it called GitHub Models, which GitHub retired on 2026-07-30, so the\n  bot has been running deterministic-only (reachability + format + local\n  dedup) and reports Depth/Fit as \"skipped\". Choosing a replacement backend\n  is deliberately deferred. Contributor language is detected\n  deterministically (Han / Kana regex on PR body) and passed to the LLM\n  as a directive; the LLM never owns language detection.\n- `scripts/ci/publish_review.py` — the privileged half of the review pair.\n  Reads the artifact `pr_review.py` produced, validates it (head SHA must\n  match both the producing run and the PR's current head, labels filtered\n  against an allowlist, body capped) and upserts one marked comment.\n- `scripts/ci/templates/comment.{en,zh,jp}.md` — localized review comments.\n- `.github/workflows/pr-review.yml` — grades a PR; never posts. Two jobs:\n  `verify` runs the PR's own code, `grade` runs the trusted base-branch\n  scripts over the PR's files as data and uploads the result as an artifact.\n- `.github/workflows/pr-review-publish.yml` — posts that artifact from\n  `workflow_run` (base-repo context, write token, never checks out the PR).\n  This split exists because fork PRs get a read-only `GITHUB_TOKEN`, so the\n  old single-workflow bot silently 403'd on every fork PR — which is nearly\n  all of them.\n- `.github/workflows/diff-sentry.yml` — `qazbnm456/diff-sentry` scan of the PR\n  diff for obfuscated payloads, exfiltration sinks, bidi/zero-width evasion\n  and workflow misconfigurations. Fails on `high` and above.\n- `.github/workflows/pr-review-backlog.yml` — dry-run over open PRs (manual,\n  workflow_dispatch). Stashes trusted scripts to `/tmp/awsec-trusted/` before\n  iterating PR refs, so `pr_review.py` always runs from the base branch even\n  when an attacker-controlled PR is checked out.\n- `.github/workflows/health-link-check.yml` — daily lychee scan over the\n  generated READMEs and `data/index.json`; surfaces broken links via a single\n  rolling issue labelled `health/link-check`. Replaces the previous\n  `validate.yml`.\n- `.github/workflows/post-merge-archive.yml` — after merges that touch\n  `data/entries/**`, submits eligible entries (active, no `archive_url` yet,\n  not opted out) to Wayback Machine and commits the resulting `archive_url`\n  back to the YAML with `[skip ci]`. Driven by `scripts/ci/archive.py`.\n- `.github/ISSUE_TEMPLATE/propose-resource.yml` — GitHub Form for proposals.\n- `.github/PULL_REQUEST_TEMPLATE.md` — self-checklist mirroring RUBRIC.md.\n- `.claude-plugin/marketplace.json` — declares the Claude plugin / Skill\n  package distributed via this repo.\n- `skills/awesome-web-security/SKILL.md` — the Skill body. Lives here so the\n  same repo serves humans and AI agents.\n- `RUBRIC.md` — the five-dimension scoring rubric the bot applies; also the\n  contributor self-check reference.\n- `CONTRIBUTING.md` — contributor flow. Treat as authoritative for PR\n  procedure; do not duplicate its contents here.\n\n## Editing rules\n\n- **Never edit `README.md`, `README-zh.md`, or `README-jp.md` directly.**\n  They are regenerated from `data/` by `scripts/generate.py`. Edits will be\n  blown away on the next regeneration.\n- To add or modify an entry, edit `data/entries/<category>.yml`.\n- To add a new category, edit `data/categories.yml` first, then add a new\n  `data/entries/<category-key>.yml`. Run `scripts/verify_anchors.py`\n  afterwards to confirm no external-facing anchor was lost.\n- After any data change, run `python3 scripts/generate.py` to refresh the\n  generated files locally before committing. CI will reject divergence.\n\n## Entry schema\n\n```yaml\n- id: xss-google-app-security                   # kebab-case, unique\n  url: https://www.google.com/...               # required, https preferred\n  title: Cross-Site Scripting – Application Security – Google\n  author:\n    name: Google                                # required if author exists\n    url: https://www.google.com/                # optional\n  category: xss                                 # must exist in categories.yml\n  type: article                                 # article|tool|cheatsheet|video|book|community|payload-list\n  languages: [en]                               # subset of: en|zh|jp|tr|universal\n  difficulty: intro                             # intro|intermediate|advanced\n  date_added: 2017-01-29                        # ISO date\n  archive_url: null                             # filled by post-merge-archive workflow\n  last_checked: null                            # filled by weekly-health workflow\n  fingerprint: null                             # content fingerprint, filled by health\n  status: active                                # active|dead|archived-only|quarantined\n```\n\nOptional fields:\n\n- `raw_rest` is the README description text that follows the title link\n  (the generator emits `- [Title](url) - {raw_rest}.`). It is **public-facing,\n  third-party-readable** content; treat it like user-facing copy.\n  - DO include: a one-sentence factual description of what the resource is,\n    optionally followed by a `Written by [Author](url)` byline.\n  - DO NOT include: references to this project, issue/PR numbers, phrases\n    like \"originally proposed by\", or any internal metadata. Git history\n    already preserves attribution; a third-party reader of the README must\n    not infer that the entry has any historical relationship to this repo.\n  - Leave migrator-written values as-is; only rewrite when the original is\n    wrong or stale.\n- `archive_opt_out: true` skips Wayback Machine archiving for this entry.\n  Set this only when the original author has explicitly asked not to be\n  archived (paywalled content, takedown requests). Defaults to false.\n- `languages: [universal]` is a wildcard meaning \"render this entry in\n  every language README\". Use sparingly; prefer explicit `[en, zh, jp]` when\n  you know the audience exactly.\n\n## Anchor preservation\n\nExternal sites and the ToC both link to `#some-anchor` targets. Renaming or\nremoving an existing anchor silently breaks those links. The CI guard\n`scripts/verify_anchors.py` compares the working tree's anchor set against\nmaster and fails the build if any baseline anchor is missing. Never rename\nan existing anchor; always add new ones for new sections.\n\n## Language policy\n\nProject-authored content is English. Exceptions, where multi-language is\nintrinsic to the artifact:\n\n- `README-zh.md`, `README-jp.md` — translated versions of `README.md`.\n- `data/categories.yml` `title_zh` / `title_jp` overrides, if any are added\n  later (currently the section titles are uniform across languages).\n- `data/entries/*.yml` `title` and `notes` fields preserve the resource's\n  original language (e.g. a Chinese article keeps its Chinese title).\n- `skills/awesome-web-security/SKILL.md` `when_to_use` trigger phrases use\n  multi-lingual keywords so the skill activates on non-English prompts.\n  The SKILL.md body itself remains English.\n- `scripts/ci/templates/comment.{en,zh,jp}.md` — the auto-review bot replies\n  in the contributor's language when detected with high confidence, falling\n  back to English otherwise. Dimension names (`Reachability`, `Format`,\n  `Depth`, `Fit`, `Dedup`) stay in English; they are keys into RUBRIC.md.\n\nEverything else — code, comments, schema field names, templates, CI output,\nlabels, commit messages — is English.\n\n## Multi-language entry routing\n\nA single entry can appear in multiple READMEs. The `languages` field\ncontrols where it shows up:\n\n- New entry, no language hint from the contributor → put it in `[en]` only;\n  ask the contributor if they want it in `zh` / `jp` too.\n- Locale-specific resource (Chinese-language article, Japanese-only forum) →\n  use `[zh]` / `[jp]` only.\n- Truly cross-cultural canonical resource → `[en, zh, jp]` or `[universal]`.\n- Do not force-translate or force-mirror an entry across languages to\n  \"match\" the structure. Each README is allowed to have entries the others\n  don't.\n\n## Handling new resource requests\n\nTwo kinds of inbound requests, both ported into the YAML data model\nthe same way the 2026 backlog was cleared:\n\n**Issue Form submission** (`.github/ISSUE_TEMPLATE/propose-resource.yml`)\n— the contributor filed an issue, not a PR. Port it directly: add the\nentry to `data/entries/<category>.yml`, run `python3\nscripts/generate.py` and the verify scripts, commit to `master` with\n`Closes #<n>` and a `Co-authored-by:` trailer crediting the submitter.\nThey never had a branch, so the co-author trailer is their credit.\n\n**Direct pull request** (contributor edited `README.md` or the YAML\ndirectly) — port on *their* branch so their PR merges with full\nattribution. See CONTRIBUTING.md \"Maintainer notes\" for the six-step\nPath B playbook. Never route a direct PR through Copilot: Copilot\nopens its own PR and closes the contributor's unmerged, destroying\ntheir merged-PR credit.\n\n### Copilot as async fallback\n\nCopilot is the fallback for **Issue Form submissions only**, when the\nmaintainer is unavailable for an extended period and the queue needs\nto keep moving. It is not the standard workflow — the manual port\nabove is. The maintainer still reviews the resulting Copilot PR before\nmerge; Copilot saves the typing, not the judgment. Prompt shape:\n\n```\n@copilot please port this resource into the new YAML data model.\n\nAdd it to `data/entries/<TARGET>.yml` with:\n- url, title, author.name, author.url (from the issue fields)\n- type: <article|tool|cheatsheet|video|book|community|payload-list>\n- difficulty: <intro|intermediate|advanced>\n- languages: [en, zh, jp] unless the resource is locale-specific\n  (then [zh] or [jp]); never [universal] as the sole value without\n  confirming with the maintainer\n- status: active\n\nSet `raw_rest` to a one-sentence factual description of the resource\nitself, optionally followed by a `Written by [Author](url)` byline. Do\nNOT mention this project, the issue number, the PR number, or any\ninternal metadata in `raw_rest`.\n\nEnd the PR body with both:\n  Closes #<n>\n  Co-authored-by: <issue-author> <ID+login@users.noreply.github.com>\n\nRun `python3 scripts/generate.py` and `python3 scripts/verify_schema.py`\nbefore opening the PR.\n```\n\nAdjust `<TARGET>`, `type`, `difficulty`, `languages`, the issue\nnumber, and the co-author identity per case.\n\n## Things not to do\n\n- Do not edit the generated `README*.md` files directly.\n- Do not rename or remove existing anchors in `data/categories.yml`.\n- Do not introduce HTML tags in `data/templates/*.md` beyond `a, b, br, p,\n  img` (the project's markdownlint config).\n- Do not bulk-reorder existing entries — the generator sorts by\n  `date_added`, then by title. To move an entry up, change its\n  `date_added`.\n- Do not commit `data/index.json` edits by hand. It is fully regenerated by\n  `scripts/generate.py`.\n- Do not edit `CONTRIBUTING.md`, `code-of-conduct.md`, or workflow files\n  unless the user explicitly asks.\n- Do not create commits or push unless explicitly asked.\n\n## CI behavior\n\nOn every PR touching `data/**`, a generated README, or the generator\nscripts:\n\n1. Runs `verify_schema.py` and `verify_anchors.py`.\n2. Re-runs `generate.py` and warns if the working tree diverges from the\n   generated output (contributor forgot to regenerate).\n3. Grades each new entry against RUBRIC.md and writes the verdict to an\n   artifact. A PR that only edited a generated README is graded too: the bot\n   reports link reachability plus the YAML-first explanation, in the\n   contributor's language.\n4. `pr-review-publish.yml` picks that artifact up on `workflow_run` and posts\n   a single structured comment, replacing its own previous one, then syncs\n   the advisory labels.\n\nEvery PR, path-filtered or not, is also scanned by diff-sentry.\n\nThe bot never auto-merges and never auto-rejects.\n\n## When in doubt\n\nMatch the spirit of CONTRIBUTING.md and RUBRIC.md. Ask the user if a change\ncrosses into territory not described here (new language version, new entry\nschema field, new section taxonomy).\n","isInternal":false,"tokens":3267,"sizeBytes":13482},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/qazbnm456/awesome-web-security/HEAD/.claude-plugin/marketplace.json","title":"awesome-web-security","category":"marketplace","format":"json","content":"{\n  \"$schema\": \"https://anthropic.com/claude-code/marketplace.schema.json\",\n  \"name\": \"awesome-web-security\",\n  \"description\": \"Curated, always-fresh web security learning resources for AI agents and security researchers.\",\n  \"owner\": {\n    \"name\": \"qazbnm456\",\n    \"email\": \"qazbnm456@gmail.com\"\n  },\n  \"plugins\": [\n    {\n      \"name\": \"awesome-web-security\",\n      \"description\": \"Looks up curated web security learning resources (XSS, SQLi, CSRF, SSRF, OAuth/JWT, recon, evasion, tools, CTF). Filters by topic, difficulty, language, and resource type. Returns top references with archive fallbacks. Defensive use only; refuses unauthorized targeting.\",\n      \"version\": \"1.0.0\",\n      \"category\": \"development\",\n      \"source\": \"./\",\n      \"homepage\": \"https://github.com/qazbnm456/awesome-web-security\",\n      \"skills\": [\"./skills/awesome-web-security\"],\n      \"strict\": false\n    }\n  ]\n}\n","frontmatter":{"$schema":"https://anthropic.com/claude-code/marketplace.schema.json","name":"awesome-web-security","description":"Curated, always-fresh web security learning resources for AI agents and security researchers.","owner":{"name":"qazbnm456","email":"qazbnm456@gmail.com"},"plugins":[{"name":"awesome-web-security","description":"Looks up curated web security learning resources (XSS, SQLi, CSRF, SSRF, OAuth/JWT, recon, evasion, tools, CTF). Filters by topic, difficulty, language, and resource type. Returns top references with archive fallbacks. Defensive use only; refuses unauthorized targeting.","version":"1.0.0","category":"development","source":"./","homepage":"https://github.com/qazbnm456/awesome-web-security","skills":["./skills/awesome-web-security"],"strict":false}]},"isInternal":false,"tokens":230,"sizeBytes":893}],"systemPromptSnippet":"<yakaai_skills repo=\"qazbnm456/awesome-web-security\">\n<!-- File: skills/awesome-web-security/SKILL.md (Tokens: ~1386 | Category: anthropic-skill) -->\n---\nname: awesome-web-security\ndescription: \"Looks up curated web security learning resources (XSS, SQLi, CSRF, SSRF, OAuth/JWT, deserialization, SAML, recon, evasion, defensive tooling, CTF). Filters by topic, difficulty, language, and resource type. Returns top references with archive fallbacks. Defensive and educational use only.\"\nwhen_to_use: \"XSS, SQL injection, CSRF, SSRF, XXE, OAuth, JWT, prototype pollution, deserialization, SAML, file upload, web cache poisoning, WAF evasion, CSP bypass, browser exploitation, subdomain enumeration, OSINT, web security, penetration testing references, bug bounty resources, CTF web challenges, payload list, security cheatsheet, awesome list, 资安, 渗透, 学习资源, 安全, 漏洞, セキュリティ, ペンテスト, 脆弱性\"\nmetadata:\n  version: \"1.0.0\"\n---\n\n# /awesome-web-security\n\nCurated lookup over [qazbnm456/awesome-web-security](https://github.com/qazbnm456/awesome-web-security).\nAlways fetches the latest index from `raw.githubusercontent.com` — no stale snapshot.\n\n## When to use\n\nA user asks for resources, references, learning paths, or tools related to web\nsecurity topics: XSS, SQLi, CSRF, SSRF, XXE, OAuth/JWT, prototype pollution,\ndeserialization, SAML, file upload, web cache poisoning, WAF / CSP evasion,\nbrowser exploitation, recon (subdomain enumeration, OSINT), DNS rebinding,\nCTF write-ups, bug bounty methodology, defensive tooling, payload lists,\ncheatsheets, or related blogs.\n\n## When NOT to use\n\n- The user wants to attack a target they do not own and have not been\n  authorized to test. Decline and ask for scope: own system, CTF,\n  authorized pentest, academic research, or defensive analysis.\n- The user is asking for malware authoring, mass scanning of unowned\n  infrastructure, or detection-evasion guidance for offensive purposes.\n- The question has no security framing — it's general programming or\n  framework usage. Hand off to a non-security skill.\n\n## How\n\n1. Fetch the index with WebFetch:\n   `https://raw.githubusercontent.com/qazbnm456/awesome-web-security/master/data/index.json`\n2. Parse the JSON. Schema:\n   ```\n   {\n     \"schema_version\": \"1\",\n     \"categories\": [{\"key\": \"xss\", \"title\": \"...\", \"h_level\": 3, \"parent\": \"intro\", \"anchor\": \"xss\"}],\n     \"entries\": [{\n       \"id\": \"xss-google-app-security\",\n       \"url\": \"...\",\n       \"title\": \"...\",\n       \"author\": {\"name\": \"...\", \"url\": \"...\"},\n       \"category\": \"xss\",\n       \"type\": \"article|tool|cheatsheet|video|book|community|payload-list\",\n       \"languages\": [\"en\", \"zh\", \"jp\"],\n       \"difficulty\": \"intro|intermediate|advanced\",\n       \"date_added\": \"YYYY-MM-DD\",\n       \"archive_url\": \"...|null\",\n       \"last_checked\": \"YYYY-MM-DD|null\",\n       \"status\": \"active|dead|archived-only|quarantined\"\n     }]\n   }\n   ```\n3. Filter by:\n   - `category` matching the user's topic (a topic may map to several\n     categories — for \"XSS\" check `xss`, `tools-xss`, `tricks-xss`,\n     `practices-xss`, `evasions-csp` as relevant).\n   - `languages`: default to the user's language; fall back to `en`.\n   - `difficulty`: include all unless the user asked for \"intro\" or \"deep\".\n   - `type`: filter by what the user wants — articles, tools, cheatsheets,\n     payload lists, etc.\n4. Rank by:\n   - \"Latest\" requests → `date_added` DESC.\n   - \"Deep dive\" requests → prefer `difficulty: advanced`, then by depth\n     signals (long titles, payload-list type, presence of author URL).\n   - \"Tools\" requests → `type: tool` only.\n5. Return 5–7 entries; for each include title, URL, archive_url fallback if\n   `status != active`, and a one-line value statement explaining what this\n   entry teaches.\n\n## Safety guardrails\n\n- Refuse to assist with unauthorized targeting. Ask for scope.\n- Frame all results defensively / educationally.\n- For `payload-list` entries, append: \"Test payloads only against systems\n  you own or have written authorization to test.\"\n- Do not chain entries into an attack playbook against a named real target.\n\n## Output format\n\nFor each result:\n\n> **[Title](url)** — *author* • *difficulty* • *type*\n> One line on what this teaches and why it matters.\n> *(Archive fallback: archive_url)* — included only when `status != active`.\n\nEnd with:\n\n> Cited from [qazbnm456/awesome-web-security](https://github.com/qazbnm456/awesome-web-security). Full list and categories at the README.\n\n## Failure handling\n\n- JSON fetch fails (network, 404, parse error) → respond:\n  \"The awesome-web-security index is temporarily unreachable. Try again\n  shortly, or visit https://github.com/qazbnm456/awesome-web-security\n  directly.\" Do NOT fabricate entries.\n- No matches in the requested category → say so explicitly. Offer adjacent\n  categories from `categories[].parent` chain.\n\n## Examples\n\nUser: \"I'm learning XSS, give me intermediate-level resources in English.\"\n→ Filter `category` matching `xss`, `tools-xss`, `tricks-xss`, `evasions-csp`;\n  `languages` contains `en`; `difficulty` in `intermediate` or `advanced`;\n  rank by `date_added` DESC; return top 5–7.\n\nUser: \"我想找最新的 SSRF 文章。\"\n→ Filter `category` matching `ssrf`, `tricks-ssrf`, `tools-ssrf`;\n  `languages` contains `zh`; rank by `date_added` DESC; return in Chinese.\n\nUser: \"What's a good XSS payload list?\"\n→ Filter `category: xss` AND `type: payload-list`; rank by depth signals.\n  Append the unauthorized-testing reminder.\n\n<!-- File: CLAUDE.md (Tokens: ~3267 | Category: claude-rule) -->\n# CLAUDE.md\n\nGuidance for Claude Code working in this repository.\n\n## What this repo is\n\nA curated knowledge base of web security learning resources. Data lives in\n`data/categories.yml` and `data/entries/*.yml`; the three language READMEs\n(`README.md`, `README-zh.md`, `README-jp.md`) and `data/index.json` are\n**generated** from that data by `scripts/generate.py`. The same data backs a\nClaude Skill at `skills/awesome-web-security/` so AI agents can query the\nlist at runtime.\n\nNo build, no test suite, no application runtime. Every change is either\nYAML data, Python tooling, or Markdown docs.\n\n## Files of note\n\n- `data/categories.yml` — section tree, anchors, ToC. Edit carefully.\n- `data/entries/*.yml` — one file per section. Source of truth for entries.\n- `data/templates/preamble.md` / `postamble.md` — verbatim header/footer in\n  the generated READMEs.\n- `scripts/generate.py` — YAML → README.md / README-zh.md / README-jp.md /\n  data/index.json.\n- `scripts/migrate.py` — one-shot importer that originally produced the YAML\n  from the old hand-edited READMEs. Kept for reference; do not re-run on a\n  populated `data/`.\n- `scripts/verify_schema.py` — entry schema validation; CI gate.\n- `scripts/verify_anchors.py` — ensures no anchor used by external links is\n  removed; CI gate.\n- `scripts/verify_skill.sh` — lints `marketplace.json` and `SKILL.md`.\n- `scripts/ci/pr_review.py` — auto-review bot. **The LLM half is currently\n  dead**: it called GitHub Models, which GitHub retired on 2026-07-30, so the\n  bot has been running deterministic-only (reachability + format + local\n  dedup) and reports Depth/Fit as \"skipped\". Choosing a replacement backend\n  is deliberately deferred. Contributor language is detected\n  deterministically (Han / Kana regex on PR body) and passed to the LLM\n  as a directive; the LLM never owns language detection.\n- `scripts/ci/publish_review.py` — the privileged half of the review pair.\n  Reads the artifact `pr_review.py` produced, validates it (head SHA must\n  match both the producing run and the PR's current head, labels filtered\n  against an allowlist, body capped) and upserts one marked comment.\n- `scripts/ci/templates/comment.{en,zh,jp}.md` — localized review comments.\n- `.github/workflows/pr-review.yml` — grades a PR; never posts. Two jobs:\n  `verify` runs the PR's own code, `grade` runs the trusted base-branch\n  scripts over the PR's files as data and uploads the result as an artifact.\n- `.github/workflows/pr-review-publish.yml` — posts that artifact from\n  `workflow_run` (base-repo context, write token, never checks out the PR).\n  This split exists because fork PRs get a read-only `GITHUB_TOKEN`, so the\n  old single-workflow bot silently 403'd on every fork PR — which is nearly\n  all of them.\n- `.github/workflows/diff-sentry.yml` — `qazbnm456/diff-sentry` scan of the PR\n  diff for obfuscated payloads, exfiltration sinks, bidi/zero-width evasion\n  and workflow misconfigurations. Fails on `high` and above.\n- `.github/workflows/pr-review-backlog.yml` — dry-run over open PRs (manual,\n  workflow_dispatch). Stashes trusted scripts to `/tmp/awsec-trusted/` before\n  iterating PR refs, so `pr_review.py` always runs from the base branch even\n  when an attacker-controlled PR is checked out.\n- `.github/workflows/health-link-check.yml` — daily lychee scan over the\n  generated READMEs and `data/index.json`; surfaces broken links via a single\n  rolling issue labelled `health/link-check`. Replaces the previous\n  `validate.yml`.\n- `.github/workflows/post-merge-archive.yml` — after merges that touch\n  `data/entries/**`, submits eligible entries (active, no `archive_url` yet,\n  not opted out) to Wayback Machine and commits the resulting `archive_url`\n  back to the YAML with `[skip ci]`. Driven by `scripts/ci/archive.py`.\n- `.github/ISSUE_TEMPLATE/propose-resource.yml` — GitHub Form for proposals.\n- `.github/PULL_REQUEST_TEMPLATE.md` — self-checklist mirroring RUBRIC.md.\n- `.claude-plugin/marketplace.json` — declares the Claude plugin / Skill\n  package distributed via this repo.\n- `skills/awesome-web-security/SKILL.md` — the Skill body. Lives here so the\n  same repo serves humans and AI agents.\n- `RUBRIC.md` — the five-dimension scoring rubric the bot applies; also the\n  contributor self-check reference.\n- `CONTRIBUTING.md` — contributor flow. Treat as authoritative for PR\n  procedure; do not duplicate its contents here.\n\n## Editing rules\n\n- **Never edit `README.md`, `README-zh.md`, or `README-jp.md` directly.**\n  They are regenerated from `data/` by `scripts/generate.py`. Edits will be\n  blown away on the next regeneration.\n- To add or modify an entry, edit `data/entries/<category>.yml`.\n- To add a new category, edit `data/categories.yml` first, then add a new\n  `data/entries/<category-key>.yml`. Run `scripts/verify_anchors.py`\n  afterwards to confirm no external-facing anchor was lost.\n- After any data change, run `python3 scripts/generate.py` to refresh the\n  generated files locally before committing. CI will reject divergence.\n\n## Entry schema\n\n```yaml\n- id: xss-google-app-security                   # kebab-case, unique\n  url: https://www.google.com/...               # required, https preferred\n  title: Cross-Site Scripting – Application Security – Google\n  author:\n    name: Google                                # required if author exists\n    url: https://www.google.com/                # optional\n  category: xss                                 # must exist in categories.yml\n  type: article                                 # article|tool|cheatsheet|video|book|community|payload-list\n  languages: [en]                               # subset of: en|zh|jp|tr|universal\n  difficulty: intro                             # intro|intermediate|advanced\n  date_added: 2017-01-29                        # ISO date\n  archive_url: null                             # filled by post-merge-archive workflow\n  last_checked: null                            # filled by weekly-health workflow\n  fingerprint: null                             # content fingerprint, filled by health\n  status: active                                # active|dead|archived-only|quarantined\n```\n\nOptional fields:\n\n- `raw_rest` is the README description text that follows the title link\n  (the generator emits `- [Title](url) - {raw_rest}.`). It is **public-facing,\n  third-party-readable** content; treat it like user-facing copy.\n  - DO include: a one-sentence factual description of what the resource is,\n    optionally followed by a `Written by [Author](url)` byline.\n  - DO NOT include: references to this project, issue/PR numbers, phrases\n    like \"originally proposed by\", or any internal metadata. Git history\n    already preserves attribution; a third-party reader of the README must\n    not infer that the entry has any historical relationship to this repo.\n  - Leave migrator-written values as-is; only rewrite when the original is\n    wrong or stale.\n- `archive_opt_out: true` skips Wayback Machine archiving for this entry.\n  Set this only when the original author has explicitly asked not to be\n  archived (paywalled content, takedown requests). Defaults to false.\n- `languages: [universal]` is a wildcard meaning \"render this entry in\n  every language README\". Use sparingly; prefer explicit `[en, zh, jp]` when\n  you know the audience exactly.\n\n## Anchor preservation\n\nExternal sites and the ToC both link to `#some-anchor` targets. Renaming or\nremoving an existing anchor silently breaks those links. The CI guard\n`scripts/verify_anchors.py` compares the working tree's anchor set against\nmaster and fails the build if any baseline anchor is missing. Never rename\nan existing anchor; always add new ones for new sections.\n\n## Language policy\n\nProject-authored content is English. Exceptions, where multi-language is\nintrinsic to the artifact:\n\n- `README-zh.md`, `README-jp.md` — translated versions of `README.md`.\n- `data/categories.yml` `title_zh` / `title_jp` overrides, if any are added\n  later (currently the section titles are uniform across languages).\n- `data/entries/*.yml` `title` and `notes` fields preserve the resource's\n  original language (e.g. a Chinese article keeps its Chinese title).\n- `skills/awesome-web-security/SKILL.md` `when_to_use` trigger phrases use\n  multi-lingual keywords so the skill activates on non-English prompts.\n  The SKILL.md body itself remains English.\n- `scripts/ci/templates/comment.{en,zh,jp}.md` — the auto-review bot replies\n  in the contributor's language when detected with high confidence, falling\n  back to English otherwise. Dimension names (`Reachability`, `Format`,\n  `Depth`, `Fit`, `Dedup`) stay in English; they are keys into RUBRIC.md.\n\nEverything else — code, comments, schema field names, templates, CI output,\nlabels, commit messages — is English.\n\n## Multi-language entry routing\n\nA single entry can appear in multiple READMEs. The `languages` field\ncontrols where it shows up:\n\n- New entry, no language hint from the contributor → put it in `[en]` only;\n  ask the contributor if they want it in `zh` / `jp` too.\n- Locale-specific resource (Chinese-language article, Japanese-only forum) →\n  use `[zh]` / `[jp]` only.\n- Truly cross-cultural canonical resource → `[en, zh, jp]` or `[universal]`.\n- Do not force-translate or force-mirror an entry across languages to\n  \"match\" the structure. Each README is allowed to have entries the others\n  don't.\n\n## Handling new resource requests\n\nTwo kinds of inbound requests, both ported into the YAML data model\nthe same way the 2026 backlog was cleared:\n\n**Issue Form submission** (`.github/ISSUE_TEMPLATE/propose-resource.yml`)\n— the contributor filed an issue, not a PR. Port it directly: add the\nentry to `data/entries/<category>.yml`, run `python3\nscripts/generate.py` and the verify scripts, commit to `master` with\n`Closes #<n>` and a `Co-authored-by:` trailer crediting the submitter.\nThey never had a branch, so the co-author trailer is their credit.\n\n**Direct pull request** (contributor edited `README.md` or the YAML\ndirectly) — port on *their* branch so their PR merges with full\nattribution. See CONTRIBUTING.md \"Maintainer notes\" for the six-step\nPath B playbook. Never route a direct PR through Copilot: Copilot\nopens its own PR and closes the contributor's unmerged, destroying\ntheir merged-PR credit.\n\n### Copilot as async fallback\n\nCopilot is the fallback for **Issue Form submissions only**, when the\nmaintainer is unavailable for an extended period and the queue needs\nto keep moving. It is not the standard workflow — the manual port\nabove is. The maintainer still reviews the resulting Copilot PR before\nmerge; Copilot saves the typing, not the judgment. Prompt shape:\n\n```\n@copilot please port this resource into the new YAML data model.\n\nAdd it to `data/entries/<TARGET>.yml` with:\n- url, title, author.name, author.url (from the issue fields)\n- type: <article|tool|cheatsheet|video|book|community|payload-list>\n- difficulty: <intro|intermediate|advanced>\n- languages: [en, zh, jp] unless the resource is locale-specific\n  (then [zh] or [jp]); never [universal] as the sole value without\n  confirming with the maintainer\n- status: active\n\nSet `raw_rest` to a one-sentence factual description of the resource\nitself, optionally followed by a `Written by [Author](url)` byline. Do\nNOT mention this project, the issue number, the PR number, or any\ninternal metadata in `raw_rest`.\n\nEnd the PR body with both:\n  Closes #<n>\n  Co-authored-by: <issue-author> <ID+login@users.noreply.github.com>\n\nRun `python3 scripts/generate.py` and `python3 scripts/verify_schema.py`\nbefore opening the PR.\n```\n\nAdjust `<TARGET>`, `type`, `difficulty`, `languages`, the issue\nnumber, and the co-author identity per case.\n\n## Things not to do\n\n- Do not edit the generated `README*.md` files directly.\n- Do not rename or remove existing anchors in `data/categories.yml`.\n- Do not introduce HTML tags in `data/templates/*.md` beyond `a, b, br, p,\n  img` (the project's markdownlint config).\n- Do not bulk-reorder existing entries — the generator sorts by\n  `date_added`, then by title. To move an entry up, change its\n  `date_added`.\n- Do not commit `data/index.json` edits by hand. It is fully regenerated by\n  `scripts/generate.py`.\n- Do not edit `CONTRIBUTING.md`, `code-of-conduct.md`, or workflow files\n  unless the user explicitly asks.\n- Do not create commits or push unless explicitly asked.\n\n## CI behavior\n\nOn every PR touching `data/**`, a generated README, or the generator\nscripts:\n\n1. Runs `verify_schema.py` and `verify_anchors.py`.\n2. Re-runs `generate.py` and warns if the working tree diverges from the\n   generated output (contributor forgot to regenerate).\n3. Grades each new entry against RUBRIC.md and writes the verdict to an\n   artifact. A PR that only edited a generated README is graded too: the bot\n   reports link reachability plus the YAML-first explanation, in the\n   contributor's language.\n4. `pr-review-publish.yml` picks that artifact up on `workflow_run` and posts\n   a single structured comment, replacing its own previous one, then syncs\n   the advisory labels.\n\nEvery PR, path-filtered or not, is also scanned by diff-sentry.\n\nThe bot never auto-merges and never auto-rejects.\n\n## When in doubt\n\nMatch the spirit of CONTRIBUTING.md and RUBRIC.md. Ask the user if a change\ncrosses into territory not described here (new language version, new entry\nschema field, new section taxonomy).\n\n<!-- File: .claude-plugin/marketplace.json (Tokens: ~230 | Category: marketplace) -->\n{\n  \"$schema\": \"https://anthropic.com/claude-code/marketplace.schema.json\",\n  \"name\": \"awesome-web-security\",\n  \"description\": \"Curated, always-fresh web security learning resources for AI agents and security researchers.\",\n  \"owner\": {\n    \"name\": \"qazbnm456\",\n    \"email\": \"qazbnm456@gmail.com\"\n  },\n  \"plugins\": [\n    {\n      \"name\": \"awesome-web-security\",\n      \"description\": \"Looks up curated web security learning resources (XSS, SQLi, CSRF, SSRF, OAuth/JWT, recon, evasion, tools, CTF). Filters by topic, difficulty, language, and resource type. Returns top references with archive fallbacks. Defensive use only; refuses unauthorized targeting.\",\n      \"version\": \"1.0.0\",\n      \"category\": \"development\",\n      \"source\": \"./\",\n      \"homepage\": \"https://github.com/qazbnm456/awesome-web-security\",\n      \"skills\": [\"./skills/awesome-web-security\"],\n      \"strict\": false\n    }\n  ]\n}\n</yakaai_skills>"}