mirror of
				https://github.com/nkanaev/yarr.git
				synced 2025-11-04 08:48:45 +00:00 
			
		
		
		
	restrict private IP access
This commit is contained in:
		@@ -513,6 +513,10 @@ func (s *Server) handlePageCrawl(c *router.Context) {
 | 
			
		||||
		})
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if isInternalFromURL(url) {
 | 
			
		||||
		log.Printf("attempt to access internal IP %s from %s", url, c.Req.RemoteAddr)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	body, err := worker.GetBody(url)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								src/server/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/server/util.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func isInternalFromURL(urlStr string) bool {
 | 
			
		||||
	parsedURL, err := url.Parse(urlStr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	host := parsedURL.Host
 | 
			
		||||
 | 
			
		||||
	// Handle "host:port" format
 | 
			
		||||
	if strings.Contains(host, ":") {
 | 
			
		||||
		host, _, err = net.SplitHostPort(host)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if host == "localhost" {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ip := net.ParseIP(host)
 | 
			
		||||
	if ip == nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								src/server/util_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/server/util_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
package server
 | 
			
		||||
 | 
			
		||||
import "testing"
 | 
			
		||||
 | 
			
		||||
func TestIsInternalFromURL(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		url      string
 | 
			
		||||
		expected bool
 | 
			
		||||
	}{
 | 
			
		||||
		{"http://192.168.1.1:8080", true},
 | 
			
		||||
		{"http://10.0.0.5", true},
 | 
			
		||||
		{"http://172.16.0.1", true},
 | 
			
		||||
		{"http://172.31.255.255", true},
 | 
			
		||||
		{"http://172.32.0.1", false}, // outside private range
 | 
			
		||||
		{"http://127.0.0.1", true},
 | 
			
		||||
		{"http://127.0.0.1:7000", true},
 | 
			
		||||
		{"http://127.0.0.1:7000/secret", true},
 | 
			
		||||
		{"http://169.254.0.5", true},
 | 
			
		||||
		{"http://localhost", true}, // resolves to 127.0.0.1
 | 
			
		||||
		{"http://8.8.8.8", false},
 | 
			
		||||
		{"http://google.com", false}, // resolves to public IPs
 | 
			
		||||
		{"invalid-url", false},       // invalid format
 | 
			
		||||
		{"", false},                  // empty string
 | 
			
		||||
	}
 | 
			
		||||
	for _, test := range tests {
 | 
			
		||||
		result := isInternalFromURL(test.url)
 | 
			
		||||
		if result != test.expected {
 | 
			
		||||
			t.Errorf("isInternalFromURL(%q) = %v; want %v", test.url, result, test.expected)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user