package urlutil import ( "net/url" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestIsRedirectAllowed(t *testing.T) { // from: https://raw.githubusercontent.com/random-robbie/open-redirect/master/payloads.txt rawurls := strings.Fields(` &%0d%0a1Location:https://google.com @google.com @https://www.google.com %2f%2e%2e crlftest%0dLocation:https://google.com /https:/%5cblackfan.ru/ //example.com@google.com/%2f.. ///google.com/%2f.. ///example.com@google.com/%2f.. ////google.com/%2f.. ////example.com@google.com/%2f.. /x:1/:///%01javascript:alert(document.cookie)/ https://google.com/%2f.. https://example.com@google.com/%2f.. /https://google.com/%2f.. /https://example.com@google.com/%2f.//example.com@google.com/%2f.. ///google.com/%2f.. ///example.com@google.com/%2f.. ////google.com/%2f.. ////example.com@google.com/%2f.. https://google.com/%2f.. https://example.com@google.com/%2f.. /https://google.com/%2f.. /https://example.com@google.com/%2f.. //google.com/%2f%2e%2e //example.com@google.com/%2f%2e%2e ///google.com/%2f%2e%2e ///example.com@google.com/%2f%2e%2e ////google.com/%2f%2e%2e ////example.com@google.com/%2f%2e%2e https://google.com/%2f%2e%2e https://example.com@google.com/%2f%2e%2e /https://google.com/%2f%2e%2e /https://example.com@google.com/%2f%2e%2e //google.com/ //example.com@google.com/ ///google.com/ ///example.com@google.com/ ////google.com/ ////example.com@google.com/ https://google.com/ https://example.com@google.com/ /https://google.com/ /https://example.com@google.com/ //google.com// //example.com@google.com// ///google.com// ///example.com@google.com// ////google.com// ////example.com@google.com// https://google.com// https://example.com@google.com// //https://google.com// //https://example.com@google.com// //google.com/%2e%2e%2f //example.com@google.com/%2e%2e%2f ///google.com/%2e%2e%2f ///example.com@google.com/%2e%2e%2f ////google.com/%2e%2e%2f ////example.com@google.com/%2e%2e%2f https://google.com/%2e%2e%2f https://example.com@google.com/%2e%2e%2f //https://google.com/%2e%2e%2f //https://example.com@google.com/%2e%2e%2f ///google.com/%2e%2e ///example.com@google.com/%2e%2e ////google.com/%2e%2e ////example.com@google.com/%2e%2e https:///google.com/%2e%2e https:///example.com@google.com/%2e%2e //https:///google.com/%2e%2e //example.com@https:///google.com/%2e%2e /https://google.com/%2e%2e /https://example.com@google.com/%2e%2e ///google.com/%2f%2e%2e ///example.com@google.com/%2f%2e%2e ////google.com/%2f%2e%2e ////example.com@google.com/%2f%2e%2e https:///google.com/%2f%2e%2e https:///example.com@google.com/%2f%2e%2e /https://google.com/%2f%2e%2e /https://example.com@google.com/%2f%2e%2e /https:///google.com/%2f%2e%2e /https:///example.com@google.com/%2f%2e%2e /%09/google.com /%09/example.com@google.com //%09/google.com //%09/example.com@google.com ///%09/google.com ///%09/example.com@google.com ////%09/google.com ////%09/example.com@google.com https://%09/google.com https://%09/example.com@google.com /%5cgoogle.com /%5cexample.com@google.com //%5cgoogle.com //%5cexample.com@google.com ///%5cgoogle.com ///%5cexample.com@google.com ////%5cgoogle.com ////%5cexample.com@google.com https://%5cgoogle.com https://%5cexample.com@google.com /https://%5cgoogle.com /https://%5cexample.com@google.com https://google.com https://example.com@google.com //google.com https:google.com //google%E3%80%82com \/\/google.com/ /\/google.com/ //google%00.com http://0xd8.0x3a.0xd6.0xce http://example.com@0xd8.0x3a.0xd6.0xce http://3H6k7lIAiqjfNeN@0xd8.0x3a.0xd6.0xce http://XY>.7d8T\205pZM@0xd8.0x3a.0xd6.0xce http://0xd83ad6ce http://example.com@0xd83ad6ce http://3H6k7lIAiqjfNeN@0xd83ad6ce http://XY>.7d8T\205pZM@0xd83ad6ce http://3627734734 http://example.com@3627734734 http://3H6k7lIAiqjfNeN@3627734734 http://XY>.7d8T\205pZM@3627734734 http://472.314.470.462 http://example.com@472.314.470.462 http://3H6k7lIAiqjfNeN@472.314.470.462 http://XY>.7d8T\205pZM@472.314.470.462 http://0330.072.0326.0316 http://example.com@0330.072.0326.0316 http://3H6k7lIAiqjfNeN@0330.072.0326.0316 http://XY>.7d8T\205pZM@0330.072.0326.0316 http://00330.00072.0000326.00000316 http://example.com@00330.00072.0000326.00000316 http://3H6k7lIAiqjfNeN@00330.00072.0000326.00000316 http://XY>.7d8T\205pZM@00330.00072.0000326.00000316 http://[::216.58.214.206] http://example.com@[::216.58.214.206] http://3H6k7lIAiqjfNeN@[::216.58.214.206] http://XY>.7d8T\205pZM@[::216.58.214.206] http://[::ffff:216.58.214.206] http://example.com@[::ffff:216.58.214.206] http://3H6k7lIAiqjfNeN@[::ffff:216.58.214.206] http://XY>.7d8T\205pZM@[::ffff:216.58.214.206] http://0xd8.072.54990 http://example.com@0xd8.072.54990 http://3H6k7lIAiqjfNeN@0xd8.072.54990 http://XY>.7d8T\205pZM@0xd8.072.54990 http://0xd8.3856078 http://example.com@0xd8.3856078 http://3H6k7lIAiqjfNeN@0xd8.3856078 http://XY>.7d8T\205pZM@0xd8.3856078 http://00330.3856078 http://example.com@00330.3856078 http://3H6k7lIAiqjfNeN@00330.3856078 http://XY>.7d8T\205pZM@00330.3856078 http://00330.0x3a.54990 http://example.com@00330.0x3a.54990 http://3H6k7lIAiqjfNeN@00330.0x3a.54990 http://XY>.7d8T\205pZM@00330.0x3a.54990 http:0xd8.0x3a.0xd6.0xce http:example.com@0xd8.0x3a.0xd6.0xce http:3H6k7lIAiqjfNeN@0xd8.0x3a.0xd6.0xce http:XY>.7d8T\205pZM@0xd8.0x3a.0xd6.0xce http:0xd83ad6ce http:example.com@0xd83ad6ce http:3H6k7lIAiqjfNeN@0xd83ad6ce http:XY>.7d8T\205pZM@0xd83ad6ce http:3627734734 http:example.com@3627734734 http:3H6k7lIAiqjfNeN@3627734734 http:XY>.7d8T\205pZM@3627734734 http:472.314.470.462 http:example.com@472.314.470.462 http:3H6k7lIAiqjfNeN@472.314.470.462 http:XY>.7d8T\205pZM@472.314.470.462 http:0330.072.0326.0316 http:example.com@0330.072.0326.0316 http:3H6k7lIAiqjfNeN@0330.072.0326.0316 http:XY>.7d8T\205pZM@0330.072.0326.0316 http:00330.00072.0000326.00000316 http:example.com@00330.00072.0000326.00000316 http:3H6k7lIAiqjfNeN@00330.00072.0000326.00000316 http:XY>.7d8T\205pZM@00330.00072.0000326.00000316 http:[::216.58.214.206] http:example.com@[::216.58.214.206] http:3H6k7lIAiqjfNeN@[::216.58.214.206] http:XY>.7d8T\205pZM@[::216.58.214.206] http:[::ffff:216.58.214.206] http:example.com@[::ffff:216.58.214.206] http:3H6k7lIAiqjfNeN@[::ffff:216.58.214.206] http:XY>.7d8T\205pZM@[::ffff:216.58.214.206] http:0xd8.072.54990 http:example.com@0xd8.072.54990 http:3H6k7lIAiqjfNeN@0xd8.072.54990 http:XY>.7d8T\205pZM@0xd8.072.54990 http:0xd8.3856078 http:example.com@0xd8.3856078 http:3H6k7lIAiqjfNeN@0xd8.3856078 http:XY>.7d8T\205pZM@0xd8.3856078 http:00330.3856078 http:example.com@00330.3856078 http:3H6k7lIAiqjfNeN@00330.3856078 http:XY>.7d8T\205pZM@00330.3856078 http:00330.0x3a.54990 http:example.com@00330.0x3a.54990 http:3H6k7lIAiqjfNeN@00330.0x3a.54990 http:XY>.7d8T\205pZM@00330.0x3a.54990 〱google.com 〵google.com ゝgoogle.com ーgoogle.com ーgoogle.com /〱google.com /〵google.com /ゝgoogle.com /ーgoogle.com /ーgoogle.com %68%74%74%70%3a%2f%2f%67%6f%6f%67%6c%65%2e%63%6f%6d http://%67%6f%6f%67%6c%65%2e%63%6f%6d <>//google.com //google.com\@example.com https://:@google.com\@example.com http://google.com:80#@example.com/ http://google.com:80?@example.com/ http://3H6k7lIAiqjfNeN@example.com+@google.com/ http://XY>.7d8T\205pZM@example.com+@google.com/ http://3H6k7lIAiqjfNeN@example.com@google.com/ http://XY>.7d8T\205pZM@example.com@google.com/ http://example.com+&@google.com#+@example.com/ http://google.com\texample.com/ //google.com:80#@example.com/ //google.com:80?@example.com/ //3H6k7lIAiqjfNeN@example.com+@google.com/ //XY>.7d8T\205pZM@example.com+@google.com/ //3H6k7lIAiqjfNeN@example.com@google.com/ //XY>.7d8T\205pZM@example.com@google.com/ //example.com+&@google.com#+@example.com/ //google.com\texample.com/ //;@google.com http://;@google.com @google.com http://google.com%2f%2f.example.com/ http://google.com%5c%5c.example.com/ http://google.com%3F.example.com/ http://google.com%23.example.com/ http://example.com:80%40google.com/ http://example.com%2egoogle.com/ /https:/%5cgoogle.com/ /http://google.com /%2f%2fgoogle.com /google.com/%2f%2e%2e /http:/google.com /.google.com ///\;@google.com ///google.com /////google.com/ /////google.com //google.com/%2f%2e%2e //example.com@google.com/%2f%2e%2e ///google.com/%2f%2e%2e ///example.com@google.com/%2f%2e%2e ////google.com/%2f%2e%2e ////example.com@google.com/%2f%2e%2e https://google.com/%2f%2e%2e https://example.com@google.com/%2f%2e%2e /https://google.com/%2f%2e%2e /https://example.com@google.com/%2f%2e%2e //google.com/ //example.com@google.com/ ///google.com/ ///example.com@google.com/ ////google.com/ ////example.com@google.com/ https://google.com/ https://example.com@google.com/ /https://google.com/ /https://example.com@google.com/ //google.com// //example.com@google.com// ///google.com// ///example.com@google.com// ////google.com// ////example.com@google.com// https://google.com// https://example.com@google.com// //https://google.com// //https://example.com@google.com// //google.com/%2e%2e%2f //example.com@google.com/%2e%2e%2f ///google.com/%2e%2e%2f ///example.com@google.com/%2e%2e%2f ////google.com/%2e%2e%2f ////example.com@google.com/%2e%2e%2f https://google.com/%2e%2e%2f https://example.com@google.com/%2e%2e%2f //https://google.com/%2e%2e%2f //https://example.com@google.com/%2e%2e%2f ///google.com/%2e%2e ///example.com@google.com/%2e%2e ////google.com/%2e%2e ////example.com@google.com/%2e%2e https:///google.com/%2e%2e https:///example.com@google.com/%2e%2e //https:///google.com/%2e%2e //example.com@https:///google.com/%2e%2e /https://google.com/%2e%2e /https://example.com@google.com/%2e%2e ///google.com/%2f%2e%2e ///example.com@google.com/%2f%2e%2e ////google.com/%2f%2e%2e ////example.com@google.com/%2f%2e%2e https:///google.com/%2f%2e%2e https:///example.com@google.com/%2f%2e%2e /https://google.com/%2f%2e%2e /https://example.com@google.com/%2f%2e%2e /https:///google.com/%2f%2e%2e /https:///example.com@google.com/%2f%2e%2e /%09/google.com /%09/example.com@google.com //%09/google.com //%09/example.com@google.com ///%09/google.com ///%09/example.com@google.com ////%09/google.com ////%09/example.com@google.com https://%09/google.com https://%09/example.com@google.com /%5cgoogle.com /%5cexample.com@google.com //%5cgoogle.com //%5cexample.com@google.com ///%5cgoogle.com ///%5cexample.com@google.com ////%5cgoogle.com ////%5cexample.com@google.com https://%5cgoogle.com https://%5cexample.com@google.com /https://%5cgoogle.com /https://%5cexample.com@google.com https://google.com https://example.com@google.com //google.com https:google.com //google%E3%80%82com \/\/google.com/ /\/google.com/ //google%00.com javascript://example.com?%a0alert%281%29 http://0xd8.0x3a.0xd6.0xce http://example.com@0xd8.0x3a.0xd6.0xce http://3H6k7lIAiqjfNeN@0xd8.0x3a.0xd6.0xce http://XY>.7d8T\205pZM@0xd8.0x3a.0xd6.0xce http://0xd83ad6ce http://example.com@0xd83ad6ce http://3H6k7lIAiqjfNeN@0xd83ad6ce http://XY>.7d8T\205pZM@0xd83ad6ce http://3627734734 http://example.com@3627734734 http://3H6k7lIAiqjfNeN@3627734734 http://XY>.7d8T\205pZM@3627734734 http://472.314.470.462 http://example.com@472.314.470.462 http://3H6k7lIAiqjfNeN@472.314.470.462 http://XY>.7d8T\205pZM@472.314.470.462 http://0330.072.0326.0316 http://example.com@0330.072.0326.0316 http://3H6k7lIAiqjfNeN@0330.072.0326.0316 http://XY>.7d8T\205pZM@0330.072.0326.0316 http://00330.00072.0000326.00000316 http://example.com@00330.00072.0000326.00000316 http://3H6k7lIAiqjfNeN@00330.00072.0000326.00000316 http://XY>.7d8T\205pZM@00330.00072.0000326.00000316 http://[::216.58.214.206] http://example.com@[::216.58.214.206] http://3H6k7lIAiqjfNeN@[::216.58.214.206] http://XY>.7d8T\205pZM@[::216.58.214.206] http://[::ffff:216.58.214.206] http://example.com@[::ffff:216.58.214.206] http://3H6k7lIAiqjfNeN@[::ffff:216.58.214.206] http://XY>.7d8T\205pZM@[::ffff:216.58.214.206] http://0xd8.072.54990 http://example.com@0xd8.072.54990 http://3H6k7lIAiqjfNeN@0xd8.072.54990 http://XY>.7d8T\205pZM@0xd8.072.54990 http://0xd8.3856078 http://example.com@0xd8.3856078 http://3H6k7lIAiqjfNeN@0xd8.3856078 http://XY>.7d8T\205pZM@0xd8.3856078 http://00330.3856078 http://example.com@00330.3856078 http://3H6k7lIAiqjfNeN@00330.3856078 http://XY>.7d8T\205pZM@00330.3856078 http://00330.0x3a.54990 http://example.com@00330.0x3a.54990 http://3H6k7lIAiqjfNeN@00330.0x3a.54990 http://XY>.7d8T\205pZM@00330.0x3a.54990 http:0xd8.0x3a.0xd6.0xce http:example.com@0xd8.0x3a.0xd6.0xce http:3H6k7lIAiqjfNeN@0xd8.0x3a.0xd6.0xce http:XY>.7d8T\205pZM@0xd8.0x3a.0xd6.0xce http:0xd83ad6ce http:example.com@0xd83ad6ce http:3H6k7lIAiqjfNeN@0xd83ad6ce http:XY>.7d8T\205pZM@0xd83ad6ce http:3627734734 http:example.com@3627734734 http:3H6k7lIAiqjfNeN@3627734734 http:XY>.7d8T\205pZM@3627734734 http:472.314.470.462 http:example.com@472.314.470.462 http:3H6k7lIAiqjfNeN@472.314.470.462 http:XY>.7d8T\205pZM@472.314.470.462 http:0330.072.0326.0316 http:example.com@0330.072.0326.0316 http:3H6k7lIAiqjfNeN@0330.072.0326.0316 http:XY>.7d8T\205pZM@0330.072.0326.0316 http:00330.00072.0000326.00000316 http:example.com@00330.00072.0000326.00000316 http:3H6k7lIAiqjfNeN@00330.00072.0000326.00000316 http:XY>.7d8T\205pZM@00330.00072.0000326.00000316 http:[::216.58.214.206] http:example.com@[::216.58.214.206] http:3H6k7lIAiqjfNeN@[::216.58.214.206] http:XY>.7d8T\205pZM@[::216.58.214.206] http:[::ffff:216.58.214.206] http:example.com@[::ffff:216.58.214.206] http:3H6k7lIAiqjfNeN@[::ffff:216.58.214.206] http:XY>.7d8T\205pZM@[::ffff:216.58.214.206] http:0xd8.072.54990 http:example.com@0xd8.072.54990 http:3H6k7lIAiqjfNeN@0xd8.072.54990 http:XY>.7d8T\205pZM@0xd8.072.54990 http:0xd8.3856078 http:example.com@0xd8.3856078 http:3H6k7lIAiqjfNeN@0xd8.3856078 http:XY>.7d8T\205pZM@0xd8.3856078 http:00330.3856078 http:example.com@00330.3856078 http:3H6k7lIAiqjfNeN@00330.3856078 http:XY>.7d8T\205pZM@00330.3856078 http:00330.0x3a.54990 http:example.com@00330.0x3a.54990 http:3H6k7lIAiqjfNeN@00330.0x3a.54990 http:XY>.7d8T\205pZM@00330.0x3a.54990 〱google.com 〵google.com ゝgoogle.com ーgoogle.com ーgoogle.com /〱google.com /〵google.com /ゝgoogle.com /ーgoogle.com /ーgoogle.com %68%74%74%70%3a%2f%2f%67%6f%6f%67%6c%65%2e%63%6f%6d http://%67%6f%6f%67%6c%65%2e%63%6f%6d <>javascript:alert(1); <>//google.com //google.com\@example.com https://:@google.com\@example.com ja\nva\tscript\r:alert(1) \j\av\a\s\cr\i\pt\:\a\l\ert\(1\) \152\141\166\141\163\143\162\151\160\164\072alert(1) http://google.com:80#@example.com/ http://google.com:80?@example.com/ http://3H6k7lIAiqjfNeN@example.com+@google.com/ http://XY>.7d8T\205pZM@example.com+@google.com/ http://3H6k7lIAiqjfNeN@example.com@google.com/ http://XY>.7d8T\205pZM@example.com@google.com/ http://example.com+&@google.com#+@example.com/ http://google.com\texample.com/ //google.com:80#@example.com/ //google.com:80?@example.com/ //3H6k7lIAiqjfNeN@example.com+@google.com/ //XY>.7d8T\205pZM@example.com+@google.com/ //3H6k7lIAiqjfNeN@example.com@google.com/ //XY>.7d8T\205pZM@example.com@google.com/ //example.com+&@google.com#+@example.com/ //google.com\texample.com/ //;@google.com http://;@google.com javascript://https://example.com/?z=%0Aalert(1) http://google.com%2f%2f.example.com/ http://google.com%5c%5c.example.com/ http://google.com%3F.example.com/ http://google.com%23.example.com/ http://example.com:80%40google.com/ http://example.com%2egoogle.com/ /https:/%5cgoogle.com/ /http://google.com /%2f%2fgoogle.com /google.com/%2f%2e%2e /http:/google.com /.google.com ///\;@google.com ///google.com /////google.com/ /////google.com `) for _, rawurl := range rawurls { u, err := url.Parse(rawurl) if err != nil { continue } assert.False(t, IsRedirectAllowed(u, []string{"example.com"}), "for %s expected false", u.String()) } } func TestIsLoopback(t *testing.T) { tcs := []struct { rawurl string value bool }{ {"http://localhost", true}, {"http://test.localhost.pomerium.io", false}, {"http://127.0.0.1:9999", true}, {"http://127.22.0.1", true}, {"http://[::1]", true}, {"http://[::2]", false}, {"http://example.com", false}, } for _, tc := range tcs { u, err := url.Parse(tc.rawurl) require.NoError(t, err) assert.Equal(t, tc.value, IsLoopback(u), "for %s expected %v", u.String(), tc.value) } }