Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: added a new parameter -js to javascript injection in headless #2066

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from
22 changes: 21 additions & 1 deletion runner/headless.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ func MustDisableSandbox() bool {
return osutils.IsLinux() && os.Geteuid() == 0
}

func EvalJavaScript(page *rod.Page, jsc []string) ([]*proto.RuntimeRemoteObject, error) {
outputs := make([]*proto.RuntimeRemoteObject, 0, len(jsc))
for _, js := range jsc {
if js == "" {
continue
}
output, err := page.Eval(js)
if err != nil {
return nil, err
}
outputs = append(outputs, output)
}
return outputs, nil
}

type Browser struct {
tempDir string
engine *rod.Browser
Expand Down Expand Up @@ -99,7 +114,7 @@ func NewBrowser(proxy string, useLocal bool, optionalArgs map[string]string) (*B
return engine, nil
}

func (b *Browser) ScreenshotWithBody(url string, timeout time.Duration, idle time.Duration, headers []string) ([]byte, string, error) {
func (b *Browser) ScreenshotWithBody(url string, timeout time.Duration, idle time.Duration, headers []string, jsc []string) ([]byte, string, error) {
page, err := b.engine.Page(proto.TargetCreateTarget{})
if err != nil {
return nil, "", err
Expand All @@ -121,11 +136,16 @@ func (b *Browser) ScreenshotWithBody(url string, timeout time.Duration, idle tim
return nil, "", err
}

if _, err = EvalJavaScript(page, jsc); err != nil {
return nil, "", err
}

page.Timeout(5 * time.Second).WaitNavigation(proto.PageLifecycleEventNameFirstMeaningfulPaint)()

if err := page.WaitLoad(); err != nil {
return nil, "", err
}

_ = page.WaitIdle(idle)

screenshot, err := page.Screenshot(true, &proto.PageCaptureScreenshot{})
Expand Down
3 changes: 3 additions & 0 deletions runner/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ type ScanOptions struct {
NoHeadlessBody bool
ScreenshotTimeout time.Duration
ScreenshotIdle time.Duration
JavascriptInject []string
}

func (s *ScanOptions) Clone() *ScanOptions {
Expand Down Expand Up @@ -322,6 +323,7 @@ type Options struct {
Protocol string
OutputFilterErrorPagePath string
DisableStdout bool
JavascriptInject goflags.StringSlice
// AssetUpload
AssetUpload bool
// AssetName
Expand Down Expand Up @@ -390,6 +392,7 @@ func ParseOptions() *Options {
flagSet.BoolVarP(&options.NoHeadlessBody, "exclude-headless-body", "ehb", false, "enable excluding headless header from json output"),
flagSet.DurationVarP(&options.ScreenshotTimeout, "screenshot-timeout", "st", 10*time.Second, "set timeout for screenshot in seconds"),
flagSet.DurationVarP(&options.ScreenshotIdle, "screenshot-idle", "sid", 1*time.Second, "set idle time before taking screenshot in seconds"),
flagSet.StringSliceVarP(&options.JavascriptInject, "javascript-code", "jsc", nil, "execute JavaScript code after navigation", goflags.StringSliceOptions),
)

flagSet.CreateGroup("matchers", "Matchers",
Expand Down
2 changes: 1 addition & 1 deletion runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2186,7 +2186,7 @@ retry:
var pHash uint64
if scanopts.Screenshot {
var err error
screenshotBytes, headlessBody, err = r.browser.ScreenshotWithBody(fullURL, scanopts.ScreenshotTimeout, scanopts.ScreenshotIdle, r.options.CustomHeaders)
screenshotBytes, headlessBody, err = r.browser.ScreenshotWithBody(fullURL, scanopts.ScreenshotTimeout, scanopts.ScreenshotIdle, r.options.CustomHeaders, r.options.JavascriptInject)
if err != nil {
gologger.Warning().Msgf("Could not take screenshot '%s': %s", fullURL, err)
} else {
Expand Down
Loading