diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index 32ee6a296..59df4d20a 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -252,9 +252,13 @@ defmodule Pleroma.Formatter do defp sanitize_markdown_url(value, name) do if String.downcase(to_string(name)) in ["href", "src"] do - value - |> String.split(~r/["<>]/, parts: 2) - |> hd() + # Percent-encode instead of cutting, so the URL stays complete but can + # never close the attribute or open a tag. + String.replace(value, ~r/["<>]/, fn + "\"" -> "%22" + "<" -> "%3C" + ">" -> "%3E" + end) else value end diff --git a/test/pleroma/formatter_test.exs b/test/pleroma/formatter_test.exs index 906d39e4f..2954e526f 100644 --- a/test/pleroma/formatter_test.exs +++ b/test/pleroma/formatter_test.exs @@ -388,10 +388,9 @@ defmodule Pleroma.FormatterTest do test "escapes link attribute values" do markdown = ~s|[click](http://example.com/?a=x" onerror="alert(1))| - html = Formatter.markdown_to_html(markdown) - - assert html =~ ~s|href="http://example.com/?a=x"| - refute html =~ "onerror" + # The quotes are percent-encoded, so everything stays inside href. + assert Formatter.markdown_to_html(markdown) == + ~s|
| end test "preserves entities without rendering dangerous raw HTML" do @@ -416,10 +415,15 @@ defmodule Pleroma.FormatterTest do test "rejects entity-encoded URL delimiters" do markdown = "[click](http://example.com/?a=x"onerror=alert(1))" - html = Formatter.markdown_to_html(markdown) + assert Formatter.markdown_to_html(markdown) == + ~s|| + end - assert html =~ ~s|href="http://example.com/?a=x"| - refute html =~ "onerror" + test "keeps URLs with encoded quotes complete" do + markdown = "[search](https://example.org/?q="cat"&page=2)" + + assert Formatter.markdown_to_html(markdown) == + ~s() end test "strips email autolinks without changing explicit mailto links" do diff --git a/test/pleroma/web/common_api/utils_test.exs b/test/pleroma/web/common_api/utils_test.exs index ff5150c40..44a7486de 100644 --- a/test/pleroma/web/common_api/utils_test.exs +++ b/test/pleroma/web/common_api/utils_test.exs @@ -232,7 +232,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do code = ~s|[click](http://example.com/?a=x" onerror="alert(1))| {result, [], []} = Utils.format_input(code, "text/markdown") - assert result =~ ~s() + assert result =~ ~s|| refute result =~ ~s|onerror="alert(1)| refute result =~ ~s(