Resolve issue with localhost/local network redirects
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
5fe59dddab
commit
c3935b1d3c
61
default.go
61
default.go
@ -6,6 +6,7 @@ import (
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
@ -19,6 +20,35 @@ const (
|
||||
maxBodySizeBytes = 20971520
|
||||
)
|
||||
|
||||
var privateIPBlocks []*net.IPNet
|
||||
|
||||
func init() {
|
||||
for _, cidr := range []string{
|
||||
"127.0.0.0/8", // IPv4 loopback
|
||||
"10.0.0.0/8", // RFC1918
|
||||
"172.16.0.0/12", // RFC1918
|
||||
"192.168.0.0/16", // RFC1918
|
||||
"::1/128", // IPv6 loopback
|
||||
"fe80::/10", // IPv6 link-local
|
||||
"fc00::/7", // IPv6 unique local addr
|
||||
} {
|
||||
_, block, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("parse error on %q: %v", cidr, err))
|
||||
}
|
||||
privateIPBlocks = append(privateIPBlocks, block)
|
||||
}
|
||||
}
|
||||
|
||||
func isPrivateIP(ip net.IP) bool {
|
||||
for _, block := range privateIPBlocks {
|
||||
if block.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (api *LinkInfoApi) DefaultLinkHandler(link string) (*LinkInfo, error) {
|
||||
redirects := make([]string, 0)
|
||||
|
||||
@ -28,6 +58,12 @@ func (api *LinkInfoApi) DefaultLinkHandler(link string) (*LinkInfo, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if u.Host == "localhost" {
|
||||
return nil, errors.New("url is localhost")
|
||||
} else if ip := net.ParseIP(u.Host); ip != nil && isPrivateIP(ip) {
|
||||
return nil, errors.New("url is a local ip address")
|
||||
}
|
||||
|
||||
var res *http.Response
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
@ -39,6 +75,19 @@ func (api *LinkInfoApi) DefaultLinkHandler(link string) (*LinkInfo, error) {
|
||||
|
||||
if (res.StatusCode == 301 || res.StatusCode == 302) && res.Header.Get("Location") != "" {
|
||||
link = res.Header.Get("Location")
|
||||
|
||||
redirectUrl, err := url.Parse(link)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if redirectUrl.Host == "localhost" {
|
||||
return nil, errors.New("url attempted to redirect to localhost")
|
||||
} else if ip := net.ParseIP(redirectUrl.Host); ip != nil && isPrivateIP(ip) {
|
||||
return nil, errors.New("host is a local ip address")
|
||||
}
|
||||
|
||||
redirects = append(redirects, link)
|
||||
} else {
|
||||
break
|
||||
@ -140,7 +189,7 @@ func (api *LinkInfoApi) retrieveHtmlLinkTitle(i *LinkInfo, link string) error {
|
||||
metaTags := make(map[string]string)
|
||||
|
||||
meta.Each(func(_ int, s *goquery.Selection) {
|
||||
var key string
|
||||
var key, value string
|
||||
var exists bool
|
||||
|
||||
for _, k := range attrKeys {
|
||||
@ -154,6 +203,14 @@ func (api *LinkInfoApi) retrieveHtmlLinkTitle(i *LinkInfo, link string) error {
|
||||
if key == "" {
|
||||
return
|
||||
}
|
||||
|
||||
value, exists = s.Attr("content")
|
||||
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
|
||||
metaTags[key] = value
|
||||
})
|
||||
|
||||
var attr string
|
||||
@ -161,7 +218,7 @@ func (api *LinkInfoApi) retrieveHtmlLinkTitle(i *LinkInfo, link string) error {
|
||||
|
||||
if attr, exists = metaTags["og:title"]; exists {
|
||||
i.Title = attr
|
||||
} else if tag := q.Find("title"); tag.Length() > 0 {
|
||||
} else if tag := q.Find("head > title"); tag.Length() > 0 {
|
||||
i.Title = strings.TrimSpace(tag.Text())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user