Skip to content

Use the golang pre1.17 network parsers, that allow leading zeros on IPv4 addresses

License

Notifications You must be signed in to change notification settings

danwinship/sloppy-netparser

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sloppy Net parsers

Golang 1.17 released with a necessary breaking change on the net parsers, rejecting leading zeros in IP addresses.

There is a security CVE associated https://github.com/sickcodes/security/blob/master/advisories/SICK-2021-016.md because leading zeros can cause parser misalignment between golang and other implementations, and this be exploited by malicious actors.

Basically the problem is that Golang interprets leading zeros as decimal:

10.008.011.012 = 10.8.11.12

However, other implementations interpret leading zeros as octal, per example, ping or iptables:

$ iptables -A INPUT -d 10.008.011.012 -m comment --comment test-ip-zeros -j ACCEPT
$ iptables-save | grep test-ip-zero
-A INPUT -d 10.8.9.10/32 -m comment --comment test-ip-zeros -j ACCEPT

The Kubernetes project has to keep compatibility with previous stored values, so it has forked the previous golang parsers as part of "k8s.io/utils/net": ParseIPSloppy() and ParseCIDRSloppy()

kubernetes/utils#207

However, refactoring the code to replace the standard lib network parsers is complex, even more complicated on networking projects, where these functions are heavily used.

This tool converts the standard library functions to the forked ones, it can work on files or on paths, replacing every occurrence of net.ParseIP or net.ParseCIDR by its previous versions (1.16-), and fixing the imports accordenly.

It can rewrite the file directly or just output the difference without doing any modification

$ sloppy-netparser -diff cmd/kubeadm/app/constants/constants.go

real    0m0,007s
user    0m0,006s
sys     0m0,001s
[aojea@juanan kubernetes]$ ^C
[aojea@juanan kubernetes]$ git restore cmd/kubeadm/app/constants/constants.go
[aojea@juanan kubernetes]$ ../../github.com/aojea/sloppy-netparser/sloppy-netparser -diff cmd/kubeadm/app/constants/constants.go
cmd/kubeadm/app/constants/constants.go: fixed sloppy-netparsers
diff cmd/kubeadm/app/constants/constants.go fixed/cmd/kubeadm/app/constants/constants.go
--- /tmp/go-fix586224454        2021-08-19 19:38:16.170615958 +0200
+++ /tmp/go-fix437319661        2021-08-19 19:38:16.170615958 +0200
@@ -34,7 +34,7 @@
        apimachineryversion "k8s.io/apimachinery/pkg/version"
        bootstrapapi "k8s.io/cluster-bootstrap/token/api"
        componentversion "k8s.io/component-base/version"
-       utilnet "k8s.io/utils/net"
+       netutils "k8s.io/utils/net"
 )
 
 const (
@@ -635,7 +635,7 @@
        }
 
        // Selects the 10th IP in service subnet CIDR range as dnsIP
-       dnsIP, err := utilnet.GetIndexedIP(svcSubnetCIDR, 10)
+       dnsIP, err := netutils.GetIndexedIP(svcSubnetCIDR, 10)
        if err != nil {
                return nil, errors.Wrap(err, "unable to get internal Kubernetes Service IP from the given service CIDR")
        }
@@ -649,7 +649,7 @@
                // The default service address family for the cluster is the address family of the first
                // service cluster IP range configured via the `--service-cluster-ip-range` flag
                // of the kube-controller-manager and kube-apiserver.
-               svcSubnets, err := utilnet.ParseCIDRs(strings.Split(svcSubnetList, ","))
+               svcSubnets, err := netutils.ParseCIDRs(strings.Split(svcSubnetList, ","))
                if err != nil {
                        return nil, errors.Wrapf(err, "unable to parse ServiceSubnet %v", svcSubnetList)
                }
@@ -659,7 +659,7 @@
                return svcSubnets[0], nil
        }
        // internal IP address for the API server
-       _, svcSubnet, err := net.ParseCIDR(svcSubnetList)
+       _, svcSubnet, err := netutils.ParseCIDRSloppy(svcSubnetList)
        if err != nil {
                return nil, errors.Wrapf(err, "unable to parse ServiceSubnet %v", svcSubnetList)
        }
@@ -672,7 +672,7 @@
        if err != nil {
                return nil, errors.Wrap(err, "unable to get internal Kubernetes Service IP from the given service CIDR")
        }
-       internalAPIServerVirtualIP, err := utilnet.GetIndexedIP(svcSubnet, 1)
+       internalAPIServerVirtualIP, err := netutils.GetIndexedIP(svcSubnet, 1)
        if err != nil {
                return nil, errors.Wrapf(err, "unable to get the first IP address from the given CIDR: %s", svcSubnet.String())
        }

About

Use the golang pre1.17 network parsers, that allow leading zeros on IPv4 addresses

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 100.0%