Skip to main content

webseclist-archive-references

Builds or refreshes the Markdown-plus-PDF archive of resources cited by finalized Top 10 Web Hacking Techniques lists and bounded YYYY-ai.md preliminary collections, under archived-references/md/COLLECTION/ and archived-references/pdf/COLLECTION/. Use when a finalized or AI-generated list changes, a cited source needs preservation or repair, preliminary citations must be promoted or pruned when the real list arrives, or a review/validation queue needs work. This workflow reads source lists and never edits them.

소스 정보

저장소
irsdl/webhacklist
최근 소스 활동
2026년 9월 18일 14:55
감지된 SKILL.md 언어
영어
스타
847
포크
133

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
9 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
webseclist-archive-references
description
Builds or refreshes the Markdown-plus-PDF archive of resources cited by finalized Top 10 Web Hacking Techniques lists and bounded YYYY-ai.md preliminary collections, under archived-references/md/COLLECTION/ and archived-references/pdf/COLLECTION/. Use when a finalized or AI-generated list changes, a cited source needs preservation or repair, preliminary citations must be promoted or pruned when the real list arrives, or a review/validation queue needs work. This workflow reads source lists and never edits them.
## Source security Before handling third-party material, read and follow [the shared source-security policy](../../source-security.md). It governs sandboxed reading/conversion, trusted-policy reviews and validation before any source-derived action. These requirements apply to this entire workflow, including retries, imports and bulk work; no unsafe host fallback is permitted. # Archive the cited resources as Markdown and PDF ## Related sources Apply [research stories and related sources](references/related-sources.md) whenever researching, adding, updating, archiving or reviewing a reference. It defines the maintained relationship registry, source roles, per-source preservation, linked media and corpus migration. ## What this is This repository is a reading list: finalized Markdown files (`2006.md` through `2025.md`, plus `2016-17.md`) and explicitly marked preliminary files such as `2026-ai.md`, each containing links to web-hacking research. This skill turns those links into a durable local archive so a technique survives the article that described it going offline. For every cited resource that is not a video, the archive keeps: - a **Markdown copy** at `archived-references/md/<year>/<slug>.md`, with an attribution block naming the source, and - a **PDF copy** at `archived-references/pdf/<year>/<slug>.pdf` - our Markdown printed offline, or, when the source was already a PDF, the original PDF itself. The two format trees are parallel on purpose: the binary PDFs stay out of the Markdown tree, so diffs, sparse checkouts and exclusion rules can treat prose and print separately. `refslib/collections.py` owns the layout - never move a file between folders by hand. A recording is not archived - it is a third-party stream this repository cannot hold - but where the same research was also GIVEN AS A TALK, the reference records a link to it and how sure the archive is that it is the right one. See *The talk behind the research*. Every Markdown file's frontmatter follows **Google's Open Knowledge Format (OKF) v0.2** - `type`, `title`, `resource`, `tags`, `generated`, `verified`, `status`, `stale_after` and `sources` - with the archive's own fields kept as the custom keys the specification permits. `verified` is deliberately absent until the validation gate has run: under OKF, absence IS the honest statement. The local spec note is `references/okf-v0.2.md`; refresh it only if the specification moves. ```text year lists -> archive inventory -> acquisition -> Markdown -> PDF ``` ## Never download a program **No executable is ever fetched, on any operating system.** A program is not a document: the technique lives in the write-up, so downloading the binary gains the archive nothing and puts an executable on the maintainer's disk and into the content store. `refslib/kinds.py` gives these the kind `executable` before any other rule runs, and acquisition records them link-only. Two parts of the list are the ones people argue with, so they are the ones to remember: - **A format that looks harmless is still a program.** `.chm` reads as a help file and is a compiled, scriptable Windows binary. Judge a format by what it can execute, never by how mild its name sounds. - **An archive is refused too** - `.zip`, `.tgz`, `.7z`, `.iso` - because what is inside is unknown until it is unpacked, and unpacking is how an executable arrives without ever being named. Source TEXT is not an executable and stays archivable: `.py`, `.ps1`, `.cs` are read as text and never run. If a citation points ONLY at a download, archive the write-up that describes it and leave the download as a link. ## Antivirus deletes archived exploit text The corpus is exploit research, and a scanner reads it as what it describes. One deleted **233 objects out of the content store** - leaving 116 references with a perfectly good Markdown file on disk and nothing behind it, because the store holds the evidence while `archived-references/` holds the rendering. `verify` catches this as `missing store object`, and `index` lists every one of them on `store-gaps.md`; no other rule notices, because they all ask whether a document was PRODUCED. Recovery is a re-fetch, not a re-render: `check --missing-store` first, then `acquire --missing-store --force --refetch` for the sources that still answer and `wayback --missing-store` for those that do not. **A store gap is not a needs-work row.** Those references ARE archived - their Markdown and PDF are published and readable - and only the evidence behind the files is gone. Listing them as unfetched work put 1,011 fully archived references on `document-gaps.md` and buried the two that genuinely had no document. Keep the two reports apart: `document-gaps.md` answers *could we not get the document*, `store-gaps.md` answers *can we still show what the document was made from*. Exclude the store directory AND the repository from the scanner before a long run, or the next sweep quietly undoes it. ## The one rule **Never edit a year list.** Nothing here writes `20xx.md`. This workflow READS them and writes the archive under `archived-references/`. `verify` fingerprints every year file before a run and FAILS if one changed during it. If you want to add, remove or fix a link in a list, that is a hand edit to the list, done separately - archiving is never a required follow-up to it. A reference is filed under the source collection that cites it. That decision lives in one place, `refslib/collections.py`: a file cited by `2019.md` lands in `archived-references/md/2019/` (its PDF in `archived-references/pdf/2019/`), while `2026-ai.md` lands in parallel `2026-ai/` folders. A reference cited by more than one collection is filed under the first. Never move a file between year folders by hand. ### Preliminary collections Tracked files matching `YYYY-ai.md` are discovered automatically. They must contain exactly one ordered marker pair: ```text <!-- archived-references:start --> ... preliminary research bullets ... <!-- archived-references:end --> ``` Only links inside that boundary are archive input. Scoring notes, watchlists and dropped candidates outside it are intentionally ignored. Use `--collection YYYY-ai` with `check`, `acquire` and `pdf` to process only that provisional tree. ## The pipeline Every command is `python tools/references/refs.py <command>`. Only `check`, `check-browser`, `acquire`, `papers`, `images`, `wayback`, `insecure` and `transcripts` touch the network; `pdf` needs a browser but never a network. ```text python tools/references/refs.py harvest # cited URLs in the year lists python tools/references/refs.py sync # citations/folders, offline python tools/references/refs.py check # health of each URL [NETWORK] python tools/references/refs.py check-browser # only the walled rows [NETWORK] python tools/references/refs.py acquire # preserve, convert, render [NETWORK] python tools/references/refs.py papers # the article's own PDF [NETWORK] python tools/references/refs.py images # its figures, re-encoded [NETWORK] python tools/references/refs.py pdf # a PDF for each md [BROWSER] python tools/references/refs.py translate # anything not in English python tools/references/refs.py digest # a summary and tags per document python tools/references/refs.py index # regenerate the folder index python tools/references/refs.py verify # the offline gate ``` `digest` is the one step the tool cannot do for you, and the one a run most easily forgets: the archive can tell you a document is 40KB of prose, never that it is about a parser differential. Skip it and the reference is preserved but unfindable - the website has nothing to show and nothing to search. `papers` and `images` run BEFORE `pdf` and decide what it publishes. A reference that is already a PDF is copied; otherwise the publisher's own PDF of the article wins if `papers` found one; otherwise our Markdown is printed, carrying whatever figures `images` preserved. `images` never stores what it fetched - every image is decoded and re-encoded, which is what strips metadata, appended payloads and anything hidden in the low bits, and SVG is refused rather than rasterised. ### Ordinary sync, after a year list changed ```text python tools/references/refs.py check --prune python tools/references/refs.py check-browser python tools/references/refs.py acquire python tools/references/refs.py papers python tools/references/refs.py images python tools/references/refs.py pdf python tools/references/refs.py translate --prepare # then translate, then --apply python tools/references/refs.py index python tools/references/refs.py verify ``` For a new preliminary collection, keep the same sequence but scope the network and PDF stages with `--collection YYYY-ai`. ### Promote a preliminary collection when the real list arrives Keep both source files long enough to review their normalized URL sets: ```text python tools/references/refs.py compare 2026-ai 2026 ``` After a maintainer has accepted the finalized `2026.md` and deliberately removed `2026-ai.md` from the repository and app registry, reconcile the archive: ```text python tools/references/refs.py sync --prune --refile --prune-files python tools/references/refs.py pdf --force --collection 2026 python tools/references/refs.py index python tools/references/refs.py verify ``` `sync` is offline. Shared URLs retain their manifest record and stored bytes; their Markdown files move from `2026-ai/` to `2026/` with refreshed `cited_by` frontmatter. PDFs are regenerated from the refiled Markdown or copied again from their preserved original bytes, so none can retain a preliminary citation. URLs found only in the removed preliminary file leave the manifest, and `--prune-files` removes their published files. The content-addressed store is intentionally not garbage-collected: it is recovery evidence, not the public archive tree. `acquire` without `--force` only processes references that have no file yet, and `pdf` without `--force` only makes PDFs that do not exist yet, so this is cheap to repeat. **One `refs.py` command at a time.** Every command loads the whole manifest at start and saves it whole at exit, so the last writer wins: a long `pdf` run finishing after a batch of `import`s silently erased every import record while the files stayed on disk. Never run two commands concurrently - background a long run only when nothing else will touch the archive until it finishes. **Set `WEBSEC_REFS_STORE`** to a durable directory first (see below). **Do not stop at `acquire`.** A newly fetched foreign-language page renders into a complete-looking file its reader cannot read, so translation belongs in the same run that fetched it, and `verify` warns while any document is untranslated. ### The store: set it before every run ```text export WEBSEC_REFS_STORE=/some/durable/path # bash $env:WEBSEC_REFS_STORE = "D:\some\durable\path" # PowerShell ``` Every fetched byte is content-addressed into this store, and the Markdown/PDF in `archived-references/` reference it by hash. Without the variable the tool falls back to a git-ignored workspace cache, which `git clean -xfd` would destroy - so a page that is already gone online would be lost. `verify` warns whenever the store is that fallback. ## Making PDFs `pdf` gives every archived reference a self-contained PDF in the `pdf/<year>/` tree, parallel to its Markdown. - It prints **our archived Markdown**, converted offline to HTML by `refslib/makepdf.py`, using headless Chromium only inside the locked-down toolbox container. No host browser or host browser profile is used. The container has no network while printing, no third-party page script runs, and images become labelled links rather than remote `<img>`. - A source that was **already a PDF** (a whitepaper, a conference paper) is copied verbatim from the content store instead of re-rendered, so its own typesetting survives. - **A video is skipped** - a talk is not a page. `config.json -> pdf.skip_kinds` controls this, and `config.json -> layout.pdf_tree` names the `pdf/` tree. - It needs Docker for Markdown-origin PDFs. With no container runtime, PDF-origin sources are still copied and everything that must be rendered is skipped with a clear message. Do not work around that by launching Chrome or Edge on the host. `refs.py pdf --only <substring>` does one reference; `--force` remakes existing PDFs (after the Markdown changed). **`pdf --stale` UNSCOPED IS A CORPUS-WIDE REPRINT, and its selector is file mtimes.** One of the four staleness tests is `md newer than pdf`, so anything that touches Markdown timestamps without changing a byte - a branch switch, a fresh clone, a checkout - makes the whole archive look stale. A run meant to refresh the two documents `attribution --rewrite` had just re-published reprinted 536 PDFs before it was stopped, every one of them differing from its committed version only in the timestamps a PDF embeds. Scope it: `pdf --stale --only <substring>`, or `pdf --only <substring> --force` for a reference you just changed. If an unscoped run does get away, the manifest is the thing to check - `pdf` saves it in batches, so a run killed early leaves the entries untouched and `git checkout -- archived-references/pdf` restores the tree without disturbing new files, which are untracked. ## When a plain fetch is not enough The hard-won recovery routes from the upstream tool all still apply - the corpus is the open web either way. The route-by-route playbook, with its commands and traps, is in [references/recovery-routes.md](references/recovery-routes.md). Read it before working any reference the ordinary HTTP route does not deliver cleanly: - an app shell, sign-in redirect or waiting page -> the Docker browser ladder (`check-browser`); never a host browser - a video or PoC citation -> find, verify and archive its WRITTEN counterpart, then record the clip as `derivative` - a dead URL, or a citation pinned to a wall or shell capture -> a better Wayback snapshot (`wayback`), nearest its date; use `--replay-url` when known - a live landing page with a paper, code and slides -> preserve the full paper with `acquire --linked-document-url`; keep distinct sibling sources in the related-source registry. Use `--also-at` only for another location of the SAME document. The cited landing URL remains the identity. An ABSTRACT page needs this too and nothing will ask for it: it extracts well over the content floor and grades as research, so acquisition succeeds and the archive publishes the abstract - an expired certificate -> `insecure`, then `acquire --force`, then `images --insecure` for the figures on the same host - no useful CDX path -> bounded historical-path discovery with the pinned Docker waymore route (`historical-urls`), then verify each candidate - a Wayback-wrapped URL -> its kind is the CAPTURED page's kind, never the wrapper host's - a GitHub advisory, blob or issue -> the public API, never the rendered shell - captions, expired certificates, unreadable source PDFs -> the container sandbox (`transcripts`, `insecure`, `pdf-text`, `pdf-pages`) - a genuine scan or rendered deck -> page-image transcription with subagents Three rules from that playbook bind every session that touches the archive, so they stay here: - **`stored` MEANS A FILE WAS WRITTEN, NOT THAT IT IS THE DOCUMENT.** Every outcome count this tool prints is about the fetch, and the three ways an acquisition goes quietly wrong all report `stored`: | Symptom | What happened | Route | |---|---|---| | 3-8KB where a paper would be 100KB+ | the abstract page, not the paper | `acquire --linked-document-url` | | `title:` is `Preprint`, `Code`, `Paper` | the citation's link text, because the document declared no title | `decisions[url].title` | | prose reading `signicant`, `congur` | the font's ligatures were deleted | `acquire --force` (routes to poppler) | Read the character count `acquire` prints against what the source should hold, and open the first page of what it wrote. None of these reaches any gap report, because all three ARE archived - a document exists, and it is the wrong one or a damaged one. `verify` will not tell you either. - **A faulty capture goes on `document-gaps.md` the moment it is found.** Whenever a capture is discovered to be faulty - the manifest advertises a Markdown or PDF that is not in the tree, the file holds the wrong page (a parked or taken-over domain, a consent wall, a homepage or the site's chrome instead of the article), or the bytes behind a file are gone - record it before the session ends so it is listed for recapture. `document-gaps.md` is GENERATED state: never edit it by hand, and never leave the finding as a session note or an app-side workaround. The record is the manifest: set the entry's `content_gap` to `faulty capture: <what is wrong>; <remedy> (reported <date>)` - or, inside this workflow, let `verify`/`check` record it - then regenerate with `python tools/references/refs.py index` (`WEBSEC_REFS_STORE` set, as always) so the entry appears with its reason and remedy. This rule binds every session that touches the archive, not only this workflow: work on the year lists or on the browsing apps that stumbles over a bad capture files it here too. - **One research story can have several separately credited sources.** Existing same-line companions establish membership. Additional papers, parts, recordings and analyses belong in the maintained related-source registry described above; they inherit the story’s citation without rewriting historical year lists. Each written source has its own archive record and available copies. ## Importing documents obtained by hand Read [the manual import procedure](references/manual-imports.md) before importing hand-obtained documents, repairing an import, or changing its title. ## Grades, and what gets no file Every archived reference is graded in the manifest (this does NOT change its folder - the year does): - **research** - a document that carries technique. What the archive is for. - **records** - a record ABOUT a product rather than research: a CVE row, a vendor advisory, release notes, a package page, a talk with no transcript, a stub. Kept, and marked. - **excluded** - no file at all, with the reason recorded so the next run skips it: a broken capture (a bot wall, a consent gate, a 404 that answered), a URL that was never a research citation, or a maintainer decision. Two categories no rule can safely decide - a page that restates a source already archived, and a tool's usage page with no technique - are found with `refs.py report --candidates` and written by hand into `decisions` in `tools/references/overrides.json`. No rule overwrites a decision, and a skip is not fetched again. ## The generated folder ```text archived-references/ README.md the index, grouped by year (the only discovery route) document-gaps.md ONLY what could not be archived, with reasons and remedies store-gaps.md archived references whose stored bytes went missing excluded.md everything kept with NO document, and why manifest.json the record of record history.jsonl the append-only journal md/2006/ ... 2025/ finalized archived references as Markdown, per year md/2026-ai/ a bounded preliminary collection, when present pdf/<collection>/ PDF copies in a tree parallel to md/ ``` ### Always rebuild the work queue after archiving **No archive run is finished until `index` has run after the final archive mutation.** `document-gaps.md`, `README.md`, `excluded.md` and `store-gaps.md` are generated views of the final manifest *and the active content store*. Running `index` without `WEBSEC_REFS_STORE` set reads the empty fallback cache and reports the whole archive as store gaps. An index made halfway through a run is stale as soon as a later `acquire`, `wayback`, `import`, `translate`, `pdf`, pointer repair, fault report or manifest correction changes that state. Run this once nothing else will write the archive: ```text WEBSEC_REFS_STORE=<durable-store> python tools/references/refs.py index python tools/references/refs.py verify ``` `document-gaps.md` is the fetch queue and nothing else: a reference belongs there only while the archive could not get its document - a failed acquisition, a stub or metadata-only capture, or a filed faulty capture. Anything with a good published document stays off it, whatever else is wrong with the record. Use `index --prune-files` when a recovery changed a slug, replaced a faulty capture, refiled a collection or otherwise left generated files that the final manifest no longer claims. Never edit `document-gaps.md` by hand. If `verify` or a final review discovers a fault and you correct `content_gap` or any other manifest field, the correction is another archive mutation: run `index` again so `document-gaps.md` contains the actual remaining work before handing off. ## Translation is a stage of the pipeline, not an afterthought Check for foreign-language documents after every acquisition. Read [the translation procedure](references/translation.md) before preparing, applying or recovering translations; only genuinely foreign prose gets a translation. ## Naming the researcher Read [the attribution procedure](references/attribution.md) when extracting or publishing document-derived bylines. Credit only names supported by the source.
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기