mirror of
https://github.com/redmine/redmine.git
synced 2026-03-30 17:21:08 +02:00
Backport Redmine::Helpers::URL#uri_with_link_safe_scheme? from r21161 to 4.2-stable (#38806).
git-svn-id: https://svn.redmine.org/redmine/branches/4.2-stable@22300 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -22,6 +22,7 @@ require 'uri'
|
||||
module Redmine
|
||||
module Helpers
|
||||
module URL
|
||||
# safe for resources fetched without user interaction?
|
||||
def uri_with_safe_scheme?(uri, schemes = ['http', 'https', 'ftp', 'mailto', nil])
|
||||
# URLs relative to the current document or document root (without a protocol
|
||||
# separator, should be harmless
|
||||
@@ -32,6 +33,20 @@ module Redmine
|
||||
rescue URI::Error
|
||||
false
|
||||
end
|
||||
|
||||
# safe to render links to given uri?
|
||||
def uri_with_link_safe_scheme?(uri)
|
||||
# regexp adapted from Sanitize (we need to catch even invalid protocol specs)
|
||||
return true unless uri =~ /\A\s*([^\/#]*?)(?:\:|�*58|�*3a)/i
|
||||
|
||||
# absolute scheme
|
||||
scheme = $1.downcase
|
||||
return false unless /\A[a-z][a-z0-9\+\.\-]*\z/.match?(scheme) # RFC 3986
|
||||
|
||||
# To support Ruby 2.4, we use `none? {|obj| ... }` instead of
|
||||
# `none?(pattern)` in 4.2-stable branch.
|
||||
%w(data javascript vbscript).none? {|v| v == scheme}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -33,4 +33,45 @@ class URLTest < ActiveSupport::TestCase
|
||||
assert_not uri_with_safe_scheme?("httpx://example.com/")
|
||||
assert_not uri_with_safe_scheme?("mailto:root@")
|
||||
end
|
||||
|
||||
LINK_SAFE_URIS = [
|
||||
"http://example.com/",
|
||||
"https://example.com/",
|
||||
"ftp://example.com/",
|
||||
"foo://example.org",
|
||||
"mailto:foo@example.org",
|
||||
" http://example.com/",
|
||||
"",
|
||||
"/javascript:alert(\'filename\')",
|
||||
]
|
||||
|
||||
def test_uri_with_link_safe_scheme_should_recognize_safe_uris
|
||||
LINK_SAFE_URIS.each do |uri|
|
||||
assert uri_with_link_safe_scheme?(uri), "'#{uri}' should be safe"
|
||||
end
|
||||
end
|
||||
|
||||
LINK_UNSAFE_URIS = [
|
||||
"javascript:alert(\'XSS\');",
|
||||
"javascript :alert(\'XSS\');",
|
||||
"javascript: alert(\'XSS\');",
|
||||
"javascript : alert(\'XSS\');",
|
||||
":javascript:alert(\'XSS\');",
|
||||
"javascript:",
|
||||
"javascript:",
|
||||
"javascript:",
|
||||
"javascript:",
|
||||
"java\0script:alert(\"XSS\")",
|
||||
"java\script:alert(\"XSS\")",
|
||||
" \x0e javascript:alert(\'XSS\');",
|
||||
"data:image/png;base64,foobar",
|
||||
"vbscript:foobar",
|
||||
"data:text/html;base64,foobar",
|
||||
]
|
||||
|
||||
def test_uri_with_link_safe_scheme_should_recognize_unsafe_uris
|
||||
LINK_UNSAFE_URIS.each do |uri|
|
||||
assert_not uri_with_link_safe_scheme?(uri), "'#{uri}' should not be safe"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user