micro / micro/mu

Every page is string concatenation, so escaping is remembered rather than guaranteed

Open
#1,484 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
434
Forks
21
Avg merge
18m
Merged PRs (30d)
326

Description

The fact

html/template  0 files
text/template  1 file — internal/ai/ai.go, and it renders a system prompt

Every page in the product is built by concatenating strings. The only template in the tree is for talking to a model.

What that costs, and what it does not

The ergonomics are not the problem, and this is not an argument for rewriting 35 services into templates. Composition by function call is genuinely better than template includes — account.BalanceBody could be split out and reused on Home precisely because it is a function — and this repository's habit of putting a paragraph of reasoning directly above the markup it explains works badly in a template file.

The problem is escaping. html.EscapeString is called by hand at every interpolation, which means every one of them is a place somebody can forget, and forgetting is silent. html/template escapes by construction and knows the context — an attribute is not a text node is not a URL is not a script.

Two near-misses already in the tree, both caught by review rather than by anything mechanical:

  • service/hazards/page.go interpolates a feed's Place, Area, Name and Country — third-party strings — into markup
  • inbox/new.go puts an account id straight into a <datalist> option value

Neither is exploitable today. Both are one edit away from being so, and nothing in the build would say.

What I would actually do

Not a rewrite. A narrow, typed helper that escapes by construction, adopted where new pages are written and retrofitted only where untrusted text is interpolated:

  • Audit every interpolation of third-party or user text into markup and confirm each is escaped. This is the part with real value and it can be done today
  • A test/ scan for interpolation of a known-untrusted value without an escape on it, the way test/service_models_test.go counts model calls — mechanical, so it cannot be forgotten
  • Only then consider a helper, and only if the audit shows the manual calls are actually being missed

Not in scope

Converting existing pages. home.go being a long strings.Builder is a readability complaint, and readability is not worth the risk of touching every page in the product at once.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the interpolations in service/hazards/page.go and inbox/new.go, then audit other third-party or user text inserted into markup. Review test/service_models_test.go for the existing scan pattern. Done means untrusted interpolations are confirmed escaped and a test/ scan mechanically detects known-untrusted values that lack escaping.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
security, testing
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.