Two security findings deferred from the v0.5.0 review (PR #15). Both are defense-in-depth, not active exploits — but worth shipping.
1. Markdown link-context escaping in renderer.py
_md_escape strips <, >, |, newlines but is not aware of markdown link syntax. If an HA entity / area / device is renamed to:
Lampe](javascript:alert(1))
…and that name is interpolated into a [label](url) construct, the rendered markdown becomes:
[Lampe](javascript:alert(1))](#area-wohnzimmer)
BookStack itself sanitizes URLs in markdown links (javascript: schemes are stripped on render), so this is not actively exploitable today. We should still:
- Escape
] inside link text
- Reject non-
http(s) / non-# URLs in link targets
Files: custom_components/bookstack_sync/renderer.py — find every place a name is interpolated into a markdown link.
2. BookStack URL appears in error logs
When the BookStack server hangs up mid-sync, aiohttp's ClientResponseError includes the full request URL in its repr. We catch that and log via LOGGER.exception(...), so the BookStack hostname ends up in home-assistant.log.
The token is NOT logged — it's in the Authorization: header, never in the URL. Verified during the v0.5.0 security review.
This is "URL exposure", not credential leak. Mitigation options:
- Wrap aiohttp exceptions in
BookStackApiCommunicationError with a sanitised message that strips the URL
- Or just add a README note: "the HA log will contain your BookStack URL — redact before sharing"
Files to audit: api.py, config_flow.py, coordinator.py, sync.py — every LOGGER.exception(...) and LOGGER.error("...: %s", err).
Acceptance
- Add a regression test: render a planned page whose entity name contains
](javascript:alert(1)) — verify the resulting markdown has no executable link.
- Add a regression test for the log-scrubbing approach if we go that route (fake aiohttp error → assert URL not in formatted log message).
- Bump version to 0.5.1, keep quality_scale at gold.
Two security findings deferred from the v0.5.0 review (PR #15). Both are defense-in-depth, not active exploits — but worth shipping.
1. Markdown link-context escaping in renderer.py
_md_escapestrips<,>,|, newlines but is not aware of markdown link syntax. If an HA entity / area / device is renamed to:…and that name is interpolated into a
[label](url)construct, the rendered markdown becomes:BookStack itself sanitizes URLs in markdown links (
javascript:schemes are stripped on render), so this is not actively exploitable today. We should still:]inside link texthttp(s)/ non-#URLs in link targetsFiles:
custom_components/bookstack_sync/renderer.py— find every place a name is interpolated into a markdown link.2. BookStack URL appears in error logs
When the BookStack server hangs up mid-sync, aiohttp's
ClientResponseErrorincludes the full request URL in its repr. We catch that and log viaLOGGER.exception(...), so the BookStack hostname ends up inhome-assistant.log.The token is NOT logged — it's in the
Authorization:header, never in the URL. Verified during the v0.5.0 security review.This is "URL exposure", not credential leak. Mitigation options:
BookStackApiCommunicationErrorwith a sanitised message that strips the URLFiles to audit:
api.py,config_flow.py,coordinator.py,sync.py— everyLOGGER.exception(...)andLOGGER.error("...: %s", err).Acceptance
](javascript:alert(1))— verify the resulting markdown has no executable link.