Resolve SSRF in the function Execute
Add a function to block requests to private/internal addresses. SSRF resolved.
This commit is contained in:
parent
435223f500
commit
09d4f3ffb2
1 changed files with 23 additions and 0 deletions
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
@ -582,6 +583,24 @@ func (t *WebFetchTool) Parameters() map[string]any {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func blockPrivateTarget(ctx context.Context, parsedURL *url.URL) error {
|
||||||
|
hostname := parsedURL.Hostname() // strips port and IPv6 brackets
|
||||||
|
addrs, err := net.DefaultResolver.LookupHost(ctx, hostname)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not resolve host %q", hostname)
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
ip := net.ParseIP(addr)
|
||||||
|
if ip == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsUnspecified() {
|
||||||
|
return fmt.Errorf("requests to private/internal addresses are not allowed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *WebFetchTool) Execute(ctx context.Context, args map[string]any) *ToolResult {
|
func (t *WebFetchTool) Execute(ctx context.Context, args map[string]any) *ToolResult {
|
||||||
urlStr, ok := args["url"].(string)
|
urlStr, ok := args["url"].(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -601,6 +620,10 @@ func (t *WebFetchTool) Execute(ctx context.Context, args map[string]any) *ToolRe
|
||||||
return ErrorResult("missing domain in URL")
|
return ErrorResult("missing domain in URL")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := blockPrivateTarget(ctx, parsedURL); err != nil {
|
||||||
|
return ErrorResult(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
maxChars := t.maxChars
|
maxChars := t.maxChars
|
||||||
if mc, ok := args["maxChars"].(float64); ok {
|
if mc, ok := args["maxChars"].(float64); ok {
|
||||||
if int(mc) > 100 {
|
if int(mc) > 100 {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue