diff options
author | bgw <29340584+bgwdotdev@users.noreply.github.com> | 2024-04-25 19:19:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-25 19:19:15 +0100 |
commit | 93aeeb7a6316389f3bd4bbdb7a9ffc555677e719 (patch) | |
tree | 70d2443bf31090a320c56b1029d99c0c4bb05dd6 | |
parent | 06b75022eed1e8bbed13a85cc8aeb18199040392 (diff) | |
download | lustre-93aeeb7a6316389f3bd4bbdb7a9ffc555677e719.tar.gz lustre-93aeeb7a6316389f3bd4bbdb7a9ffc555677e719.zip |
🔀 Escape attribute values when emitting static HTML. (#113)
* fix: add the escape function over custom attribute values
* fix: update class and style attribute values to be escaped
-rw-r--r-- | birdie_snapshots/can_safely_escape_dangerous_symbols_in_attributes.accepted | 5 | ||||
-rw-r--r-- | src/lustre/internals/vdom.gleam | 33 | ||||
-rw-r--r-- | test/apps/static.gleam | 15 | ||||
-rw-r--r-- | test/lustre_test.gleam | 6 |
4 files changed, 52 insertions, 7 deletions
diff --git a/birdie_snapshots/can_safely_escape_dangerous_symbols_in_attributes.accepted b/birdie_snapshots/can_safely_escape_dangerous_symbols_in_attributes.accepted new file mode 100644 index 0000000..cbb7f9d --- /dev/null +++ b/birdie_snapshots/can_safely_escape_dangerous_symbols_in_attributes.accepted @@ -0,0 +1,5 @@ +--- +version: 1.1.2 +title: Can safely escape dangerous symbols in attributes +--- +<div example="{"mykey": "myvalue"}" class="'badquotes'" style="background:"><script>alert`1`</script>;"></div>
\ No newline at end of file diff --git a/src/lustre/internals/vdom.gleam b/src/lustre/internals/vdom.gleam index fc4a4a3..4930f80 100644 --- a/src/lustre/internals/vdom.gleam +++ b/src/lustre/internals/vdom.gleam @@ -282,10 +282,30 @@ fn attributes_to_string_builder( style, inner_html <> val, ) - Ok(#("class", val)) if class == "" -> #(html, val, style, inner_html) - Ok(#("class", val)) -> #(html, class <> " " <> val, style, inner_html) - Ok(#("style", val)) if style == "" -> #(html, class, val, inner_html) - Ok(#("style", val)) -> #(html, class, style <> " " <> val, inner_html) + Ok(#("class", val)) if class == "" -> #( + html, + escape("", val), + style, + inner_html, + ) + Ok(#("class", val)) -> #( + html, + class <> " " <> escape("", val), + style, + inner_html, + ) + Ok(#("style", val)) if style == "" -> #( + html, + class, + escape("", val), + inner_html, + ) + Ok(#("style", val)) -> #( + html, + class, + style <> " " <> escape("", val), + inner_html, + ) Ok(#(key, "")) -> #( string_builder.append(html, " " <> key), class, @@ -293,7 +313,10 @@ fn attributes_to_string_builder( inner_html, ) Ok(#(key, val)) -> #( - string_builder.append(html, " " <> key <> "=\"" <> val <> "\""), + string_builder.append( + html, + " " <> key <> "=\"" <> escape("", val) <> "\"", + ), class, style, inner_html, diff --git a/test/apps/static.gleam b/test/apps/static.gleam index 5c6ca05..fcf52f3 100644 --- a/test/apps/static.gleam +++ b/test/apps/static.gleam @@ -1,8 +1,8 @@ // IMPORTS --------------------------------------------------------------------- -import lustre/attribute.{disabled, src} +import lustre/attribute.{attribute, class, disabled, src, style} import lustre/element.{text} -import lustre/element/html.{body, h1, head, html, img, input, title} +import lustre/element/html.{body, div, h1, head, html, img, input, title} // VIEW ------------------------------------------------------------------------ @@ -16,3 +16,14 @@ pub fn view() { ]), ]) } + +pub fn escaped_attribute() { + div( + [ + class("'badquotes'"), + style([#("background", "\"><script>alert`1`</script>")]), + attribute("example", "{\"mykey\": \"myvalue\"}"), + ], + [], + ) +} diff --git a/test/lustre_test.gleam b/test/lustre_test.gleam index f3a2993..6cd93c3 100644 --- a/test/lustre_test.gleam +++ b/test/lustre_test.gleam @@ -149,3 +149,9 @@ pub fn fragment_counter_diff_test() { birdie.snap(json.to_string(patch.element_diff_to_json(diff)), title) process.send(runtime, Shutdown) } + +pub fn escaped_attribute_test() { + let title = "Can safely escape dangerous symbols in attributes" + let el = static.escaped_attribute() + birdie.snap(element.to_string(el), title) +} |