Skip to content

Commit 748fe9c

Browse files
authored
Merge pull request #1521 from HackTricks-wiki/update_Pentesting_Next_js_Server_Actions___A_Burp_Extensi_20251026_012456
Pentesting Next.js Server Actions — A Burp Extension for Has...
2 parents 6806307 + 63ad2eb commit 748fe9c

File tree

1 file changed

+69
-2
lines changed
  • src/network-services-pentesting/pentesting-web

1 file changed

+69
-2
lines changed

src/network-services-pentesting/pentesting-web/nextjs.md

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ my-nextjs-app/
4949
- **app/:** Central directory for your application’s pages, layouts, components, and API routes. Embraces the **App Router** paradigm, enabling advanced routing features and server-client component segregation.
5050
- **app/layout.tsx:** Defines the root layout for your application, wrapping around all pages and providing consistent UI elements like headers, footers, and navigation bars.
5151
- **app/page.tsx:** Serves as the entry point for the root route `/`, rendering the home page.
52-
- **app/\[route]/page.tsx:** Handles static and dynamic routes. Each folder within `app/` represents a route segment, and `page.tsx` within those folders corresponds to the route's component.
52+
- **app/[route]/page.tsx:** Handles static and dynamic routes. Each folder within `app/` represents a route segment, and `page.tsx` within those folders corresponds to the route's component.
5353
- **app/api/:** Contains API routes, allowing you to create serverless functions that handle HTTP requests. These routes replace the traditional `pages/api` directory.
5454
- **app/components/:** Houses reusable React components that can be utilized across different pages and layouts.
5555
- **app/styles/:** Contains global CSS files and CSS Modules for component-scoped styling.
@@ -1268,6 +1268,73 @@ const HeavyComponent = dynamic(() => import("../components/HeavyComponent"), {
12681268
})
12691269
```
12701270

1271-
{{#include ../../banners/hacktricks-training.md}}
1271+
## Next.js Server Actions Enumeration (hash to function name via source maps)
1272+
1273+
Modern Next.js uses “Server Actions” that execute on the server but are invoked from the client. In production these invocations are opaque: all POSTs land on a common endpoint and are distinguished by a build-specific hash sent in the `Next-Action` header. Example:
1274+
1275+
```http
1276+
POST /
1277+
Next-Action: a9f8e2b4c7d1...
1278+
```
1279+
1280+
When `productionBrowserSourceMaps` is enabled, minified JS chunks contain calls to `createServerReference(...)` that leak enough structure (plus associated source maps) to recover a mapping between the action hash and the original function name. This lets you translate hashes observed in `Next-Action` into concrete targets like `deleteUserAccount()` or `exportFinancialData()`.
1281+
1282+
### Extraction approach (regex on minified JS + optional source maps)
1283+
1284+
Search downloaded JS chunks for `createServerReference` and extract the hash and the function/source symbol. Two useful patterns:
1285+
1286+
```regex
1287+
# Strict pattern for standard minification
1288+
createServerReference\)\"([a-f0-9]{40,})\",\w+\.callServer,void 0,\w+\.findSourceMapURL,\"([^\"]+)\"\)
1289+
1290+
# Flexible pattern handling various minification styles
1291+
createServerReference[^\"]*\"([a-f0-9]{40,})\"[^\"]*\"([^\"]+)\"\s*\)
1292+
```
1293+
1294+
- Group 1: server action hash (40+ hex chars)
1295+
- Group 2: symbol or path that can be resolved to the original function via the source map when present
1296+
1297+
If the script advertises a source map (trailer comment `//# sourceMappingURL=<...>.map`), fetch it and resolve the symbol/path to the original function name.
1298+
1299+
### Practical workflow
1300+
1301+
- Passive discovery while browsing: capture requests with `Next-Action` headers and JS chunk URLs.
1302+
- Fetch the referenced JS bundles and accompanying `*.map` files (when present).
1303+
- Run the regex above to build a hash↔name dictionary.
1304+
- Use the dictionary to target testing:
1305+
- Name-driven triage (e.g., `transferFunds`, `exportFinancialData`).
1306+
- Track coverage across builds by function name (hashes rotate across builds).
1307+
1308+
### Exercising hidden actions (template-based request)
1309+
1310+
Take a valid POST observed in-proxy as a template and swap the `Next-Action` value to target another discovered action:
1311+
1312+
```http
1313+
# Before
1314+
Next-Action: a9f8e2b4c7d1
1315+
1316+
# After
1317+
Next-Action: b7e3f9a2d8c5
1318+
```
1319+
1320+
Replay in Repeater and test authorization, input validation and business logic of otherwise unreachable actions.
1321+
1322+
### Burp automation
1323+
1324+
- NextjsServerActionAnalyzer (Burp extension) automates the above in Burp:
1325+
- Mines proxy history for JS chunks, extracts `createServerReference(...)` entries, and parses source maps when available.
1326+
- Maintains a searchable hash↔function-name dictionary and de-duplicates across builds by function name.
1327+
- Can locate a valid template POST and open a ready-to-send Repeater tab with the target action’s hash swapped in.
1328+
- Repo: https://github.com/Adversis/NextjsServerActionAnalyzer
1329+
1330+
### Notes and limitations
1331+
1332+
- Requires `productionBrowserSourceMaps` enabled in production to recover names from bundles/source maps.
1333+
- Function-name disclosure is not a vulnerability by itself; use it to guide discovery and test each action’s authorization.
1334+
1335+
## References
12721336

1337+
- [Pentesting Next.js Server Actions — A Burp Extension for Hash-to-Function Mapping](https://www.adversis.io/blogs/pentesting-next-js-server-actions)
1338+
- [NextjsServerActionAnalyzer (Burp extension)](https://github.com/Adversis/NextjsServerActionAnalyzer)
12731339

1340+
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)