escape Text input, rename Raw to UnsafeRaw

This commit is contained in:
maddalax 2024-09-28 20:45:27 -05:00
parent 4d95e21316
commit 2d333a6e0a
5 changed files with 23 additions and 13 deletions

View file

@ -5,7 +5,6 @@ import (
"github.com/google/uuid"
"github.com/maddalax/htmgo/framework/h"
"github.com/maddalax/htmgo/framework/hx"
"github.com/microcosm-cc/bluemonday"
"todolist/ent"
"todolist/internal/tasks"
)
@ -18,8 +17,6 @@ const (
TabComplete Tab = "Complete"
)
var policy = bluemonday.UGCPolicy()
func getActiveTab(ctx *h.RequestContext) Tab {
if tab := h.GetQueryParam(ctx, "tab"); tab != "" {
return tab
@ -185,7 +182,7 @@ func CompleteIcon(task *ent.Task) *h.Element {
"border-green-500": task.CompletedAt != nil,
"border-slate-400": task.CompletedAt == nil,
}),
h.If(task.CompletedAt != nil, h.Raw(`
h.If(task.CompletedAt != nil, h.UnsafeRaw(`
<svg class="w-6 h-6 text-green-500" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"></path>
</svg>
@ -290,7 +287,6 @@ func ClearCompleted(ctx *h.RequestContext) *h.Partial {
func Create(ctx *h.RequestContext) *h.Partial {
name := ctx.FormValue("name")
name = policy.Sanitize(name)
if name == "" {
return h.NewPartial(h.Div(h.Text("name is required")))

View file

@ -87,7 +87,7 @@ func TestRender(t *testing.T) {
func TestRawContent(t *testing.T) {
t.Parallel()
str := "<div>hello, world</div>"
raw := Raw(str)
raw := UnsafeRaw(str)
assert.Equal(t, str, Render(raw))
}
@ -526,6 +526,13 @@ func TestBackgroundCleaner(t *testing.T) {
assert.Equal(t, 0, len(node.byKeyCache))
}
func TestEscapeHtml(t *testing.T) {
t.Parallel()
assert.Equal(t, "&lt;script&gt;alert(1)&lt;/script&gt;", Render(Text("<script>alert(1)</script>")))
assert.Equal(t, "<p >&lt;script&gt;alert(1)&lt;/script&gt;</p>", Render(Pf("<script>alert(1)</script>")))
}
func BenchmarkCacheByKey(b *testing.B) {
b.ReportAllocs()
page := CachedPerKeyT(time.Second*3, func(userId string) (any, GetElementFunc) {

View file

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/maddalax/htmgo/framework/hx"
"golang.org/x/net/html"
"html/template"
"strings"
)
@ -167,7 +168,7 @@ func (a *AttributeR) Render(context *RenderContext) {
}
func (t *TextContent) Render(context *RenderContext) {
context.builder.WriteString(t.Content)
context.builder.WriteString(template.HTMLEscapeString(t.Content))
}
func (r *RawContent) Render(context *RenderContext) {

View file

@ -123,7 +123,9 @@ func Script(url string) *Element {
}
}
func Raw(text string) *RawContent {
// UnsafeRaw is a helper function to create a raw content with the given text
// The text is not escaped, do not use this function with user input
func UnsafeRaw(text string) *RawContent {
return NewRawContent(text)
}
@ -135,12 +137,16 @@ func MultiLineQuotes(text string) string {
return "`" + text + "`"
}
func RawF(text string, args any) *RawContent {
return Raw(fmt.Sprintf(text, args))
// UnsafeRawF is a helper function to create a raw content with the given text
// The text is not escaped, do not use this function with user input
func UnsafeRawF(text string, args any) *RawContent {
return UnsafeRaw(fmt.Sprintf(text, args))
}
func RawScript(text string) *RawContent {
return Raw("<script>" + text + "</script>")
// UnsafeRawScript is a helper function to create a script tag with the given text
// The text is not escaped, do not use this function with user input
func UnsafeRawScript(text string) *RawContent {
return UnsafeRaw("<script>" + text + "</script>")
}
func Pre(children ...Ren) *Element {

View file

@ -23,7 +23,7 @@ func MarkdownContent(ctx *h.RequestContext, path string, id string) *h.Element {
h.If(id != "", h.Id(id)),
h.Div(
h.Class("w-full flex flex-col prose max-w-[95vw] md:max-w-3xl prose-code:text-black prose-p:my-1 prose:p-0 prose-li:m-0 prose-ul:m-0 prose-ol:m-0"),
h.Raw(renderer.RenderFile(path, embeddedMd)),
h.UnsafeRaw(renderer.RenderFile(path, embeddedMd)),
),
)
}