mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 11:11:30 -04:00
Merge branch 'bug40378' into 'main'
resolve host to IP to check if it's local before connecting See merge request tpo/anti-censorship/pluggable-transports/snowflake!413
This commit is contained in:
commit
b882d9456b
3 changed files with 49 additions and 6 deletions
|
@ -8,6 +8,7 @@ import (
|
|||
"net/http"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/pion/ice/v4"
|
||||
"github.com/pion/sdp/v3"
|
||||
|
@ -171,3 +172,22 @@ func GetCandidateAddrs(sdpStr string) []net.IP {
|
|||
}
|
||||
return sortedIpAddr
|
||||
}
|
||||
|
||||
// Checks whether the hostname is local
|
||||
func IsHostnameLocal(hostname string) bool {
|
||||
// Per https://en.wikipedia.org/wiki/Special-use_domain_name
|
||||
tlds := []string{
|
||||
".internal",
|
||||
".invalid",
|
||||
".local",
|
||||
".localhost",
|
||||
".onion",
|
||||
".test",
|
||||
}
|
||||
for _, tld := range tlds {
|
||||
if strings.HasSuffix(hostname, tld) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return hostname == "localhost"
|
||||
}
|
||||
|
|
|
@ -506,13 +506,13 @@ func TestUtilityFuncs(t *testing.T) {
|
|||
{pattern: "^snowflake.torproject.net$", allowNonTLS: false, targetURL: "wss://faketorproject.net", expects: fmt.Errorf("")},
|
||||
{pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "wss://faketorproject.net", expects: fmt.Errorf("")},
|
||||
{pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "wss://snowflake.torproject.net", expects: nil},
|
||||
{pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "wss://imaginary-01-snowflake.torproject.net", expects: nil},
|
||||
{pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "wss://imaginary-aaa-snowflake.torproject.net", expects: nil},
|
||||
{pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "wss://imaginary-01-snowflake.torproject.net", expects: fmt.Errorf("")},
|
||||
{pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "wss://imaginary-aaa-snowflake.torproject.net", expects: fmt.Errorf("")},
|
||||
{pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "wss://imaginary-aaa-snowflake.faketorproject.net", expects: fmt.Errorf("")},
|
||||
|
||||
{pattern: "^torproject.net$", allowNonTLS: false, targetURL: "wss://faketorproject.net", expects: fmt.Errorf("")},
|
||||
// Yes, this is how it works if there is no "^".
|
||||
{pattern: "torproject.net$", allowNonTLS: false, targetURL: "wss://faketorproject.net", expects: nil},
|
||||
{pattern: "torproject.net$", allowNonTLS: false, targetURL: "wss://faketorproject.net", expects: fmt.Errorf("")},
|
||||
|
||||
// NonTLS
|
||||
{pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "ws://snowflake.torproject.net", expects: fmt.Errorf("")},
|
||||
|
@ -556,8 +556,17 @@ func TestUtilityFuncs(t *testing.T) {
|
|||
{pattern: "$", allowNonTLS: true, targetURL: "//snowflake.torproject.net", expects: fmt.Errorf("")},
|
||||
{pattern: "$", allowNonTLS: true, targetURL: "/path", expects: fmt.Errorf("")},
|
||||
{pattern: "$", allowNonTLS: true, targetURL: "wss://snowflake.torproject .net", expects: fmt.Errorf("")},
|
||||
{pattern: "$", allowNonTLS: true, targetURL: "wss://😀", expects: nil},
|
||||
{pattern: "$", allowNonTLS: true, targetURL: "wss://пример.рф", expects: nil},
|
||||
{pattern: "$", allowNonTLS: true, targetURL: "wss://😀", expects: fmt.Errorf("")},
|
||||
{pattern: "$", allowNonTLS: true, targetURL: "wss://пример.рф", expects: fmt.Errorf("")},
|
||||
|
||||
// Local URLs
|
||||
{pattern: "localhost$", allowNonTLS: false, targetURL: "wss://localhost", expects: fmt.Errorf("")},
|
||||
{pattern: "test.internal$", allowNonTLS: false, targetURL: "wss://test.internal", expects: fmt.Errorf("")},
|
||||
{pattern: "test.invalid$", allowNonTLS: false, targetURL: "wss://test.invalid", expects: fmt.Errorf("")},
|
||||
{pattern: "test.localhost$", allowNonTLS: false, targetURL: "wss://test.localhost", expects: fmt.Errorf("")},
|
||||
{pattern: "test.local$", allowNonTLS: false, targetURL: "wss://test.local", expects: fmt.Errorf("")},
|
||||
{pattern: "test.onion$", allowNonTLS: false, targetURL: "wss://test.onion", expects: fmt.Errorf("")},
|
||||
{pattern: "test.test$", allowNonTLS: false, targetURL: "wss://test.test", expects: fmt.Errorf("")},
|
||||
|
||||
// Non-websocket protocols
|
||||
{pattern: "snowflake.torproject.net$", allowNonTLS: false, targetURL: "https://snowflake.torproject.net", expects: fmt.Errorf("")},
|
||||
|
|
|
@ -712,13 +712,27 @@ func checkIsRelayURLAcceptable(
|
|||
return fmt.Errorf("bad Relay URL %w", err)
|
||||
}
|
||||
if !allowPrivateIPs {
|
||||
ip := net.ParseIP(parsedRelayURL.Hostname())
|
||||
hostname := parsedRelayURL.Hostname()
|
||||
if util.IsHostnameLocal(hostname) {
|
||||
return fmt.Errorf("rejected Relay URL: private hostnames are not allowed")
|
||||
}
|
||||
ip := net.ParseIP(hostname)
|
||||
// Otherwise it's a domain name, or an invalid IP.
|
||||
if ip != nil {
|
||||
// We should probably use a ready library for this.
|
||||
if !isRemoteAddress(ip) {
|
||||
return fmt.Errorf("rejected Relay URL: private IPs are not allowed")
|
||||
}
|
||||
} else {
|
||||
ipArray, err := net.LookupIP(hostname)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not look up IP %s", hostname)
|
||||
}
|
||||
for _, ip := range ipArray {
|
||||
if !isRemoteAddress(ip) {
|
||||
return fmt.Errorf("rejected Relay URL: private IPs are not allowed")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !allowNonTLSRelay && parsedRelayURL.Scheme != "wss" {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue