Go: net: should expand IP address 1.1 to 1.0.0.1

Created on 28 Jan 2020  Â·  13Comments  Â·  Source: golang/go

nameserver 1.1 in /etc/resolv.conf not parsed

What did you do?

go get github.com/kevinburke/twilio-go

What did you see instead?

go get github.com/kevinburke/twilio-go: module github.com/kevinburke/twilio-go:
Get https://proxy.golang.org/github.com/kevinburke/twilio-go/@v/list:
dial tcp: lookup proxy.golang.org on [::1]:53: dial tcp [::1]:53:
connect: connection refused

Workaround

Change 1.1 to 1.0.0.1 or 1.1.1.1 in /etc/resolv.conf

# /etc/resolv.conf
nameserver 1.1
NeedsInvestigation

Most helpful comment

Well, that's just about all the internet I can handle today. Good evening

All 13 comments

Looking at http://man7.org/linux/man-pages/man5/resolv.conf.5.html, name server is defined to be an IPV4 or IPV6 address, nameserver 1.1 appears to be neither so I don't see how it could be used as a DNS server.

Why did you expect that Go would be able to use 1.1 as a nameserver?

1.1 should expand to 1.0.0.1

Examples:

Try putting nameserver 1.1 into resolv.conf and then ping something; your resolver should properly use that resolver.

Or, just ping 1.1 or traceroute 1.1, or ping 127.1. On Linux (but apparently not Mac), you can even ping 0 (which expands to 0.0.0.0)

CloudFlare's public nameservers are documented at: https://1.1/ (which should be a working link in your browser)

dig google.com @1.1
....
;; ANSWER SECTION:
google.com.     120 IN  A   172.217.6.142
....
;; SERVER: 1.0.0.1#53(1.0.0.1)

The expansion rules are covered here (part of POSIX / IEEE 1003.1).

http://man7.org/linux/man-pages/man3/inet_addr.3.html

#! /usr/bin/env python

import socket
print(socket.gethostbyname('1.1'))
# '1.0.0.1'

It appears that net does not properly expand and parse IPv4 in this format, so that might be the underlying cause here.

This is part of POSIX (IEEE 1003.1).

Do you have a citation for that? I didn't think that IEEE 1003.1 talked about networking at all. Thanks.

package main

import (
    "fmt"
    "net"
    "os"
)

func main() {
    ip := net.ParseIP("1.1")
    if ip.To4() == nil {
        fmt.Printf("IPv4 expansion is not working.")
        os.Exit(1)
    }
}

Sorry Ian, but technically he is right. Couldn't find a way to link into
the relevant part of the spec. Rgds, Nigel Vickers

The Open Group Base Specifications Issue 7, 2018 edition
IEEE Std 1003.1â„¢-2017 (Revision of IEEE Std 1003.1-2008)
Copyright © 2001-2018 IEEE and The Open Group

include

in_addr_t inet_addr(const char *cp);
char *inet_ntoa(struct in_addr in);

DESCRIPTION
The inet_addr() function shall convert the string pointed to by cp, in the
standard IPv4 dotted decimal notation, to an integer value suitable for use
as an Internet address.

The inet_ntoa() function shall convert the Internet host address specified
by in to a string in the Internet standard dot notation.

The inet_ntoa() function need not be thread-safe.

All Internet addresses shall be returned in network order (bytes ordered
from left to right).

Values specified using IPv4 dotted decimal notation take one of the
following forms:

a.b.c.d
When four parts are specified, each shall be interpreted as a byte of data
and assigned, from left to right, to the four bytes of an Internet address.
a.b.c
When a three-part address is specified, the last part shall be interpreted
as a 16-bit quantity and placed in the rightmost two bytes of the network
address. This makes the three-part address format convenient for specifying
Class B network addresses as "128.net.host".
a.b
When a two-part address is supplied, the last part shall be interpreted as
a 24-bit quantity and placed in the rightmost three bytes of the network
address. This makes the two-part address format convenient for specifying
Class A network addresses as "net.host".
a
When only one part is given, the value shall be stored directly in the
network address without any byte rearrangement.
All numbers supplied as parts in IPv4 dotted decimal notation may be
decimal, octal, or hexadecimal, as specified in the ISO C standard (that
is, a leading 0x or 0X implies hexadecimal; otherwise, a leading '0'
implies octal; otherwise, the number is interpreted as decimal).

On Tue, 28 Jan 2020 at 16:25, Ian Lance Taylor notifications@github.com
wrote:

This is part of POSIX (IEEE 1003.1).

Do you have a citation for that? I didn't think that IEEE 1003.1 talked
about networking at all. Thanks.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/golang/go/issues/36822?email_source=notifications&email_token=ABAB73CP5DM7F6MOV672SZ3RABE5JA5CNFSM4KMLTTQ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKDWG6A#issuecomment-579298168,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABAB73GUHRTR33H4XTS7SULRABE5JANCNFSM4KMLTTQQ
.

Thanks for the pointer.

Indeed, TIL!

Well, that's just about all the internet I can handle today. Good evening

Are there any security issues related to this potentially changing behavior in higher level packages(net/http, etc)? I think it may be a good idea to make a note about the potential for SSRF and other security problems on the release notes if/when this is changed.

ie if you are filtering some internal address like 192.168.0.2 you could potentially expand via 192.168.2 and a simple filter might not catch it. I know best practice is to use proxy hosts setup on separate networks/subnets but it's been shown in the past with major programs(github enterprise) that many webhook implementations skip this or use alternative methods.

https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf

Good point (and that's an awesome presentation.)

I'm not clear on what exact attack vector you're suggesting here -- are we talking about URL routing with embedded IP's, general input sanitation, other protocols, etc. It seems like most naive implementations that would be expecting an IPv4 at all should also enforce a dotted-quad input sanitation filter, since any developer that would just allow untrusted input without even the bare minimum of bounds checking for some sort of properly formed IP (whatever that means to the developer!) will probably have far larger issues anyway.

Even if the developer has some inscrutable take on what an IPv4 "looks" like, in practice this expansion isn't really much different from how you can drop octets in IPv6, so perhaps the behavior should match whatever is currently done for IPv6 octets.

One POSIX online reference is on opengroup
Searching for inet_addr returns the page pasted above.

Change https://golang.org/cl/268259 mentions this issue: net: expand IP when octets are missing

Was this page helpful?
0 / 5 - 0 ratings