Fix broken issue-body images in the panel drawer #43

Merged
pedromcaraujo merged 1 commit from fix/panel-issue-images into main 2026-09-15 15:34:54 +01:00

Fixes #42.

Images embedded in an issue body rendered as a broken-image icon (plus the linked alt-text) in the panel drawer.

Cause

Forgejo's /api/v1/markdown API renders image attachments as root-relative HTML — <a href="/attachments/<uuid>"><img src="/attachments/<uuid>"></a>. The drawer injects that HTML, but it's served from the launcher origin, not Forgejo, so /attachments/… resolves against the launcher and 404s.

Fix (web/panel.py)

  • _rewrite_urls post-processes the rendered HTML: <img src> is routed through a new authenticated sidecar proxy, and <a href> links are absolutized to the Forgejo base. Protocol-relative and absolute URLs are left untouched.
  • New /panel/<channel>/attachment endpoint fetches the image from Forgejo with the API token and streams it back same-origin — so private-repo images load without relying on the browser holding a live Forgejo session.
  • SSRF guard: the proxy only accepts Forgejo-internal attachment/media paths (/attachments/… or /<repo>/…), rejects //, absolute URLs and .., and caps the buffered size at 25 MB.

No frontend or module change needed — the drawer already injects body_html and nginx already proxies the whole /panel/ subtree to the sidecar.

Fixes #42. Images embedded in an issue body rendered as a broken-image icon (plus the linked alt-text) in the panel drawer. ### Cause Forgejo's `/api/v1/markdown` API renders image attachments as **root-relative** HTML — `<a href="/attachments/<uuid>"><img src="/attachments/<uuid>"></a>`. The drawer injects that HTML, but it's served from the launcher origin, not Forgejo, so `/attachments/…` resolves against the launcher and 404s. ### Fix (`web/panel.py`) - `_rewrite_urls` post-processes the rendered HTML: `<img src>` is routed through a new authenticated sidecar proxy, and `<a href>` links are absolutized to the Forgejo base. Protocol-relative and absolute URLs are left untouched. - New `/panel/<channel>/attachment` endpoint fetches the image from Forgejo with the API token and streams it back same-origin — so private-repo images load without relying on the browser holding a live Forgejo session. - SSRF guard: the proxy only accepts Forgejo-internal attachment/media paths (`/attachments/…` or `/<repo>/…`), rejects `//`, absolute URLs and `..`, and caps the buffered size at 25 MB. No frontend or module change needed — the drawer already injects `body_html` and nginx already proxies the whole `/panel/` subtree to the sidecar.
Fix broken issue-body images in the panel drawer (#42)
All checks were successful
CI / check (pull_request) Successful in 31s
b597306889
Forgejo's /markdown API renders image attachments as root-relative HTML
(src="/attachments/<uuid>"). Injected into the drawer — served from the
launcher origin, not Forgejo — those paths 404, so images render broken.

Post-process the rendered HTML in the sidecar: route <img> through a new
authenticated attachment proxy (/panel/<channel>/attachment) so private-repo
images load without relying on the browser's Forgejo session, and absolutize
<a> links to the Forgejo base. The proxy restricts fetches to Forgejo-internal
attachment/media paths and caps buffered size.
pedromcaraujo deleted branch fix/panel-issue-images 2026-09-15 15:34:54 +01:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pedromcaraujo/forge!43
No description provided.