test_http.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. # taken from Django 3.2.0.alpha0 and adapted to run in pytest
  2. from flaskbb.utils.http import is_safe_url
  3. def test_bad_urls():
  4. bad_urls = (
  5. "http://example.com",
  6. "http:///example.com",
  7. "https://example.com",
  8. "ftp://example.com",
  9. r"\\example.com",
  10. r"\\\example.com",
  11. r"/\\/example.com",
  12. r"\\\example.com",
  13. r"\\example.com",
  14. r"\\//example.com",
  15. r"/\/example.com",
  16. r"\/example.com",
  17. r"/\example.com",
  18. "http:///example.com",
  19. r"http:/\//example.com",
  20. r"http:\/example.com",
  21. r"http:/\example.com",
  22. 'javascript:alert("XSS")',
  23. "\njavascript:alert(x)",
  24. "\x08//example.com",
  25. r"http://otherserver\@example.com",
  26. r"http:\\testserver\@example.com",
  27. r"http://testserver\me:pass@example.com",
  28. r"http://testserver\@example.com",
  29. r"http:\\testserver\confirm\me@example.com",
  30. "http:999999999",
  31. "ftp:9999999999",
  32. "\n",
  33. "http://[2001:cdba:0000:0000:0000:0000:3257:9652/",
  34. "http://2001:cdba:0000:0000:0000:0000:3257:9652]/",
  35. )
  36. for bad_url in bad_urls:
  37. assert not is_safe_url(bad_url, allowed_hosts={"testserver", "testserver2"})
  38. def test_good_urls():
  39. good_urls = (
  40. "/view/?param=http://example.com",
  41. "/view/?param=https://example.com",
  42. "/view?param=ftp://example.com",
  43. "view/?param=//example.com",
  44. "https://testserver/",
  45. "HTTPS://testserver/",
  46. "//testserver/",
  47. "http://testserver/confirm?email=me@example.com",
  48. "/url%20with%20spaces/",
  49. "path/http:2222222222",
  50. )
  51. for good_url in good_urls:
  52. assert is_safe_url(good_url, allowed_hosts={"otherserver", "testserver"})
  53. def test_basic_auth():
  54. # Valid basic auth credentials are allowed.
  55. assert is_safe_url(
  56. r"http://user:pass@testserver/", allowed_hosts={"user:pass@testserver"}
  57. )
  58. def test_no_allowed_hosts():
  59. # A path without host is allowed.
  60. assert is_safe_url("/confirm/me@example.com", allowed_hosts=None)
  61. # Basic auth without host is not allowed.
  62. assert not is_safe_url(r"http://testserver\@example.com", allowed_hosts=None)
  63. def test_allowed_hosts_str():
  64. assert is_safe_url("http://good.com/good", allowed_hosts="good.com")
  65. assert not is_safe_url("http://good.co/evil", allowed_hosts="good.com")
  66. def test_secure_param_https_urls():
  67. secure_urls = (
  68. "https://example.com/p",
  69. "HTTPS://example.com/p",
  70. "/view/?param=http://example.com",
  71. )
  72. for url in secure_urls:
  73. assert is_safe_url(url, allowed_hosts={"example.com"}, require_https=True)
  74. def test_secure_param_non_https_urls():
  75. insecure_urls = (
  76. "http://example.com/p",
  77. "ftp://example.com/p",
  78. "//example.com/p",
  79. )
  80. for url in insecure_urls:
  81. assert not is_safe_url(url, allowed_hosts={"example.com"}, require_https=True)