url.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package sanitizer // import "miniflux.app/v2/internal/reader/sanitizer"
  4. import "strings"
  5. // validURISchemes is the allowlist for URLs in sanitized feed body content.
  6. // It is intentionally broad; stricter surfaces (redirects, template hrefs)
  7. // should use urllib.IsAbsoluteURL / urllib.IsRelativePath instead.
  8. //
  9. // See https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
  10. var validURISchemes = []string{
  11. // Most commong schemes on top.
  12. "https",
  13. "http",
  14. // Then the rest.
  15. "apt",
  16. "bitcoin",
  17. "callto",
  18. "dav",
  19. "davs",
  20. "ed2k",
  21. "facetime",
  22. "feed",
  23. "ftp",
  24. "geo",
  25. "git",
  26. "gopher",
  27. "irc",
  28. "irc6",
  29. "ircs",
  30. "itms-apps",
  31. "itms",
  32. "magnet",
  33. "mailto",
  34. "news",
  35. "nntp",
  36. "rtmp",
  37. "sftp",
  38. "sip",
  39. "sips",
  40. "shortcuts",
  41. "skype",
  42. "spotify",
  43. "ssh",
  44. "steam",
  45. "svn",
  46. "svn+ssh",
  47. "tel",
  48. "webcal",
  49. "xmpp",
  50. // iOS Apps
  51. "opener", // https://www.opener.link
  52. "hack", // https://apps.apple.com/it/app/hack-for-hacker-news-reader/id1464477788?l=en-GB
  53. }
  54. // HasValidURIScheme reports whether the URL begins with an allowed scheme.
  55. // The scheme comparison is case-insensitive per RFC 3986 §3.1.
  56. func HasValidURIScheme(absoluteURL string) bool {
  57. scheme, _, ok := strings.Cut(absoluteURL, ":")
  58. if !ok || scheme == "" {
  59. return false
  60. }
  61. for _, validScheme := range validURISchemes {
  62. if strings.EqualFold(scheme, validScheme) {
  63. return true
  64. }
  65. }
  66. return false
  67. }