Enforce name limits server-side and reject hidden runes in model names

Security review follow-ups. The 200-character registry-name cap the UI
forms promise now holds in domain.Validate for categories, tags,
merchants and instruments, so a non-browser client cannot persist an
unbounded name that every subsequent state response would carry. And a
model-supplied merchant or taxonomy name containing control or format
code points — bidi overrides, zero-width characters — is dropped like
an identifier-shaped one: React escaping already prevented injection,
but such names could visually spoof or reorder the review UI the
operator approves from.
This commit is contained in:
Lars Nolden
2026-09-14 12:30:13 +02:00
parent 676065292e
commit b7e5bf26cc
5 changed files with 28 additions and 12 deletions
+1 -1
View File
@@ -83,7 +83,7 @@ func normalizedProposalName(value string, max int) (string, error) {
if !utf8.ValidString(value) || value == "" || utf8.RuneCountInString(value) > max {
return "", errors.New("proposal name is blank, invalid UTF-8 or too long")
}
if strings.ContainsAny(value, "{}[]()<>/\\") || strings.Contains(value, "___") {
if strings.ContainsAny(value, "{}[]()<>/\\") || strings.Contains(value, "___") || hasHiddenRunes(value) {
return "", errors.New("proposal name is identifier-shaped")
}
return value, nil