validate.go (4142B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package netutil 19 20 import ( 21 "net/netip" 22 ) 23 24 var ( 25 // IPv6Reserved contains IPv6 reserved IP prefixes. 26 // https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml 27 IPv6Reserved = [...]netip.Prefix{ 28 netip.MustParsePrefix("::1/128"), // Loopback 29 netip.MustParsePrefix("::/128"), // Unspecified address 30 netip.MustParsePrefix("::ffff:0:0/96"), // IPv4-mapped address 31 netip.MustParsePrefix("64:ff9b::/96"), // IPv4/IPv6 translation, RFC 6052 32 netip.MustParsePrefix("64:ff9b:1::/48"), // IPv4/IPv6 translation, RFC 8215 33 netip.MustParsePrefix("100::/64"), // Discard prefix, RFC 6666 34 netip.MustParsePrefix("2001::/23"), // IETF Protocol Assignments, RFC 2928 35 netip.MustParsePrefix("2001:db8::/32"), // Test, doc, examples 36 netip.MustParsePrefix("2002::/16"), // 6to4 37 netip.MustParsePrefix("2620:4f:8000::/48"), // Direct Delegation AS112 Service, RFC 7534 38 netip.MustParsePrefix("fc00::/7"), // Unique Local 39 netip.MustParsePrefix("fe80::/10"), // Link-local 40 netip.MustParsePrefix("fec0::/10"), // Site-local, deprecated 41 netip.MustParsePrefix("ff00::/8"), // Multicast 42 } 43 44 // IPv4Reserved contains IPv4 reserved IP prefixes. 45 // https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml 46 IPv4Reserved = [...]netip.Prefix{ 47 netip.MustParsePrefix("0.0.0.0/8"), // Current network 48 netip.MustParsePrefix("10.0.0.0/8"), // Private 49 netip.MustParsePrefix("100.64.0.0/10"), // RFC6598 50 netip.MustParsePrefix("127.0.0.0/8"), // Loopback 51 netip.MustParsePrefix("169.254.0.0/16"), // Link-local 52 netip.MustParsePrefix("172.16.0.0/12"), // Private 53 netip.MustParsePrefix("192.0.0.0/24"), // RFC6890 54 netip.MustParsePrefix("192.0.2.0/24"), // Test, doc, examples 55 netip.MustParsePrefix("192.31.196.0/24"), // AS112-v4, RFC 7535 56 netip.MustParsePrefix("192.52.193.0/24"), // AMT, RFC 7450 57 netip.MustParsePrefix("192.88.99.0/24"), // IPv6 to IPv4 relay 58 netip.MustParsePrefix("192.168.0.0/16"), // Private 59 netip.MustParsePrefix("192.175.48.0/24"), // Direct Delegation AS112 Service, RFC 7534 60 netip.MustParsePrefix("198.18.0.0/15"), // Benchmarking tests 61 netip.MustParsePrefix("198.51.100.0/24"), // Test, doc, examples 62 netip.MustParsePrefix("203.0.113.0/24"), // Test, doc, examples 63 netip.MustParsePrefix("224.0.0.0/4"), // Multicast 64 netip.MustParsePrefix("240.0.0.0/4"), // Reserved (includes broadcast / 255.255.255.255) 65 } 66 ) 67 68 // ValidateAddr will parse a netip.AddrPort from string, and return the result of ValidateIP() on addr. 69 func ValidateAddr(s string) bool { 70 ipport, err := netip.ParseAddrPort(s) 71 if err != nil { 72 return false 73 } 74 return ValidateIP(ipport.Addr()) 75 } 76 77 // ValidateIP returns whether IP is an IPv4/6 address in non-reserved, public ranges. 78 func ValidateIP(ip netip.Addr) bool { 79 switch { 80 // IPv4: check if IPv4 in reserved nets 81 case ip.Is4(): 82 for _, reserved := range IPv4Reserved { 83 if reserved.Contains(ip) { 84 return false 85 } 86 } 87 return true 88 89 // IPv6: check if IP in IPv6 reserved nets 90 case ip.Is6(): 91 for _, reserved := range IPv6Reserved { 92 if reserved.Contains(ip) { 93 return false 94 } 95 } 96 return true 97 98 // Assume malicious by default 99 default: 100 return false 101 } 102 }