Hacktricks-skills debug-client-side-js
How to debug client-side JavaScript during XSS and web application security testing. Use this skill whenever you need to analyze JavaScript behavior, set persistent breakpoints, or debug JS code that changes with URL parameters. Essential for XSS testing, JavaScript vulnerability analysis, and understanding client-side logic. Make sure to use this skill when investigating client-side vulnerabilities, analyzing JavaScript execution flow, or when breakpoints keep resetting due to URL changes.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/xss-cross-site-scripting/debugging-client-side-js/SKILL.MDDebugging Client-Side JavaScript for Security Testing
Debugging client-side JavaScript during security testing can be frustrating because every time you change the URL (including parameters or parameter values), you need to reset breakpoints and reload the page. This skill covers techniques to maintain persistent breakpoints and effectively debug JavaScript behavior.
Why This Matters
When testing for XSS vulnerabilities or analyzing client-side logic:
- JavaScript often processes input differently based on URL parameters
- Breakpoints reset when the page reloads with new parameters
- You need to observe execution flow across multiple test cases
- Understanding JS behavior helps identify injection points and bypasses
Technique 1: Using debugger;
Statements
debugger;The
debugger; statement causes the browser to pause execution when it reaches that line, opening the debugger automatically.
How to Use
-
Download the JavaScript files locally
- Use browser DevTools to save the JS files you want to debug
- Or download them directly from the server
-
Add
at strategic pointsdebugger;- Place
where you want execution to pausedebugger; - Common locations: input validation functions, output encoding functions, event handlers
- Place
-
Serve the modified files
- Use browser overrides (see below) to load your modified version
- Or host the files locally and reference them
Example
// Original code function processInput(data) { return data.trim(); } // Modified with debugger function processInput(data) { debugger; // Pause here to inspect input return data.trim(); }
Technique 2: Browser Overrides (Recommended)
Browser overrides let you maintain a local copy of JavaScript files that execute instead of the remote version. This is the most reliable way to set persistent breakpoints.
Setup Steps
-
Create a local folder for overrides
mkdir ~/js-overrides -
Configure the browser
- Open DevTools (F12 or right-click → Inspect)
- Go to Sources tab
- Click Overrides in the left sidebar
- Click Allow and select your local folder (e.g.,
)~/js-overrides - Check the box next to the target domain (e.g.,
)https://target-site.com
-
Save the file for overrides
- In the Sources tab, navigate to the JavaScript file you want to debug
- Right-click the file
- Select Save for overrides
- The file is now copied to your local override folder
-
Add breakpoints or
statementsdebugger;- Edit the local copy in the browser's editor
- Add
statements where you want to pausedebugger; - Or set regular breakpoints by clicking line numbers
- Save the changes (Ctrl+S or Cmd+S)
-
Reload the target page
- Your local JavaScript copy will now load instead of the remote version
- Your breakpoints and
statements persist across reloadsdebugger; - Change URL parameters freely without losing your breakpoints
Why Overrides Are Better Than Manual Editing
| Manual Editing | Browser Overrides |
|---|---|
| Requires re-downloading after each change | Changes persist automatically |
| Hard to track which version you're testing | Clear separation between remote and local |
| Easy to lose modifications | Version-controlled in your local folder |
| No way to quickly revert | Toggle overrides on/off easily |
Common Debugging Scenarios
Scenario 1: Testing XSS Payloads
When testing if your XSS payload executes:
- Set a breakpoint or
in the function that processes user inputdebugger; - Reload with your payload in the URL parameter
- Inspect the
ordata
variable to see if it's been sanitizedinput - Step through to see where the payload might bypass filters
Scenario 2: Understanding Input Validation
To see how input is validated:
- Add
at the start of validation functionsdebugger; - Test with various inputs (normal, special characters, encoded values)
- Watch how the input transforms through each validation step
- Identify where validation might be bypassed
Scenario 3: Tracing Event Handlers
For event-based XSS (click handlers, etc.):
- Set breakpoints in event handler functions
- Trigger the event (click button, submit form)
- Inspect the event object and any data passed to handlers
- Check if user-controlled data reaches dangerous sinks
Tips for Effective Debugging
- Start broad, then narrow: First add
at the top of the file to confirm it's loading, then move to specific functionsdebugger; - Use console.log() for quick checks:
can help you see values without pausingconsole.log('input:', data); - Check the Call Stack: When paused, the Call Stack shows how you got to that point - useful for understanding execution flow
- Watch expressions: Add variables to the Watch panel to monitor their values as you step through
- Don't forget encoded values: XSS payloads are often URL-encoded or HTML-encoded - decode them in the console to see the actual value
Troubleshooting
Overrides Not Working
- Verify the domain is checked: In Overrides, make sure the target domain has a checkmark
- Clear cache: Hard reload (Ctrl+Shift+R or Cmd+Shift+R) to clear cached JavaScript
- Check the file path: Ensure the file you're editing matches the path in the Sources panel
- Disable extensions: Some browser extensions can interfere with overrides
Debugger Not Pausing
- Check if DevTools is open: The debugger only pauses if DevTools is open
- Verify the file is being loaded: Check the Network tab to confirm your overridden file is loading
- Look for errors: Check the Console tab for JavaScript errors that might prevent execution
References
Next Steps
After debugging the JavaScript:
- Document the vulnerable code paths you discovered
- Test your findings with actual payloads
- Consider how the findings fit into the broader application security picture
- If you need to analyze the server-side handling, use server-side debugging techniques