mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-12 18:32:14 +01:00
fix(outbound)!: per-module deny-private-ips and deny-public-ips, permissive defaults
This commit is contained in:
@@ -127,15 +127,19 @@ func webhookMiddleware(w *Webhook) api.Middleware {
|
||||
}
|
||||
|
||||
// Let's check if the webhook URLs are acceptable according to our
|
||||
// allowed/denied lists, and against the IP-based outbound URL
|
||||
// guard. See [gotenberg.FilterOutboundURL].
|
||||
err := gotenberg.FilterOutboundURL(ctx, webhookUrl, w.allowList, w.denyList, deadline)
|
||||
// allowed/denied lists, and against the IP-class options.
|
||||
// See [gotenberg.FilterOutboundURL].
|
||||
ipOpts := []gotenberg.DecideOption{
|
||||
gotenberg.WithDenyPrivateIPs(w.denyPrivateIPs),
|
||||
gotenberg.WithDenyPublicIPs(w.denyPublicIPs),
|
||||
}
|
||||
err := gotenberg.FilterOutboundURL(ctx, webhookUrl, w.allowList, w.denyList, deadline, ipOpts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("filter webhook URL: %w", err)
|
||||
}
|
||||
|
||||
if webhookErrorUrl != "" {
|
||||
err = gotenberg.FilterOutboundURL(ctx, webhookErrorUrl, w.errorAllowList, w.errorDenyList, deadline)
|
||||
err = gotenberg.FilterOutboundURL(ctx, webhookErrorUrl, w.errorAllowList, w.errorDenyList, deadline, ipOpts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("filter webhook error URL: %w", err)
|
||||
}
|
||||
@@ -198,7 +202,7 @@ func webhookMiddleware(w *Webhook) api.Middleware {
|
||||
|
||||
// Filter the events URL if provided.
|
||||
if webhookEventsUrl != "" {
|
||||
err = gotenberg.FilterOutboundURL(ctx, webhookEventsUrl, w.allowList, w.denyList, deadline)
|
||||
err = gotenberg.FilterOutboundURL(ctx, webhookEventsUrl, w.allowList, w.denyList, deadline, ipOpts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("filter webhook events URL: %w", err)
|
||||
}
|
||||
@@ -220,7 +224,7 @@ func webhookMiddleware(w *Webhook) api.Middleware {
|
||||
startTime: startTime,
|
||||
|
||||
client: &retryablehttp.Client{
|
||||
HTTPClient: gotenberg.NewOutboundHttpClient(w.clientTimeout, w.allowList, w.denyList),
|
||||
HTTPClient: gotenberg.NewOutboundHttpClient(w.clientTimeout, w.allowList, w.denyList, ipOpts...),
|
||||
RetryMax: w.maxRetry,
|
||||
RetryWaitMin: w.retryMinWait,
|
||||
RetryWaitMax: w.retryMaxWait,
|
||||
|
||||
@@ -23,6 +23,8 @@ type Webhook struct {
|
||||
denyList []*regexp2.Regexp
|
||||
errorAllowList []*regexp2.Regexp
|
||||
errorDenyList []*regexp2.Regexp
|
||||
denyPrivateIPs bool
|
||||
denyPublicIPs bool
|
||||
maxRetry int
|
||||
retryMinWait time.Duration
|
||||
retryMaxWait time.Duration
|
||||
@@ -39,7 +41,9 @@ func (w *Webhook) Descriptor() gotenberg.ModuleDescriptor {
|
||||
fs := flag.NewFlagSet("webhook", flag.ExitOnError)
|
||||
fs.Bool("webhook-enable-sync-mode", false, "Enable synchronous mode for the webhook feature")
|
||||
fs.StringSlice("webhook-allow-list", []string{}, "Set the allowed URLs for the webhook feature using regular expressions - supports multiple values")
|
||||
fs.StringSlice("webhook-deny-list", []string{`^https?://(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|169\.254\.|0\.0\.0\.0|127\.|localhost|\[::1\]|\[fd)`}, "Set the denied URLs for the webhook feature using regular expressions - supports multiple values")
|
||||
fs.StringSlice("webhook-deny-list", []string{}, "Set the denied URLs for the webhook feature using regular expressions - supports multiple values")
|
||||
fs.Bool("webhook-deny-private-ips", false, "Reject webhook URLs whose host resolves to a non-public IP address (loopback, RFC1918, link-local, unique-local). Enable on deployments that accept untrusted webhook destinations to mitigate SSRF against internal services")
|
||||
fs.Bool("webhook-deny-public-ips", false, "Reject webhook URLs whose host resolves to a public IP address. Enable on air-gapped or data-governed deployments to prevent callbacks from leaving a private network")
|
||||
fs.Int("webhook-max-retry", 4, "Set the maximum number of retries for the webhook feature")
|
||||
|
||||
// Deprecated flags.
|
||||
@@ -72,6 +76,8 @@ func (w *Webhook) Provision(ctx *gotenberg.Context) error {
|
||||
w.denyList = flags.MustRegexpSlice("webhook-deny-list")
|
||||
w.errorAllowList = flags.MustDeprecatedRegexpSlice("webhook-error-allow-list", "webhook-allow-list")
|
||||
w.errorDenyList = flags.MustDeprecatedRegexpSlice("webhook-error-deny-list", "webhook-deny-list")
|
||||
w.denyPrivateIPs = flags.MustBool("webhook-deny-private-ips")
|
||||
w.denyPublicIPs = flags.MustBool("webhook-deny-public-ips")
|
||||
w.maxRetry = flags.MustInt("webhook-max-retry")
|
||||
w.retryMinWait = flags.MustDuration("webhook-retry-min-wait")
|
||||
w.retryMaxWait = flags.MustDuration("webhook-retry-max-wait")
|
||||
|
||||
Reference in New Issue
Block a user