Skip to main content

38 posts tagged with "go"

View All Tags

Live HTML Over SSE: Pushing Rendered Fragments With app.Render in Fiber v3.6

ยท 29 min read
Fiber Team
Maintainers

A support team works from a shared queue page. Every agent has it open all day, and the page polls the server every five seconds. Two things go wrong with that. The queue is never quite current, so two agents regularly click "Claim" on the same ticket within the same five seconds, and one of them finds out a few seconds later that their work was wasted. And the polling is mostly empty: thirty open tabs ask the server 360 times a minute whether anything happened, and the answer is nearly always no.

Server-Sent Events fix both. The server keeps one response open per tab and writes to it when something changes. The question is what to write. Sending JSON means a second rendering layer in the browser that has to produce the same markup as your Go templates. Sending HTML means you render the fragment on the server with the same template that renders the full page, and the browser only has to put it in the right place. With htmx and its SSE extension, that last part needs no JavaScript of your own.

Rendering a template used to be tied to a request in Fiber: c.Render writes into the response of the request at hand. An update that one agent triggers has to reach thirty other streams, and none of them is the request that caused it. Fiber v3.6.0 added app.Render, which writes a template through the configured view engine into any io.Writer, with no request involved. This post builds the live queue around it: render each update once, number it, fan it out to every subscriber, replay what a reconnecting browser missed and send a full reset when replay is impossible. Everything was built and tested against Fiber v3.6.1 with html/v3.1.0 of the template engine, htmx 2.0.11 and htmx-ext-sse 2.2.4. app.Render needs Fiber v3.6.0 or later, which requires Go 1.26. The SSE middleware has been there since v3.3.0.

Deny by Default: Route-Aware Authorization With c.Endpoint() in Fiber v3.6

ยท 23 min read
Fiber Team
Maintainers

A pull request adds GET /api/admin/export, a CSV download of every customer record. The handler is fine, the test for the CSV format is fine, and the reviewer approves it. Two weeks later somebody notices that the route was registered on the api group instead of the admin group, so the only thing it checked was a valid login. Every customer with an account could download every other customer. Nobody wrote a wrong access rule. The route simply never had one, and nothing in the app noticed.

This is the most ordinary way to end up in A01 of the OWASP Top 10 2025, broken access control, whose first piece of advice is to deny by default. In a Fiber app, "default" usually means "whatever middleware the route happens to inherit from its group". That works until the day a route lands in the wrong place. Fiber v3.6.0 added c.Endpoint(), which lets global middleware see the route that will handle a request before any handler runs. This post uses it to build a single policy table keyed by route name, a middleware that rejects every route the table does not mention, and a startup check that refuses to boot when the table and the routes disagree. Everything was built and tested against Fiber v3.6.1. c.Endpoint(), c.Bearer() and c.SetLocal() need v3.6.0 or later, which requires Go 1.26.

Localhost Is Not a Boundary: DNS Rebinding and Host Authorization in Fiber v3

ยท 22 min read
Fiber Team
Maintainers

Somebody on your team writes a small helper for the editor. It is a Fiber app on 127.0.0.1:7777 that lists and reads files from the current project, so an editor plugin or a coding agent can ask it for context. It has no authentication, because it only listens on loopback and "nothing outside this machine can reach it". That sentence is half true. Nothing outside the machine can open a connection to it. But the browser on the same machine can, and the browser runs code from every website its user visits.

Over the past months, several Model Context Protocol servers received advisories for exactly this setup, among them genieacs-mcp, whose Streamable HTTP transport listened on 127.0.0.1:8080 without checking Host or Origin. The attack behind them is called DNS rebinding, and it is older than most of the tools it now hits. This post shows how it works, why the usual browser defenses do not notice it, and how the hostauthorization middleware that shipped in Fiber v3.3.0 closes the hole, for local tools and for public servers. Everything was built and tested against Fiber v3.6.1, which needs Go 1.26. The example also uses c.Origin(), which arrived in v3.6.0.