proxydial

package module
v0.0.0-...-278b064 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 5, 2022 License: MIT Imports: 4 Imported by: 1

README

Package proxydial provides a safer equivalent to Go's builtin net.Dial, that you can use if you're acting as a proxy (or in any way making http requests to URLs you don't trust).

It prevents connections to internal IP addresses, which can cause severe vulnerabilities.

Installation

go get github.com/superhuman/proxydial

Usage

See GoDoc for usage documentation.

License

proxydial is made available under the MIT license. See LICENSE.mit for details.

Meta-fu

Bug reports and feature requests are welcome. If you think you've found a security vulnerability, please email me directly.

Documentation

Overview

Package proxydial provides a replacement for Go's builtin net.Dialer that is designed to be used in applications where you're proxying a user's request, or more generally making requests to URLs that you don't necessarily trust completely.

Usually you will use the Dial function in an HTTP Client as follows:

    client := http.Client{
        Transport: &http.Transport{
             Proxy: http.ProxyFromEnvironment,
				Dial: proxydialer.Dial,
             TLSHandshakeTimeout: 10 * time.Second
        }
    }

The advantage of the proxydialer is that it prevents connections being made to internal IP addresses (e.g. 127.0.0.1, or 169.254.169.254) or to ports that could cause harm to the rest of the internet (e.g. 22, 25).

Index

Constants

This section is empty.

Variables

View Source
var DefaultDialer = Dialer{
	AllowedNets: []string{"tcp"},

	AllowedPorts: []int16{80, 443, 8080, 8443},

	BlockedRanges: []*net.IPNet{
		cidrRange("0.0.0.0/8"),
		cidrRange("10.0.0.0/8"),
		cidrRange("100.64.0.0/10"),
		cidrRange("127.0.0.0/8"),
		cidrRange("169.254.0.0/16"),
		cidrRange("172.16.0.0/12"),
		cidrRange("192.0.0.0/24"),
		cidrRange("192.0.2.0/24"),
		cidrRange("192.88.99.0/24"),
		cidrRange("192.168.0.0/16"),
		cidrRange("198.18.0.0/15"),
		cidrRange("198.51.100.0/24"),
		cidrRange("203.0.113.0/24"),
		cidrRange("224.0.0.0/4"),
		cidrRange("240.0.0.0/4"),
		cidrRange("255.255.255.255/32"),
		cidrRange("::/128"),
		cidrRange("::1/128"),

		cidrRange("100::/64"),
		cidrRange("64:ff9b::/96"),
		cidrRange("2001::/32"),
		cidrRange("2001:10::/28"),
		cidrRange("2001:20::/28"),
		cidrRange("2001:db8::/32"),
		cidrRange("2002::/16"),
		cidrRange("fc00::/7"),
		cidrRange("fe80::/10"),
		cidrRange("ff00::/8"),
	},
	BlockMulticast:   true,
	BlockPrivate:     true,
	BlockLinkLocal:   true,
	BlockUnspecified: true,
}

DefaultDialer is a proxydialer designed for HTTP. It prevents connections to non-standard HTTP ports and internal IP addresses.

Functions

func Dial

func Dial(network, addr string) (net.Conn, error)

Dial creates a connection to the given address using DefaultDialer.Dial

Types

type Dialer

type Dialer struct {
	// AllowedNets is a whitelist of nets that connections may be made over. For http
	// this should be only []string{"tcp"}
	AllowedNets []string

	// AllowedPorts is a whitelist of ports that connections may be made to. For http
	// the usual suspects would be []int16{80, 443}, but some other ports are used
	// fairly frequently.
	AllowedPorts []int16

	// BlockedRanges is a black list of IP ranges that connections may not be made to
	// This should usually include net.ParseCIDR("127.0.0.1/8") to prevent connections
	// to localhost, in addition to any other subnets that you use internally.
	BlockedRanges []*net.IPNet

	// BlockPrivate blocks any IP on a private network
	BlockPrivate bool
	// BlockLinkLocal blocks any IP on a link local network
	BlockLinkLocal bool
	// BlockMulticast blocks any IP on a multicast network
	BlockMulticast bool
	// BlockUnspecified blocks any unspecified IP
	BlockUnspecified bool

	// Timeout is the maximum amount of time a dial will wait for
	// a connection to complete. If Deadline is also set, it may fail
	// earlier.
	//
	// The default is no timeout.
	//
	// When dialing a name with multiple IP addresses, the timeout
	// may be divided between them.
	//
	// With or without a timeout, the operating system may impose
	// its own earlier timeout. For instance, TCP timeouts are
	// often around 3 minutes.
	Timeout time.Duration

	// Deadline is the absolute point in time after which dials
	// will fail. If Timeout is set, it may fail earlier.
	// Zero means no deadline, or dependent on the operating system
	// as with the Timeout option.
	Deadline time.Time

	// KeepAlive specifies the keep-alive period for an active
	// network connection.
	// If zero, keep-alives are not enabled. Network protocols
	// that do not support keep-alives ignore this field.
	KeepAlive time.Duration

	// LocalAddr is the local address to use when dialing an
	// address. The address must be of a compatible type for the
	// network being dialed.
	// If nil, a local address is automatically chosen.
	LocalAddr net.Addr
}

Dialer lets you connect to external addresses. It's equivalent to net.Dialer from the go standard library, except that connections that are not to AllowedNets, not to AllowedPorts, or to BlockedRanges are aborted. It also does not yet support HappyEyeballs.

func (*Dialer) Dial

func (d *Dialer) Dial(network, addr string) (net.Conn, error)

Dial creates a connection to the given address. If the network is not in d.AllowedNetworks, or the port is not in d.AllowedPorts, or the IP address after DNS resolution is in b.BlockedRanges, then the connection will not be attempted.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL