Merge branch 'audit-mix-audit-report' (#69) into release/2.11

# Conflicts:
#	lib/pleroma/http/adapter_helper/hackney.ex
This commit is contained in:
Lain Soykaf 2026-10-22 16:37:08 +04:00
commit 9ea8d37e9f
No known key found for this signature in database
23 changed files with 216 additions and 22 deletions

View file

@ -375,13 +375,22 @@ defmodule Pleroma.FormatterTest do
end
describe "markdown_to_html/2" do
test "keeps formatted link text when stripping email autolinks" do
opts = %{breaks: true, strip_email_autolinks: true}
assert Formatter.markdown_to_html("[**hello**](https://example.org/)", opts) ==
~s(<p><a href="https://example.org/"><strong>hello</strong></a></p>)
assert Formatter.markdown_to_html("[`code`](https://example.org/)", opts) ==
~s(<p><a href="https://example.org/"><code class="inline">code</code></a></p>)
end
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|<p><a href="http://example.com/?a=x%22 onerror=%22alert(1)">click</a></p>|
end
test "preserves entities without rendering dangerous raw HTML" do
@ -406,10 +415,15 @@ defmodule Pleroma.FormatterTest do
test "rejects entity-encoded URL delimiters" do
markdown = "[click](http://example.com/?a=x&#34;onerror=alert(1))"
html = Formatter.markdown_to_html(markdown)
assert Formatter.markdown_to_html(markdown) ==
~s|<p><a href="http://example.com/?a=x%22onerror=alert(1)">click</a></p>|
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=&quot;cat&quot;&page=2)"
assert Formatter.markdown_to_html(markdown) ==
~s(<p><a href="https://example.org/?q=%22cat%22&amp;page=2">search</a></p>)
end
test "strips email autolinks without changing explicit mailto links" do

View file

@ -141,6 +141,44 @@ defmodule Pleroma.HTMLTest do
end
end
describe "link schemes as a browser sees them" do
# Browsers remove tabs and newlines in URLs and control characters and
# spaces at the start, so these are javascript: links to them.
test "removes javascript: links hidden with control characters" do
for href <- [
"java\tscript:alert(1)",
"java&#x09;script:alert(1)",
"java\nscript:alert(1)",
"&#x0d;javascript:alert(1)",
" javascript:alert(1)",
"\u0001javascript:alert(1)"
],
scrubber <- [
Pleroma.HTML.Scrubber.Default,
Pleroma.HTML.Scrubber.TwitterText,
Pleroma.HTML.Scrubber.LinksOnly
] do
html = HTML.filter_tags(~s(<a href="#{href}">x</a>), scrubber)
refute html =~ "href", "#{inspect(href)} survived #{inspect(scrubber)}: #{html}"
end
end
test "keeps normal links" do
for href <- ["https://example.org/a?b=c", "/relative/path", "#fragment"] do
assert HTML.filter_tags(~s(<a href="#{href}">x</a>), Pleroma.HTML.Scrubber.Default) ==
~s(<a href="#{href}">x</a>)
end
end
test "removes images with hidden schemes" do
html =
HTML.filter_tags(~s|<img src="java\tscript:alert(1)"/>|, Pleroma.HTML.Scrubber.Default)
refute html =~ "src"
end
end
describe "default scrubber" do
test "normalizes HTML as expected" do
expected = """

View file

@ -50,6 +50,15 @@ defmodule Pleroma.HTTP.AdapterHelper.GunTest do
assert Keyword.has_key?(defaults, :b)
end
test "uses Hackney's ssl_options from the config as Gun's tls_opts" do
clear_config([:http, :adapter], ssl_options: [versions: [:"tlsv1.3"]])
opts = Gun.options([], URI.parse("https://example.com"))
assert opts[:tls_opts] == [versions: [:"tlsv1.3"]]
refute Keyword.has_key?(opts, :ssl_options)
end
test "parses string proxy host & port" do
clear_config([:http, :proxy_url], "localhost:8123")

View file

@ -13,6 +13,12 @@ defmodule Pleroma.HTTP.AdapterHelper.HackneyTest do
{:ok, uri: uri}
end
# Hackney 4 shares one HTTP/2 connection per host, and closing a response
# stops that connection for every stream on it.
test "Hackney only speaks HTTP/1.1" do
assert :hackney_util.default_protocols() == [:http1]
end
describe "options/2" do
setup do: clear_config([:http, :adapter], a: 1, b: 2)
@ -39,6 +45,19 @@ defmodule Pleroma.HTTP.AdapterHelper.HackneyTest do
assert opts[:proxy] == "localhost:8123"
end
test "gives Hackney a string host for a proxy with an IP address", %{uri: uri} do
clear_config([:http, :proxy_url], {:socks5, {127, 0, 0, 1}, 9050})
assert Hackney.options([], uri)[:proxy] == {:socks5, ~c"127.0.0.1", 9050}
clear_config([:http, :proxy_url], {{10, 0, 0, 1}, 8123})
assert Hackney.options([], uri)[:proxy] == {~c"10.0.0.1", 8123}
clear_config([:http, :proxy_url], nil)
assert Hackney.options([proxy: {:socks5, {0, 0, 0, 0, 0, 0, 0, 1}, 9050}], uri)[:proxy] ==
{:socks5, ~c"::1", 9050}
end
test "respect connection opts and no proxy", %{uri: uri} do
opts = Hackney.options([a: 2, b: 1], uri)

View file

@ -0,0 +1,13 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.HTTP.DefaultAdapterTest do
use ExUnit.Case, async: true
# The test environment uses Tesla.Mock, and config.exs imports the config
# of the current Mix env, so check the shipped default in the file itself.
test "Gun is the default HTTP client" do
assert File.read!("config/config.exs") =~ ~r/^config :tesla, adapter: Tesla.Adapter.Gun$/m
end
end

View file

@ -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(<a href="http://example.com/?a=x">)
assert result =~ ~s|<a href="http://example.com/?a=x%22 onerror=%22alert(1)">|
refute result =~ ~s|onerror="alert(1)|
refute result =~ ~s(<a href="http://example.com/?a=x" onerror=)
end