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.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/xss-cross-site-scripting/debugging-client-side-js/SKILL.MD
source content

Debugging 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

The

debugger;
statement causes the browser to pause execution when it reaches that line, opening the debugger automatically.

How to Use

  1. Download the JavaScript files locally

    • Use browser DevTools to save the JS files you want to debug
    • Or download them directly from the server
  2. Add

    debugger;
    at strategic points

    • Place
      debugger;
      where you want execution to pause
    • Common locations: input validation functions, output encoding functions, event handlers
  3. 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

  1. Create a local folder for overrides

    mkdir ~/js-overrides
    
  2. 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
      )
  3. 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
  4. Add breakpoints or

    debugger;
    statements

    • Edit the local copy in the browser's editor
    • Add
      debugger;
      statements where you want to pause
    • Or set regular breakpoints by clicking line numbers
    • Save the changes (Ctrl+S or Cmd+S)
  5. Reload the target page

    • Your local JavaScript copy will now load instead of the remote version
    • Your breakpoints and
      debugger;
      statements persist across reloads
    • Change URL parameters freely without losing your breakpoints

Why Overrides Are Better Than Manual Editing

Manual EditingBrowser Overrides
Requires re-downloading after each changeChanges persist automatically
Hard to track which version you're testingClear separation between remote and local
Easy to lose modificationsVersion-controlled in your local folder
No way to quickly revertToggle overrides on/off easily

Common Debugging Scenarios

Scenario 1: Testing XSS Payloads

When testing if your XSS payload executes:

  1. Set a breakpoint or
    debugger;
    in the function that processes user input
  2. Reload with your payload in the URL parameter
  3. Inspect the
    data
    or
    input
    variable to see if it's been sanitized
  4. Step through to see where the payload might bypass filters

Scenario 2: Understanding Input Validation

To see how input is validated:

  1. Add
    debugger;
    at the start of validation functions
  2. Test with various inputs (normal, special characters, encoded values)
  3. Watch how the input transforms through each validation step
  4. Identify where validation might be bypassed

Scenario 3: Tracing Event Handlers

For event-based XSS (click handlers, etc.):

  1. Set breakpoints in event handler functions
  2. Trigger the event (click button, submit form)
  3. Inspect the event object and any data passed to handlers
  4. Check if user-controlled data reaches dangerous sinks

Tips for Effective Debugging

  • Start broad, then narrow: First add
    debugger;
    at the top of the file to confirm it's loading, then move to specific functions
  • Use console.log() for quick checks:
    console.log('input:', data);
    can help you see values without pausing
  • 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:

  1. Document the vulnerable code paths you discovered
  2. Test your findings with actual payloads
  3. Consider how the findings fit into the broader application security picture
  4. If you need to analyze the server-side handling, use server-side debugging techniques