diff --git a/cmd/gomuks/media.go b/cmd/gomuks/media.go index 858d974..e5bb635 100644 --- a/cmd/gomuks/media.go +++ b/cmd/gomuks/media.go @@ -38,6 +38,7 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/hlog" _ "golang.org/x/image/webp" + "golang.org/x/net/html" "go.mau.fi/util/exhttp" "go.mau.fi/util/ffmpeg" @@ -147,7 +148,7 @@ func isAllowedAvatarMime(mime string) bool { func (w *avatarResponseWriter) WriteHeader(statusCode int) { if statusCode != http.StatusOK && statusCode != http.StatusNotModified { - data := []byte(fmt.Sprintf(fallbackAvatarTemplate, w.bgColor, w.character)) + data := []byte(fmt.Sprintf(fallbackAvatarTemplate, w.bgColor, html.EscapeString(w.character))) w.Header().Set("Content-Type", "image/svg+xml") w.Header().Set("Content-Length", strconv.Itoa(len(data))) w.Header().Del("Content-Disposition") diff --git a/web/src/api/media.ts b/web/src/api/media.ts index ec3d2b2..9822d2a 100644 --- a/web/src/api/media.ts +++ b/web/src/api/media.ts @@ -40,9 +40,17 @@ function makeFallbackAvatar(backgroundColor: string, fallbackCharacter: string): ${fallbackCharacter} + >${escapeHTMLChar(fallbackCharacter)} `) +} +function escapeHTMLChar(char: string): string { + switch (char) { + case "&": return "&" + case "<": return "<" + case ">": return ">" + default: return char + } } export const getAvatarURL = (userID: UserID, content?: Partial): string | undefined => {