Files
mangaBookmark/backend
sulthan b9f9aea82c docs: secure-coding rules for agents, and refresh stale AGENTS.md top-matter (#16)
Two doc commits: a new secure-coding rules section, plus a fix for top-matter the rebrand left stale.

## `9156525` — secure-coding rules

`AGENTS.md` carried two security invariants (bearer auth, CORS) but nothing about the code an agent actually writes here. That is the gap worth closing: measured rates for AI-generated web/backend code are ~40% vulnerable (Pearce et al.), 45% failing security tests (Veracode 2025), and users *with* assistants shipped SQLi at 36% vs 7% for the control group (Perry et al., Stanford). The failure classes cluster on broken access control, injection, session/error handling and invented dependencies — all live surfaces in this repo.

Rules were **extracted, not pasted**. Every one names a guard that already exists in-tree, so the instruction is *match this*, not *invent something*:

| Rule | Existing anchor |
| --- | --- |
| parameterized SQL only; constants may concatenate | `store.go` — all queries use `?` |
| `html/template` only; no `template.HTML` on stored data | `web.go:85` |
| client-supplied URLs pass the fetch gate | `poller.go:144 fetchableSeriesURL` |
| cap remote bodies | `fetch.go:16 maxBodyBytes` |
| `subtle.ConstantTimeCompare`, never `==` | `middleware.go:22`, `session.go:61` |
| generic error out, detail to log, never log the token | `web.go:151` |
| `X-Forwarded-Proto` for Secure; **rightmost** XFF for IP | `session.go:68,101` |
| cookie flags; expiry checked before signature | `session.go:72-94`, `Verify` |
| validate at handler boundary | `handlers.go:48` `MaxBytesReader` 64 KB, 400 on bad key/status/kind |
| site strings via `el({text})`, never `{html}` | `el()` in both userscripts |
| `fetch()`/`authHeaders()` → `API_BASE` only | existing `authHeaders` |
| `localStorage` = cache/queue, never credentials | shared with site JS |

Plus a dependency rule (stdlib first; verify a package exists before adding — ~20% of LLM-proposed packages don't resolve, which is the slopsquatting vector) and a review gate marking auth/CORS/session/crypto/fetch-gate as security-critical.

Deliberately **excluded**: container signing, k8s admission control, IaC scanning, PII/HIPAA/PCI, C/C++ memory safety. Per OpenSSF's guide for AI assistant instructions, irrelevant rules make a model generate code compensating for attacks that cannot happen. None of those apply to a single-user Go + SQLite + userscript stack.

Sources: OWASP AISVS 1.0 Appendix C, OWASP Top 10 / ASVS v5, OpenSSF *Security-Focused Guide for AI Code Assistant Instructions* (2025-08-01).

## `5d4d890` — stale top-matter

The rebrand rewrote root `AGENTS.md` as a compression pass and switched Bromite -> Violentmonkey, but left the project described as a manga-only tracker over two sites. Six sites, two libraries and two userscripts now exist.

Root `AGENTS.md`:

- *What this is* names both scripts with their site lists, the `kind` column, and the `<site>:<series_id>` key shape.
- Origins constraint generalised past Asura/Demonic.
- Records that **kagane and novelfull are reliably Cloudflare-challenged** and browser-polled over CDP. Without it that bullet list reads as contradicting the code, since the paragraph above asserts blocking is "not universal — and not reliably reproducible".
- Diagram says two userscripts.

`backend/AGENTS.md` — two instances of the same defect, found while verifying the above:

- Store key list gained `novelfull|lightnovelworld` and the `kind` column.
- **`NOVEL_USERSCRIPT_PATH` documented** — it shipped in `main.go:150` undocumented.

The dated Cloudflare paragraph is left verbatim: it is a timestamped observation ("Verified 2026-07-26"), so rewriting it would falsify a record rather than update it. `userscript/AGENTS.md` is untouched; it already documents both novel adapters and the `LIBRARY`/`STORE_PREFIX` split.

## Verification

Docs-only, no code touched. Every code reference above was read at `4229c17` before being cited — the fetch gate, body cap, constant-time compares, cookie flags, handler validation, `el()` helper and both route registrations. No invented line numbers.

## Not addressed here

The `API_TOKEN` literal is committed in plaintext in both userscripts and in their `@downloadURL`/`@updateURL` lines. The new rules say not to propagate it, but the actual remedy is rotation plus build-time substitution, since the value is already in git history. Separate change; flagging it so it does not get lost.

Reviewed-on: #16
Co-authored-by: Sulthan Zaki <sultankiki05@gmail.com>
Co-committed-by: Sulthan Zaki <sultankiki05@gmail.com>
2026-08-06 20:07:34 +07:00
..