Skip to content

Commit 0db64ea

Browse files
authored
Merge pull request #308 from edoardottt/devel
Devel
2 parents b3047b5 + 3c876c4 commit 0db64ea

1 file changed

Lines changed: 8 additions & 25 deletions

File tree

pkg/scan/chrome.go

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// pphack - The Most Advanced Client-Side Prototype Pollution Scanner
2-
// This repository is under MIT License https://github.com/edoardottt/pphack/blob/main/LICENSE
1+
/*
2+
pphack - The Most Advanced Client-Side Prototype Pollution Scanner
33
4+
This repository is under MIT License https://github.com/edoardottt/pphack/blob/main/LICENSE
5+
*/
46
package scan
57

68
import (
@@ -34,7 +36,7 @@ func GetChromeOptions(r *Runner) []func(*chromedp.ExecAllocator) {
3436
}
3537

3638
// GetChromeBrowser takes as input the chrome options and returns
37-
// the contexts with the associated cancel functions to use the
39+
// the context with the associated cancel functions to use the
3840
// headless chrome browser it creates.
3941
// Returns ecancel (exec allocator cancel), pctx (parent browser context),
4042
// and pcancel (parent context cancel).
@@ -46,7 +48,6 @@ func GetChromeBrowser(copts []func(*chromedp.ExecAllocator)) (context.CancelFunc
4648
pctx, pcancel := chromedp.NewContext(ectx)
4749

4850
// Run an empty chromedp task to verify the browser starts successfully.
49-
// If it fails, ecancel is called before Fatal to avoid leaking the allocator.
5051
if err := chromedp.Run(pctx); err != nil {
5152
ecancel()
5253
gologger.Fatal().Msgf("error starting browser: %s", err.Error())
@@ -69,7 +70,7 @@ func buildHeaders(headers map[string]interface{}) chromedp.Tasks {
6970

7071
// Scan is the core function that performs the prototype pollution scan.
7172
// It takes a parent browser context (pctx), runner config (r), optional HTTP
72-
// headers, the JavaScript payload (js), the original input value, and the
73+
// headers, the JavaScript payload (js), the original input value and the
7374
// fully constructed target URL.
7475
//
7576
// Flow:
@@ -90,21 +91,18 @@ func Scan(
9091
resDetection []string
9192
)
9293

93-
// Initialize result with the original input value and the constructed scan URL.
9494
resultData := output.ResultData{
9595
TargetURL: value,
9696
ScanURL: targetURL,
9797
}
9898

99-
// Wrap the parent context with a per-scan timeout so hung pages
100-
// don't block the scanner indefinitely.
99+
// Wrap the parent context with a per-scan timeout to avoid blocking.
101100
ctx, ctxCancel := context.WithTimeout(pctx, time.Second*time.Duration(r.Options.Timeout))
102101
defer ctxCancel()
103102

104103
// Open a new Chrome tab scoped to the timeout context.
105-
// tabCancel explicitly closes the tab when Scan returns,
104+
// tabCancel explicitly closes the tab when Scan returns
106105
// preventing tab accumulation across concurrent scans.
107-
// Previously this cancel was silently dropped with _, causing a tab leak.
108106
tabCtx, tabCancel := chromedp.NewContext(ctx)
109107
defer tabCancel()
110108

@@ -123,14 +121,8 @@ func Scan(
123121
resultData.ScanError = errScan.Error()
124122
}
125123

126-
// Trim and store the JS evaluation result.
127-
// This value is reused in the exploit gate below to avoid a redundant TrimSpace call.
128124
resultData.JSEvaluation = strings.TrimSpace(resScan)
129125

130-
// Early return guard: skip exploit phase entirely if:
131-
// - exploit mode is off, OR
132-
// - the scan itself errored (page unreachable, timeout, etc.), OR
133-
// - the JS payload returned empty (no pollution detected).
134126
if !r.Options.Exploit || errScan != nil || resultData.JSEvaluation == "" {
135127
return resultData, nil
136128
}
@@ -140,16 +132,12 @@ func Scan(
140132
}
141133

142134
// Run fingerprinting as a separate, isolated task list.
143-
// Previously the fingerprint eval was appended onto scanTasks, which caused
144-
// the full task list (Navigate + JS eval + fingerprint) to re-run from scratch,
145-
// re-navigating the page unnecessarily and potentially corrupting scan state.
146135
fingerprintTasks := chromedp.Tasks{
147136
chromedp.EvaluateAsDevTools(exploit.Fingerprint, &resDetection),
148137
}
149138

150139
errDetection := chromedp.Run(tabCtx, fingerprintTasks)
151140
if errDetection != nil {
152-
// Log detection errors unconditionally - errors are not verbosity-dependent.
153141
gologger.Error().Msg(errDetection.Error())
154142
resultData.FingerprintError = errDetection.Error()
155143
}
@@ -162,9 +150,6 @@ func Scan(
162150
gologger.Info().Msg(fmt.Sprintf("Trying to exploit %s", value))
163151
}
164152

165-
// Build exploit-phase headers separately using buildHeaders.
166-
// Previously this was a duplicated inline block; now it uses the shared helper
167-
// for consistency with the scan phase header handling.
168153
exploitTasks := buildHeaders(headers)
169154

170155
result, errExploit := exploit.CheckExploit(
@@ -179,8 +164,6 @@ func Scan(
179164
resultData.ExploitURLs = result
180165

181166
if errExploit != nil {
182-
// Previously this field was incorrectly set to errDetection.Error(),
183-
// masking the actual exploit error. Now correctly uses errExploit.
184167
resultData.ExploitError = errExploit.Error()
185168
gologger.Error().Msg(errExploit.Error())
186169
}

0 commit comments

Comments
 (0)