Skip to content

net: reject leading zeros in IP address parsers [freeze exception] #30999

Closed

Description

What version of Go are you using (go version)?

$ go version
go version go1.12.1 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/xxx/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/xxx/gocode"
GOPROXY=""
GORACE=""
GOROOT="/home/xxx/go"
GOTMPDIR=""
GOTOOLDIR="/home/xxx/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build040813268=/tmp/go-build -gno-record-gcc-switches"

What did you do?

package main

import "net/http"

func main() {
	http.Get("http://7.7.7.017")
}

What did you expect to see?

7.7.7.017 is interpreted as 7.7.7.15.

$ ping 7.7.7.017
PING 7.7.7.017 (7.7.7.15) 56(84) bytes of data.

What did you see instead?

The program tries to connect to 7.7.7.17.

Activity

  1. changed the title [-]net/http: octal literals in IP addresses are interpreted as decimal ones[/-] [+]net/url: Parse interprets octal literals in IP addresses as decimal ones[/+] on Mar 22, 2019
  2. agnivade commented on Mar 22, 2019

    @agnivade
    Contributor

    This is more of a net/url issue rather than net/http.

    What does the RFC say regarding this ?

  3. added
    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
    on Apr 22, 2019
  4. added this to the Go1.13 milestone on Apr 22, 2019
  5. modified the milestones: Go1.13, Go1.14 on Jul 8, 2019
  6. modified the milestones: Go1.14, Backlog on Oct 9, 2019
  7. secenv commented on Mar 31, 2021

    @secenv

    As shown in this recent article, this behavior could be used in server-side request forgery, local file inclusion and remote file inclusion vulnerabilities.

  8. tv42 commented on Mar 31, 2021

    @tv42

    There is no real RFC on textual IP address representation. The best we have is https://tools.ietf.org/html/draft-main-ipaddr-text-rep-02 which says

    All the forms except for decimal octets are seen as non-standard (despite being quite widely interoperable) and undesirable.

    I'd argue Go net.ParseIP/ParseCIDR etc should return an error on zero-prefixed input. It avoids ambiguity and since Go has historically parsed them differently than BSD, an error is a safer change in behavior than silently giving different results.

    See also https://man7.org/linux/man-pages/man3/inet_pton.3.html which does not accept zero-prefixed IPs.

  9. tv42 commented on Mar 31, 2021

    @tv42

    And as I discussed with @secenv on IRC, that article is naive. Typical "attacks" that 0127.0.0.1 enables are enabled also by evil.example.com A 127.0.0.1 in DNS, and the fix for both is to check the target IP after resolving, basically &http.Client{Transport: &http.Transport{DialContext: dialOnlySafeIPs}}

  10. secenv commented on Mar 31, 2021

    @secenv

    I forgot to add that it is indeed an issue that affects net.ParseCIDR https://play.golang.org/p/HpWqhr9tZ53 . I agree with @tv42, those functions should return errors. The documentation should at least warn the developer.

    Guess I should mention @FiloSottile for further discussion on the security impact of this issue.

  11. tv42 commented on Mar 31, 2021

    @tv42

    I found a more authoritative RFC on IP address textual representation -- although it's only Informational not Standards Track: https://tools.ietf.org/html/rfc6943#section-3.1.1

    Since Go doesn't use the "loose" syntax of RFC6943, it's non-conforming already. Rejecting non-dotted-decimal inputs would make Go use the "strict" syntax.

  12. rsc commented on Apr 5, 2021

    @rsc
    Contributor

    I agree about changing Go's IP address parsers
    (ParseIP, ParseCIDR, any others) to reject leading zeros (except "0"),
    because:

    (1) the RFCs are mostly quiet but in a few places hint that decimal is the right interpretation,
    (2) Go interprets leading zeros as decimal, and
    (3) BSD stacks nonetheless interpret leading zeros as octal.
    (4) The fact that basically no one has noticed this divergence implies
    that essentially no one uses leading zeros in IP addresses.

    It seems like an open question whether this should be done
    in a point release or saved for the next major release (Go 1.17).
    But to start, we should agree to do it at all.
    Adding to the proposal process.

  13. 54 remaining items

  14. benjsmi commented on Sep 22, 2021

    @benjsmi

    So I'm not seeing this issue specifically mentioned in the Go 1.16 release notes -- is CVE-2021-29923 addressed in Go 1.16.x? And if so, which x?

  15. ianlancetaylor commented on Sep 22, 2021

    @ianlancetaylor
    Contributor

    The net.ParseIP function rejects IPv4 addresses that contain decimal components with leading zeros in Go 1.17 but not in Go 1.16.

    Per #30999 (comment) we do not plan to backport this change to Go 1.16.

  16. gopherbot commented on Nov 5, 2021

    @gopherbot
    Contributor

    Change https://golang.org/cl/361534 mentions this issue: net/netip: don't accept ParseAddr with leading zeros

  17. moved this to Accepted in Proposalson Aug 10, 2022
  18. added a commit that references this issue on Sep 15, 2022
  19. removed this from Proposalson Oct 19, 2022
  20. added a commit that references this issue on Mar 5, 2023
  21. locked and limited conversation to collaborators on Jun 23, 2023
  22. added a commit that references this issue on Apr 29, 2024
    d3e3d03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions