<feed xmlns='http://www.w3.org/2005/Atom'>
<title>vyos-documentation.git, branch claude/vyos-docs-security-remediate-2cff61</title>
<subtitle>VyOS readthedocs (mirror of https://github.com/vyos/vyos-documentation.git)
</subtitle>
<id>https://git.amelek.net/vyos/vyos-documentation.git/atom?h=claude%2Fvyos-docs-security-remediate-2cff61</id>
<link rel='self' href='https://git.amelek.net/vyos/vyos-documentation.git/atom?h=claude%2Fvyos-docs-security-remediate-2cff61'/>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/'/>
<updated>2026-07-28T02:36:57+00:00</updated>
<entry>
<title>security: normalize percent escapes per run, not per segment</title>
<updated>2026-07-28T02:36:57+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@vyos.io</email>
</author>
<published>2026-07-28T02:36:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/commit/?id=0c9348035b583f3cd5fca72937a7ec1a61d7df45'/>
<id>urn:sha1:0c9348035b583f3cd5fca72937a7ec1a61d7df45</id>
<content type='text'>
Round-2 adversarial finding (Codex, medium): whole-segment decode meant
one malformed escape (a%20b%zz) threw for the segment and double-encoded
the valid escapes beside it. encodeSegment now decodes+re-encodes each
well-formed %HH run independently; literal spans (including a bare '%')
always pass through encodeURIComponent, so taint neutralization holds
unconditionally; a run decoding to invalid UTF-8 stays verbatim (already
pure %HH text).

workers suite 108/108 (+2 discriminating regression tests).

🤖 Generated by [robots](https://vyos.io)
</content>
</entry>
<entry>
<title>security: normalize pre-existing percent escapes in encodePath</title>
<updated>2026-07-28T02:24:34+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@vyos.io</email>
</author>
<published>2026-07-28T02:24:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/commit/?id=cfca705f325a073c00e221a080eff968112d7653'/>
<id>urn:sha1:cfca705f325a073c00e221a080eff968112d7653</id>
<content type='text'>
Adversarial-review finding (Codex, medium): location.pathname returns
well-formed escapes verbatim, so blind encodeURIComponent double-encoded
them (%2E -&gt; %252E), broke the HEAD probe on escaped deep links, and
dumped the user at the version root. Each segment is now decoded first
(malformed escapes keep the raw segment — no throw), then re-encoded to
canonical single encoding. Decoding cannot resurrect dot-segments:
the URL parser resolves '.'/'..' and their percent-encoded forms during
navigation, so pathname never presents them (verified against the WHATWG
parser in Node).

workers suite 106/106 (+2 regression tests, mutation-verified).

🤖 Generated by [robots](https://vyos.io)
</content>
</entry>
<entry>
<title>security: remediate CodeQL code-scanning alerts (picker XSS sinks, test sanitization, vendored DataTables exclusion)</title>
<updated>2026-07-28T01:29:23+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@vyos.io</email>
</author>
<published>2026-07-28T01:06:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/commit/?id=957af46300afc91dee324100d9dc0ad91c4a144f'/>
<id>urn:sha1:957af46300afc91dee324100d9dc0ad91c4a144f</id>
<content type='text'>
Remediates all 11 open CodeQL alerts on the default branch:

- version-picker.js (js/xss-through-dom, alerts 1-3): percent-encode every
  DOM-derived path component (select.value, parsed location segments) at URL
  construction time via encodePath()/langUrlFor(), and tighten the
  parseLocation slug charset to [A-Za-z0-9._-]. No-op on legitimate sphinx
  slugs — URLs stay byte-identical (asserted by tests).

- workers/apex/test/manifest.test.ts (js/incomplete-multi-character-
  sanitization, alert 6): strip HTML comments from the root.html fixture
  repeatedly to a fixpoint instead of a single pass.

- docs/_static/js/datatables.js (alerts 4,5,7-11): excluded from CodeQL
  analysis via .github/codeql/codeql-config.yml (new codeql-cfg-path input
  to the fleet reusable workflow). The file is vendored stock DataTables
  1.11.5; the flagged helpers are display/sort normalization, not
  sanitization boundaries. Excluding keeps the vendored copy byte-identical
  to upstream instead of hand-patching it.

Adds 9 picker tests (hostile-input encoding + slug-charset accept/reject);
workers suite 103/103 green.

🤖 Generated by [robots](https://vyos.io)
</content>
</entry>
<entry>
<title>Merge pull request #2165 from vyos/claude/remove-superpowerdocs-ba80b9</title>
<updated>2026-07-28T00:31:47+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@andamasov.com</email>
</author>
<published>2026-07-28T00:31:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/commit/?id=a16c5ef2654ab7bc2a5a54494880543f91c5d89d'/>
<id>urn:sha1:a16c5ef2654ab7bc2a5a54494880543f91c5d89d</id>
<content type='text'>
docs: exclude superpowers/ from the Sphinx build</content>
</entry>
<entry>
<title>docs: exclude superpowers/ from the Sphinx build</title>
<updated>2026-07-28T00:13:48+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@vyos.io</email>
</author>
<published>2026-07-28T00:13:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/commit/?id=a9dc16aac2a7e7a6e5e4bb1c19897b3d707ba4d1'/>
<id>urn:sha1:a9dc16aac2a7e7a6e5e4bb1c19897b3d707ba4d1</id>
<content type='text'>
`docs/superpowers/` holds Claude Code plugin-generated internal design
specs and plans, not user documentation. Adding `superpowers` to
`exclude_patterns` guards against Sphinx ever picking the directory up
and publishing it should it reappear in the source tree.

Guard only — the content itself was already removed in 3ab97e71 and
abb8be5b.
</content>
</entry>
<entry>
<title>Merge pull request #2160 from vyos/claude/smoke-hardening-2</title>
<updated>2026-07-22T16:04:39+00:00</updated>
<author>
<name>Yevhen Bondarenko</name>
<email>evgeniy.bondarenko@sentrium.io</email>
</author>
<published>2026-07-22T16:04:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/commit/?id=56fe7c650ea2b7a1f506eb5823855f02e379f38e'/>
<id>urn:sha1:56fe7c650ea2b7a1f506eb5823855f02e379f38e</id>
<content type='text'>
docs-gates: re-land HTTPError close + detail logging; widen smoke retry envelope</content>
</entry>
<entry>
<title>docs-gates: hard-bound the smoke deadline (cap probe timeout + inter-round sleep to remaining budget)</title>
<updated>2026-07-22T15:53:45+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@vyos.io</email>
</author>
<published>2026-07-22T15:53:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/commit/?id=cef13a0cd6aa64ab2a9b30fe1199d60939846357'/>
<id>urn:sha1:cef13a0cd6aa64ab2a9b30fe1199d60939846357</id>
<content type='text'>
Codex adversarial finding: DEADLINE_SECONDS was only checked BEFORE each op, so a
probe or sleep starting at 479s could overshoot to ~510s — 480 was a soft target,
not a hard bound.

Make it hard: run() now computes an absolute deadline = start + DEADLINE_SECONDS
plus a _remaining() helper. The per-probe socket timeout is capped to
min(PROBE_TIMEOUT_SECONDS, max(1, remaining)) — the previously hardcoded 30 is now
the PROBE_TIMEOUT_SECONDS constant; a probe with &lt; 1s of budget is skipped and
counted unresolved. The inter-round sleep is capped to
min(RETRY_SLEEP_SECONDS, remaining) and is skipped entirely when the budget is
exhausted (falling into the existing deadline path). No body-read-level deadline is
added — pages are small, so the socket-op timeout bounds reads adequately.

Deadline-path failure accounting is unchanged. Tests: the probe timeout is capped
to the remaining budget (fake opener records the timeout it was opened with); the
inter-round sleep is capped to the remaining budget (sleep spy); the existing suite
stays green.

🤖 Generated by [robots](https://vyos.io)
</content>
</entry>
<entry>
<title>docs-gates: widen smoke retry envelope for worker-version propagation (5 rounds x 30s)</title>
<updated>2026-07-22T15:39:42+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@vyos.io</email>
</author>
<published>2026-07-22T15:30:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/commit/?id=95b8a4115439826e7dff767bf3515684535d0783'/>
<id>urn:sha1:95b8a4115439826e7dff767bf3515684535d0783</id>
<content type='text'>
The merge-triggered smoke run for the round-based retry work failed on a
worker-version propagation race that outlasted the 3-round x 20s envelope: all
probes were served the previous SHA through rounds 1-2 and one path (cli.html)
was still stale at round 3 (2 sleeps x 20s = 40s insufficient).

Widen to MAX_ROUNDS=5 / RETRY_SLEEP_SECONDS=30 -&gt; 4 inter-round sleeps x 30s =
2 min, covering the observed 1-2+ min propagation waves. The green path is
unaffected (no retries -&gt; zero added time); DEADLINE_SECONDS=480 still bounds the
worst case. Tests read the constants dynamically (monkeypatch), so none pin the
old literals.

🤖 Generated by [robots](https://vyos.io)
</content>
</entry>
<entry>
<title>docs-gates: close HTTPError response; name failed assertion in smoke logs (CR round 2)</title>
<updated>2026-07-22T15:29:29+00:00</updated>
<author>
<name>Yuriy Andamasov</name>
<email>yuriy@vyos.io</email>
</author>
<published>2026-07-22T15:13:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/commit/?id=6ae607d4c37f2c61a5b06fc5649e46dac63eaac8'/>
<id>urn:sha1:6ae607d4c37f2c61a5b06fc5649e46dac63eaac8</id>
<content type='text'>
Two accepted GitHub-side CodeRabbit findings on the smoke gate:

Close the HTTPError response stream: _probe_once read the non-2xx body via
e.read() but never closed the HTTPError, which is file-like and owns the
response socket — leaking it / raising ResourceWarning on the expected-404 path
every run. The read is now wrapped in "with e:" INSIDE the crash-containment
nesting, so the stream is closed even if the read raises (still yielding the
retryable transport-error result, never a traceback).

Name the failed assertion in retry/fail logs: _probe_once now returns a compact
`detail` naming which check failed ("status" / "docs-build" / "apex-build" /
"search-mount", multiple joined by "+", or the transport error text; None when
ok) instead of a bare transport-only field. SMOKE-RETRY / SMOKE-FAIL lines gain
`detail=&lt;...&gt;` alongside the existing status / docs-build fields, so an apex-build
or search-mount failure no longer logs an opaque "status=200 docs-build=&lt;sha&gt;".
ok-path behavior and the JSON / exit contract are unchanged.

Tests: HTTPError stream is closed on the happy-404 path and when the read raises
(RecordingBody close recorder); apex-build-only and search-mount-only failures
name their detail in the logs; _probe_once joins multiple failed checks with "+".
Removed the now-unused _http_error helper.

🤖 Generated by [robots](https://vyos.io)
</content>
</entry>
<entry>
<title>Merge pull request #2159 from vyos/claude/smoke-hardening</title>
<updated>2026-07-22T15:18:19+00:00</updated>
<author>
<name>Yevhen Bondarenko</name>
<email>evgeniy.bondarenko@sentrium.io</email>
</author>
<published>2026-07-22T15:18:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/vyos/vyos-documentation.git/commit/?id=a083130560c6c02fc0f21bb2e80c20aa9a21de42'/>
<id>urn:sha1:a083130560c6c02fc0f21bb2e80c20aa9a21de42</id>
<content type='text'>
docs-gates: smoke per-probe retry + explicit UA; workers: broaden asset-ext classification</content>
</entry>
</feed>
