Pentesting Next.js Server Actions

A Burp Extension for Hash-to-Function Mapping

Next.js server actions present an interesting challenge during penetration tests. These server-side functions appear in proxy tools as POST requests with hashed identifiers like a9fa42b4c7d1 in the Next-Action header, making it difficult to understand what each request actually does. When applications have productionBrowserSourceMaps enabled, this Burp extension NextjsServerActionAnalyzer bridges that gap by automatically mapping these hashes to their actual function names.

The Problem with Server Action Testing

During a typical web application assessment, endpoints usually have descriptive names and methods: GET /api/user/1 clearly indicates its purpose. Next.js server actions work differently. They all POST to the same endpoint, distinguished only by hash values that change with each build. Without tooling, testers must manually track which hash performs which action—a time-consuming process that becomes impractical with larger applications.

So we and Claude wrote a BurpSuite plugin to help map actions to function names.

How the Extension Works

The extension's effectiveness stems from understanding how Next.js bundles server actions in production. When productionBrowserSourceMaps is enabled, JavaScript chunks contain mappings between action hashes and their original function names.

The tool simply uses flexible regex patterns to extract these mappings from minified JavaScript.

# Strict pattern for standard minification
createServerReference\)\("([a-f0-9]{40,})",\w+\.callServer,void 0,\w+\.findSourceMapURL,"([^"]+)"\)

# Flexible pattern handling various minification styles
createServerReference[^"]*"([a-f0-9]{40,})"[^"]*"([^"]+)"\s*\)

The extension automatically scans proxy history for JavaScript chunks, identifies those containing createServerReference calls, and builds a comprehensive mapping of hash IDs to function names.

Unused Action Detection

Rather than simply tracking which hash IDs have been executed, it tracks function names. This is important since the same function might have different hash IDs across builds, but the function name will remain constant.

For example, if deleteUserAccount() has a hash of a9f8e2b4c7d1 in one build and b7e3f9a2d8c5 in another, manually tracking these would see these as different actions. The extension recognizes they're the same function, providing accurate unused action detection even across multiple application versions.

Automated Testing of Unused Actions

A useful feature of the extension is its ability to transform discovered but unused actions into testable requests. When you identify an unused action like exportFinancialData(), the extension can automatically:

  1. Find a template request with proper Next.js headers
  2. Replace the action ID with the unused action's hash
  3. Create a ready-to-test request in Burp Repeater

This removes the manual work of manually creating server action requests.

Improving Test Coverage

We recently assessed a Next.js application with dozens of server actions. The client had left productionBrowserSourceMaps enabled in their production environment—a common configuration that includes debugging information in JavaScript files. This presented an opportunity to improve our testing methodology.

Using the Burp extension, we:

  1. Captured server action requests during normal application usage
  2. Extracted function names from the source maps in JavaScript bundles
  3. Mapped hashes to functions like updateUserProfile() and fetchReportData()
  4. Discovered unused actions that weren't triggered through the UI

The function name mapping transformed our testing approach. Instead of tracking anonymous hashes, we could see that b7e3f9a2 mapped to deleteUserAccount() and c4d8b1e6 mapped to exportUserData(). This clarity helped us create more targeted test cases.

Implementation

The extension works by:

  • Monitoring proxy history for requests containing Next-Action headers
  • Downloading JavaScript files referenced in the application
  • Parsing source maps when available to extract original function names
  • Creating a searchable mapping between hash IDs and function names
  • Highlighting potentially sensitive functions based on naming patterns

Imagine testing a function that appears as just a hash. Without context, you might hope to come across while enumerating actions and crafting generic test cases. But knowing it maps to transferFunds() immediately suggests specific authorization and input validation tests. This context-aware testing led to more thorough coverage in less time. You can also filter by function name or hash to quickly pull up requests with that action.

The extension also helps tracking which functions changed between builds, ensuring all discovered actions were tested, and using actual function names instead of hashes in findings (as the hashes aren’t super helpful to devs).

Of course, this approach does requires productionBrowserSourceMaps to be enabled and function names alone don't reveal vulnerabilities as a well-written applications should remain secure regardless of function disclosure.

When source maps are available, it transforms opaque hash identifiers into meaningful function names. While not a vulnerability finder itself, it's a valuable addition to the penetration tester's toolkit for Next.js applications. For teams testing Next.js applications, especially those with source maps enabled, this extension can significantly improve testing workflow and coverage.

Check it out! https://github.com/Adversis/NextjsServerActionAnalyzer

Have a project in mind? Let’s talk

Get in touch