diff --git a/lib/phlex/sgml.rb b/lib/phlex/sgml.rb
index c76cf547..653bf1d3 100644
--- a/lib/phlex/sgml.rb
+++ b/lib/phlex/sgml.rb
@@ -393,14 +393,6 @@ def __final_attributes__(**attributes)
attributes = process_attributes(**attributes)
end
- if attributes[:href]&.start_with?(/\s*javascript:/)
- attributes.delete(:href)
- end
-
- if attributes["href"]&.start_with?(/\s*javascript:/)
- attributes.delete("href")
- end
-
buffer = +""
__build_attributes__(attributes, buffer: buffer)
@@ -418,8 +410,11 @@ def __build_attributes__(attributes, buffer:)
else raise ArgumentError, "Attribute keys should be Strings or Symbols."
end
+ lower_name = name.downcase
+ next if lower_name == "href" && v.start_with?(/\s*javascript:/i)
+
# Detect unsafe attribute names. Attribute names are considered unsafe if they match an event attribute or include unsafe characters.
- if HTML::EVENT_ATTRIBUTES[name] || name.match?(/[<>&"']/)
+ if HTML::EVENT_ATTRIBUTES[lower_name] || name.match?(/[<>&"']/)
raise ArgumentError, "Unsafe attribute name detected: #{k}."
end
diff --git a/test/phlex/view/naughty_business.rb b/test/phlex/view/naughty_business.rb
index 5e4cad47..c75dcff0 100644
--- a/test/phlex/view/naughty_business.rb
+++ b/test/phlex/view/naughty_business.rb
@@ -3,6 +3,36 @@
describe Phlex::HTML do
extend ViewHelper
+ with "naughty javascript links" do
+ view do
+ def template
+ a(href: "javascript:alert(1)") { "a" }
+ a(href: "JAVASCRIPT:alert(1)") { "b" }
+ a(href: :"JAVASCRIPT:alert(1)") { "c" }
+ a(HREF: "javascript:alert(1)") { "d" }
+ end
+ end
+
+ it "removes the href attributes" do
+ expect(output).to be == "abcd"
+ end
+ end
+
+ with "naughty uppercase event tag" do
+ view do
+ def template
+ button ONCLICK: "ALERT(1)" do
+ "naughty button"
+ end
+ end
+ end
+
+ it "raises" do
+ expect { output }.to raise_exception ArgumentError,
+ message: be == "Unsafe attribute name detected: ONCLICK."
+ end
+ end
+
with "naughty text" do
view do
def view_template