mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-16 12:22:17 +01:00
fix(chromium): better default deny list regexp
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -15,6 +14,7 @@ import (
|
||||
"github.com/chromedp/cdproto/network"
|
||||
"github.com/chromedp/cdproto/runtime"
|
||||
"github.com/chromedp/chromedp"
|
||||
"github.com/dlclark/regexp2"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/gotenberg/gotenberg/v8/pkg/gotenberg"
|
||||
@@ -39,8 +39,8 @@ type browserArguments struct {
|
||||
wsUrlReadTimeout time.Duration
|
||||
|
||||
// Tasks specific.
|
||||
allowList *regexp.Regexp
|
||||
denyList *regexp.Regexp
|
||||
allowList *regexp2.Regexp
|
||||
denyList *regexp2.Regexp
|
||||
clearCache bool
|
||||
clearCookies bool
|
||||
disableJavaScript bool
|
||||
@@ -263,20 +263,17 @@ func (b *chromiumBrowser) do(ctx context.Context, logger *zap.Logger, url string
|
||||
return errors.New("browser not started, cannot handle tasks")
|
||||
}
|
||||
|
||||
// We validate the "main" URL against our allow / deny lists.
|
||||
if !b.arguments.allowList.MatchString(url) {
|
||||
return fmt.Errorf("'%s' does not match the expression from the allowed list: %w", url, ErrUrlNotAuthorized)
|
||||
}
|
||||
|
||||
if b.arguments.denyList.String() != "" && b.arguments.denyList.MatchString(url) {
|
||||
return fmt.Errorf("'%s' matches the expression from the denied list: %w", url, ErrUrlNotAuthorized)
|
||||
}
|
||||
|
||||
deadline, ok := ctx.Deadline()
|
||||
if !ok {
|
||||
return errors.New("context has no deadline")
|
||||
}
|
||||
|
||||
// We validate the "main" URL against our allow / deny lists.
|
||||
err := gotenberg.FilterDeadline(b.arguments.allowList, b.arguments.denyList, url, deadline)
|
||||
if err != nil {
|
||||
return fmt.Errorf("filter URL: %w", err)
|
||||
}
|
||||
|
||||
b.ctxMu.RLock()
|
||||
defer b.ctxMu.RUnlock()
|
||||
|
||||
@@ -310,7 +307,7 @@ func (b *chromiumBrowser) do(ctx context.Context, logger *zap.Logger, url string
|
||||
listenForEventExceptionThrown(taskCtx, logger, &consoleExceptions, &consoleExceptionsMu)
|
||||
}
|
||||
|
||||
err := chromedp.Run(taskCtx, tasks...)
|
||||
err = chromedp.Run(taskCtx, tasks...)
|
||||
if err != nil {
|
||||
errMessage := err.Error()
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/dlclark/regexp2"
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
@@ -268,46 +268,9 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "ErrUrlNotAuthorized: main URL does not match the allowed list",
|
||||
scenario: "context has no deadline",
|
||||
browser: func() browser {
|
||||
b := new(chromiumBrowser)
|
||||
b.arguments = browserArguments{
|
||||
allowList: regexp.MustCompile("^file:///[^tmp].*"),
|
||||
}
|
||||
b.isStarted.Store(true)
|
||||
return b
|
||||
}(),
|
||||
fs: gotenberg.NewFileSystem(),
|
||||
noDeadline: false,
|
||||
start: false,
|
||||
expectError: true,
|
||||
expectedError: ErrUrlNotAuthorized,
|
||||
},
|
||||
{
|
||||
scenario: "ErrUrlNotAuthorized: main URL does match the denied list",
|
||||
browser: func() browser {
|
||||
b := new(chromiumBrowser)
|
||||
b.arguments = browserArguments{
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile("^file:///tmp.*"),
|
||||
}
|
||||
b.isStarted.Store(true)
|
||||
return b
|
||||
}(),
|
||||
fs: gotenberg.NewFileSystem(),
|
||||
noDeadline: false,
|
||||
start: false,
|
||||
expectError: true,
|
||||
expectedError: ErrUrlNotAuthorized,
|
||||
},
|
||||
{
|
||||
scenario: "ErrUrlNotAuthorized: main URL does match the denied list",
|
||||
browser: func() browser {
|
||||
b := new(chromiumBrowser)
|
||||
b.arguments = browserArguments{
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
}
|
||||
b.isStarted.Store(true)
|
||||
return b
|
||||
}(),
|
||||
@@ -316,14 +279,48 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
start: false,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "ErrFiltered: main URL does not match the allowed list",
|
||||
browser: func() browser {
|
||||
b := new(chromiumBrowser)
|
||||
b.arguments = browserArguments{
|
||||
allowList: regexp2.MustCompile(`^file:(?!//\/tmp/).*`, 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
}
|
||||
b.isStarted.Store(true)
|
||||
return b
|
||||
}(),
|
||||
fs: gotenberg.NewFileSystem(),
|
||||
noDeadline: false,
|
||||
start: false,
|
||||
expectError: true,
|
||||
expectedError: gotenberg.ErrFiltered,
|
||||
},
|
||||
{
|
||||
scenario: "ErrFiltered: main URL does match the denied list",
|
||||
browser: func() browser {
|
||||
b := new(chromiumBrowser)
|
||||
b.arguments = browserArguments{
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("^file:///tmp.*", 0),
|
||||
}
|
||||
b.isStarted.Store(true)
|
||||
return b
|
||||
}(),
|
||||
fs: gotenberg.NewFileSystem(),
|
||||
noDeadline: false,
|
||||
start: false,
|
||||
expectError: true,
|
||||
expectedError: gotenberg.ErrFiltered,
|
||||
},
|
||||
{
|
||||
scenario: "a request does not match the allowed list",
|
||||
browser: newChromiumBrowser(
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile("^file:///tmp.*"),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("^file:///tmp.*", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -354,8 +351,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile("^file:///[^tmp].*"),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile(`^file:(?!//\/tmp/).*`, 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -386,8 +383,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -421,8 +418,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -454,8 +451,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -487,8 +484,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
clearCache: true,
|
||||
},
|
||||
),
|
||||
@@ -520,8 +517,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
clearCookies: true,
|
||||
},
|
||||
),
|
||||
@@ -553,8 +550,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
disableJavaScript: true,
|
||||
},
|
||||
),
|
||||
@@ -588,8 +585,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -625,8 +622,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -658,8 +655,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -694,8 +691,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -727,8 +724,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -762,8 +759,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -797,8 +794,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -832,8 +829,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -878,8 +875,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -913,8 +910,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -959,8 +956,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -995,8 +992,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1033,8 +1030,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1066,8 +1063,8 @@ func TestChromiumBrowser_pdf(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1202,45 +1199,12 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "ErrUrlNotAuthorized: main URL does not match the allowed list",
|
||||
scenario: "context has not deadline",
|
||||
browser: func() browser {
|
||||
b := new(chromiumBrowser)
|
||||
b.arguments = browserArguments{
|
||||
allowList: regexp.MustCompile("^file:///[^tmp].*"),
|
||||
}
|
||||
b.isStarted.Store(true)
|
||||
return b
|
||||
}(),
|
||||
fs: gotenberg.NewFileSystem(),
|
||||
noDeadline: false,
|
||||
start: false,
|
||||
expectError: true,
|
||||
expectedError: ErrUrlNotAuthorized,
|
||||
},
|
||||
{
|
||||
scenario: "ErrUrlNotAuthorized: main URL does match the denied list",
|
||||
browser: func() browser {
|
||||
b := new(chromiumBrowser)
|
||||
b.arguments = browserArguments{
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile("^file:///tmp.*"),
|
||||
}
|
||||
b.isStarted.Store(true)
|
||||
return b
|
||||
}(),
|
||||
fs: gotenberg.NewFileSystem(),
|
||||
noDeadline: false,
|
||||
start: false,
|
||||
expectError: true,
|
||||
expectedError: ErrUrlNotAuthorized,
|
||||
},
|
||||
{
|
||||
scenario: "ErrUrlNotAuthorized: main URL does match the denied list",
|
||||
browser: func() browser {
|
||||
b := new(chromiumBrowser)
|
||||
b.arguments = browserArguments{
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
}
|
||||
b.isStarted.Store(true)
|
||||
return b
|
||||
@@ -1250,14 +1214,48 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
start: false,
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
scenario: "ErrFiltered: main URL does not match the allowed list",
|
||||
browser: func() browser {
|
||||
b := new(chromiumBrowser)
|
||||
b.arguments = browserArguments{
|
||||
allowList: regexp2.MustCompile(`^file:(?!//\/tmp/).*`, 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
}
|
||||
b.isStarted.Store(true)
|
||||
return b
|
||||
}(),
|
||||
fs: gotenberg.NewFileSystem(),
|
||||
noDeadline: false,
|
||||
start: false,
|
||||
expectError: true,
|
||||
expectedError: gotenberg.ErrFiltered,
|
||||
},
|
||||
{
|
||||
scenario: "ErrFiltered: main URL does match the denied list",
|
||||
browser: func() browser {
|
||||
b := new(chromiumBrowser)
|
||||
b.arguments = browserArguments{
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("^file:///tmp.*", 0),
|
||||
}
|
||||
b.isStarted.Store(true)
|
||||
return b
|
||||
}(),
|
||||
fs: gotenberg.NewFileSystem(),
|
||||
noDeadline: false,
|
||||
start: false,
|
||||
expectError: true,
|
||||
expectedError: gotenberg.ErrFiltered,
|
||||
},
|
||||
{
|
||||
scenario: "a request does not match the allowed list",
|
||||
browser: newChromiumBrowser(
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile("^file:///tmp.*"),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("^file:///tmp.*", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1288,8 +1286,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile("^file:///[^tmp].*"),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile(`^file:(?!//\/tmp/).*`, 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1320,8 +1318,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1355,8 +1353,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1388,8 +1386,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1421,8 +1419,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
clearCache: true,
|
||||
},
|
||||
),
|
||||
@@ -1454,8 +1452,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
clearCookies: true,
|
||||
},
|
||||
),
|
||||
@@ -1487,8 +1485,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
disableJavaScript: true,
|
||||
},
|
||||
),
|
||||
@@ -1522,8 +1520,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1559,8 +1557,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1594,8 +1592,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1627,8 +1625,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1662,8 +1660,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1697,8 +1695,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1732,8 +1730,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1778,8 +1776,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1813,8 +1811,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1859,8 +1857,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
@@ -1900,8 +1898,8 @@ func TestChromiumBrowser_screenshot(t *testing.T) {
|
||||
browserArguments{
|
||||
binPath: os.Getenv("CHROMIUM_BIN_PATH"),
|
||||
wsUrlReadTimeout: 5 * time.Second,
|
||||
allowList: regexp.MustCompile(""),
|
||||
denyList: regexp.MustCompile(""),
|
||||
allowList: regexp2.MustCompile("", 0),
|
||||
denyList: regexp2.MustCompile("", 0),
|
||||
},
|
||||
),
|
||||
fs: func() *gotenberg.FileSystem {
|
||||
|
||||
@@ -20,10 +20,6 @@ func init() {
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrUrlNotAuthorized happens if a URL is not acceptable according to the
|
||||
// allowed/denied lists.
|
||||
ErrUrlNotAuthorized = errors.New("URL not authorized")
|
||||
|
||||
// ErrInvalidEmulatedMediaType happens if the emulated media type is not
|
||||
// "screen" nor "print". Empty value are allowed though.
|
||||
ErrInvalidEmulatedMediaType = errors.New("invalid emulated media type")
|
||||
@@ -291,7 +287,7 @@ func (mod *Chromium) Descriptor() gotenberg.ModuleDescriptor {
|
||||
fs.String("chromium-host-resolver-rules", "", "Set custom mappings to the host resolver")
|
||||
fs.String("chromium-proxy-server", "", "Set the outbound proxy server; this switch only affects HTTP and HTTPS requests")
|
||||
fs.String("chromium-allow-list", "", "Set the allowed URLs for Chromium using a regular expression")
|
||||
fs.String("chromium-deny-list", "^file:///[^tmp].*", "Set the denied URLs for Chromium using a regular expression")
|
||||
fs.String("chromium-deny-list", `^file:(?!//\/tmp/).*`, "Set the denied URLs for Chromium using a regular expression")
|
||||
fs.Bool("chromium-clear-cache", false, "Clear Chromium cache between each conversion")
|
||||
fs.Bool("chromium-clear-cookies", false, "Clear Chromium cookies between each conversion")
|
||||
fs.Bool("chromium-disable-javascript", false, "Disable JavaScript")
|
||||
|
||||
@@ -3,7 +3,6 @@ package chromium
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
@@ -13,14 +12,17 @@ import (
|
||||
"github.com/chromedp/cdproto/page"
|
||||
"github.com/chromedp/cdproto/runtime"
|
||||
"github.com/chromedp/chromedp"
|
||||
"github.com/dlclark/regexp2"
|
||||
"go.uber.org/multierr"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/gotenberg/gotenberg/v8/pkg/gotenberg"
|
||||
)
|
||||
|
||||
// listenForEventRequestPaused listens for requests to check if they are
|
||||
// allowed or not.
|
||||
func listenForEventRequestPaused(ctx context.Context, logger *zap.Logger, allowList *regexp.Regexp, denyList *regexp.Regexp) {
|
||||
func listenForEventRequestPaused(ctx context.Context, logger *zap.Logger, allowList *regexp2.Regexp, denyList *regexp2.Regexp) {
|
||||
chromedp.ListenTarget(ctx, func(ev interface{}) {
|
||||
switch e := ev.(type) {
|
||||
case *fetch.EventRequestPaused:
|
||||
@@ -28,13 +30,15 @@ func listenForEventRequestPaused(ctx context.Context, logger *zap.Logger, allowL
|
||||
logger.Debug(fmt.Sprintf("event EventRequestPaused fired for '%s'", e.Request.URL))
|
||||
allow := true
|
||||
|
||||
if !allowList.MatchString(e.Request.URL) {
|
||||
logger.Warn(fmt.Sprintf("'%s' does not match the expression from the allowed list", e.Request.URL))
|
||||
allow = false
|
||||
deadline, ok := ctx.Deadline()
|
||||
if !ok {
|
||||
logger.Error("context has no deadline, cannot filter URL")
|
||||
return
|
||||
}
|
||||
|
||||
if denyList.String() != "" && denyList.MatchString(e.Request.URL) {
|
||||
logger.Warn(fmt.Sprintf("'%s' matches the expression from the denied list", e.Request.URL))
|
||||
err := gotenberg.FilterDeadline(allowList, denyList, e.Request.URL, deadline)
|
||||
if err != nil {
|
||||
logger.Warn(err.Error())
|
||||
allow = false
|
||||
}
|
||||
|
||||
@@ -43,16 +47,15 @@ func listenForEventRequestPaused(ctx context.Context, logger *zap.Logger, allowL
|
||||
|
||||
if allow {
|
||||
req := fetch.ContinueRequest(e.RequestID)
|
||||
err := req.Do(executorCtx)
|
||||
err = req.Do(executorCtx)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("continue request: %s", err))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
req := fetch.FailRequest(e.RequestID, network.ErrorReasonAccessDenied)
|
||||
err := req.Do(executorCtx)
|
||||
err = req.Do(executorCtx)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("fail request: %s", err))
|
||||
}
|
||||
|
||||
@@ -621,7 +621,7 @@ func handleChromiumError(err error, url string, options Options) error {
|
||||
)
|
||||
}
|
||||
|
||||
if errors.Is(err, ErrUrlNotAuthorized) {
|
||||
if errors.Is(err, gotenberg.ErrFiltered) {
|
||||
return api.WrapError(
|
||||
err,
|
||||
api.NewSentinelHttpError(
|
||||
|
||||
@@ -1243,10 +1243,10 @@ func TestConvertUrl(t *testing.T) {
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "ErrUrlNotAuthorized",
|
||||
scenario: "ErrFiltered",
|
||||
ctx: &api.ContextMock{Context: new(api.Context)},
|
||||
api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error {
|
||||
return ErrUrlNotAuthorized
|
||||
return gotenberg.ErrFiltered
|
||||
}},
|
||||
options: DefaultPdfOptions(),
|
||||
expectError: true,
|
||||
@@ -1503,10 +1503,10 @@ func TestScreenshotUrl(t *testing.T) {
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "ErrUrlNotAuthorized",
|
||||
scenario: "ErrFiltered",
|
||||
ctx: &api.ContextMock{Context: new(api.Context)},
|
||||
api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error {
|
||||
return ErrUrlNotAuthorized
|
||||
return gotenberg.ErrFiltered
|
||||
}},
|
||||
options: DefaultScreenshotOptions(),
|
||||
expectError: true,
|
||||
|
||||
Reference in New Issue
Block a user