fix(html): check link schemes the way browsers read them
FastSanitize checks the scheme with URI.parse/1, which finds none in java<TAB>script:alert(1). Browsers remove tabs and newlines and leading control characters first and run it as a javascript: link. The scrubbers now use Pleroma.HTML.URIAttributes, which normalizes the URL the same way before the scheme check.
This commit is contained in:
parent
58d4f6aa2c
commit
1be50ed28b
6 changed files with 95 additions and 5 deletions
40
lib/pleroma/html/uri_attributes.ex
Normal file
40
lib/pleroma/html/uri_attributes.ex
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTML.URIAttributes do
|
||||
@moduledoc """
|
||||
URI attribute rules for the scrubbers.
|
||||
|
||||
Works like `FastSanitize.Sanitizer.Meta.allow_tag_with_uri_attributes/3`, but
|
||||
checks the scheme the way a browser reads the URL. Browsers remove tabs and
|
||||
newlines anywhere and control characters and spaces at the start, so
|
||||
`java\\tscript:` is a `javascript:` link to them, while `URI.parse/1` finds no
|
||||
scheme and FastSanitize lets it through.
|
||||
"""
|
||||
|
||||
defmacro allow_tag_with_uri_attributes(tag, attrs, valid_schemes) do
|
||||
for attr <- attrs do
|
||||
quote do
|
||||
def scrub_attribute(unquote(tag), {unquote(attr), "&" <> _}), do: nil
|
||||
|
||||
def scrub_attribute(unquote(tag), {unquote(attr), uri} = attribute) do
|
||||
if Pleroma.HTML.URIAttributes.valid_scheme?(uri, unquote(valid_schemes)),
|
||||
do: attribute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@spec valid_scheme?(String.t(), [String.t()]) :: boolean()
|
||||
def valid_scheme?(uri, valid_schemes) do
|
||||
scheme =
|
||||
uri
|
||||
|> String.replace(~r/[\t\n\r]/, "")
|
||||
|> String.replace(~r/\A[\x00-\x20]+/, "")
|
||||
|> URI.parse()
|
||||
|> Map.get(:scheme)
|
||||
|
||||
is_nil(scheme) or scheme in valid_schemes
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue