Check for DNS rebinding attacks
This commit is contained in:
111
internal/dnsforward/rebind_test.go
Normal file
111
internal/dnsforward/rebind_test.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package dnsforward
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRebindingPrivateAddresses(t *testing.T) {
|
||||
c := &dnsRebindChecker{}
|
||||
|
||||
r1 := byte(rand.Int31() & 0xFE)
|
||||
r2 := byte(rand.Int31() & 0xFE)
|
||||
r3 := byte(rand.Int31() & 0xFE)
|
||||
|
||||
for _, ip := range []net.IP{
|
||||
net.IPv4(0, r1, r2, r3), /* 0.0.0.0/8 (RFC 5735 section 3. "here" network) */
|
||||
net.IPv4(127, r1, r2, r3), /* 127.0.0.0/8 (loopback) */
|
||||
net.IPv4(10, r1, r2, r3), /* 10.0.0.0/8 (private) */
|
||||
net.IPv4(172, 0x10|byte(1&rand.Int31()), r2, r3), /* 172.16.0.0/12 (private) */
|
||||
net.IPv4(192, 168, r2, r3), /* 192.168.0.0/16 (private) */
|
||||
net.IPv4(169, 254, r2, r3), /* 169.254.0.0/16 (zeroconf) */
|
||||
net.IPv4(192, 0, 2, r3), /* 192.0.2.0/24 (test-net) */
|
||||
net.IPv4(198, 51, 100, r3), /* 198.51.100.0/24(test-net) */
|
||||
net.IPv4(203, 0, 113, r3), /* 203.0.113.0/24 (test-net) */
|
||||
net.IPv4(255, 255, 255, 255), /* 255.255.255.255/32 (broadcast)*/
|
||||
|
||||
/* RFC 6303 4.3 (unspecified & loopback) */
|
||||
net.IPv6zero,
|
||||
net.IPv6unspecified,
|
||||
|
||||
/* RFC 6303 4.4 */
|
||||
/* RFC 6303 4.5 */
|
||||
/* RFC 6303 4.6 */
|
||||
net.IPv6interfacelocalallnodes,
|
||||
net.IPv6linklocalallnodes,
|
||||
net.IPv6linklocalallrouters,
|
||||
|
||||
/* (TODO) Check IPv4-mapped IPv6 addresses */
|
||||
} {
|
||||
assert.Truef(t, c.isRebindIP(ip), "%s is not a rebind", ip)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRebindLocalhost(t *testing.T) {
|
||||
c := &dnsRebindChecker{}
|
||||
assert.False(t, c.isRebindHost("example.com"))
|
||||
assert.False(t, c.isRebindHost("200.0.0.1"))
|
||||
assert.True(t, c.isRebindHost("127.0.0.1"))
|
||||
assert.True(t, c.isRebindHost("localhost"))
|
||||
}
|
||||
|
||||
func TestIsResponseRebind(t *testing.T) {
|
||||
s := &Server{}
|
||||
s.conf.RebindingAllowedHosts = []string{
|
||||
"totally-safe.com",
|
||||
}
|
||||
|
||||
for _, host := range []string{
|
||||
"0.1.2.3", /* 0.0.0.0/8 (RFC 5735 section 3. "here" network) */
|
||||
"127.1.2.3", /* 127.0.0.0/8 (loopback) */
|
||||
"10.1.2.3", /* 10.0.0.0/8 (private) */
|
||||
"172.16.2.3", /* 172.16.0.0/12 (private) */
|
||||
"192.168.2.3", /* 192.168.0.0/16 (private) */
|
||||
"169.254.2.3", /* 169.254.0.0/16 (zeroconf) */
|
||||
"192.0.2.3", /* 192.0.2.0/24 (test-net) */
|
||||
"198.51.100.3", /* 198.51.100.0/24(test-net) */
|
||||
"203.0.113.3", /* 203.0.113.0/24 (test-net) */
|
||||
"255.255.255.255", /* 255.255.255.255/32 (broadcast)*/
|
||||
|
||||
/* RFC 6303 4.3 (unspecified & loopback) */
|
||||
net.IPv6zero.String(),
|
||||
net.IPv6unspecified.String(),
|
||||
|
||||
/* RFC 6303 4.4 */
|
||||
/* RFC 6303 4.5 */
|
||||
/* RFC 6303 4.6 */
|
||||
net.IPv6interfacelocalallnodes.String(),
|
||||
net.IPv6linklocalallnodes.String(),
|
||||
net.IPv6linklocalallrouters.String(),
|
||||
|
||||
"localhost",
|
||||
} {
|
||||
s.conf.RebindingEnabled = true
|
||||
assert.True(t, s.isResponseRebind("example.com", host))
|
||||
assert.False(t, s.isResponseRebind("totally-safe.com", host))
|
||||
assert.False(t, s.isResponseRebind("absolutely.totally-safe.com", host))
|
||||
|
||||
s.conf.RebindingEnabled = false
|
||||
assert.False(t, s.isResponseRebind("example.com", host))
|
||||
assert.False(t, s.isResponseRebind("totally-safe.com", host))
|
||||
assert.False(t, s.isResponseRebind("absolutely.totally-safe.com", host))
|
||||
}
|
||||
|
||||
for _, host := range []string{
|
||||
"200.168.2.3",
|
||||
"another-example.com",
|
||||
} {
|
||||
s.conf.RebindingEnabled = true
|
||||
assert.False(t, s.isResponseRebind("example.com", host))
|
||||
assert.False(t, s.isResponseRebind("totally-safe.com", host))
|
||||
assert.False(t, s.isResponseRebind("absolutely.totally-legit.com", host))
|
||||
|
||||
s.conf.RebindingEnabled = false
|
||||
assert.False(t, s.isResponseRebind("example.com", host))
|
||||
assert.False(t, s.isResponseRebind("totally-safe.com", host))
|
||||
assert.False(t, s.isResponseRebind("absolutely.totally-legit.com", host))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user