Skip to content

Commit 786498d

Browse files
author
Евгений Балякин
committed
Initial Flight DevTools implementation
0 parents  commit 786498d

73 files changed

Lines changed: 8657 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [main]
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: actions/setup-node@v4
14+
with:
15+
node-version: 22
16+
cache: npm
17+
- run: npm ci
18+
- run: npm run typecheck
19+
- run: npm test
20+
- run: npm run build

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
node_modules/
2+
dist/
3+
.idea/
4+
.turbo/
5+
.vite/
6+
coverage/
7+
*.log
8+
.DS_Store
9+
*.tsbuildinfo

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Evgeny Balyakin
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Flight Security DevTools
2+
3+
**The local-first security boundary inspector for React Server Components and Flight payloads.**
4+
5+
Flight Security DevTools turns unreadable React Flight streams into an explainable map of what crossed the server/client boundary: data, module references, Server Actions, pending refs, parser anomalies, secrets, PII, and RCE-class patterns.
6+
7+
![Flight Security DevTools screenshot](docs/assets/app-screenshot.svg)
8+
9+
## Why It Exists
10+
11+
React Server Components changed the real security boundary of modern React apps. The component tree looks clean, but the Flight payload is where sensitive data, callable server references, module references, errors, and control-flow objects actually cross into the browser.
12+
13+
Flight Security DevTools is built to answer three questions quickly:
14+
15+
- **What crossed the boundary?**
16+
- **What is risky?**
17+
- **What should be fixed next?**
18+
19+
## Highlights
20+
21+
- **Chrome DevTools panel**: opens as a dedicated `Flight` tab next to Elements, Console, and Network.
22+
- **Zero proxy MVP capture**: uses `chrome.devtools.network` to detect completed RSC responses without `debugger` permission.
23+
- **Parser Worker**: parses Flight payloads off the UI thread.
24+
- **Boundary Risk Summary**: deterministic 0-100 risk score with Low, Medium, High, and Critical levels.
25+
- **Security rules**: detects prototype traversal, suspicious thenables, constructor access, dangerous modules, secrets, PII, source/stack exposure, and oversized chunks.
26+
- **Tree and Raw evidence**: jump from a finding to the parsed chunk or raw Flight row.
27+
- **Boundary Map**: separates data, callable, module, and control-flow exposure.
28+
- **Streaming-first parser API**: supports complete responses and incremental stream parsing.
29+
- **Local-first privacy**: analysis runs locally; long-term storage/export primitives are designed for sanitized traces.
30+
31+
## Architecture
32+
33+
```text
34+
Chrome DevTools Network capture
35+
|
36+
v
37+
Parser Worker -> @flight-devtools/parser -> Boundary Analyzer -> Security Rules
38+
|
39+
v
40+
DevTools Panel: Boundary / Tree / Raw / Timeline / Map / Actions / Security / Diff
41+
```
42+
43+
The parser package is independent from the extension and can be used in Node.js, browsers, workers, and future CI tooling.
44+
45+
## Repository Layout
46+
47+
```text
48+
packages/
49+
parser/ # @flight-devtools/parser, standalone TypeScript parser
50+
extension/ # Chrome MV3 DevTools extension
51+
docs/ # product and API docs
52+
examples/ # parser usage examples
53+
```
54+
55+
## Quick Start
56+
57+
```bash
58+
npm install
59+
npm test
60+
npm run build
61+
```
62+
63+
Load the extension build from:
64+
65+
```text
66+
packages/extension/dist
67+
```
68+
69+
Open `chrome://extensions`, enable Developer Mode, choose **Load unpacked**, and select that folder. Then open Chrome DevTools on a Next.js App Router page and switch to the **Flight** panel.
70+
71+
For extension UI development:
72+
73+
```bash
74+
npm run dev:extension
75+
```
76+
77+
## Parser API
78+
79+
```ts
80+
import {
81+
createFlightSession,
82+
createFlightStreamParser,
83+
parseFlightRequest,
84+
parseFlightResponse
85+
} from '@flight-devtools/parser';
86+
87+
const tree = parseFlightResponse(
88+
'0:{"user":"$1","action":"$F2"}\n1:{"email":"ada@example.com"}\n'
89+
);
90+
91+
console.log(tree.boundaryFindings);
92+
console.log(tree.securityAlerts);
93+
94+
const session = createFlightSession([
95+
{
96+
request: {
97+
id: 'r1',
98+
url: 'https://app.test/dashboard?_rsc=1',
99+
method: 'GET',
100+
startedAt: Date.now()
101+
},
102+
responseBody: '0:{"user":"$1"}\n1:{"token":"Bearer abcdefghijklmnopqrstuvwxyz"}\n'
103+
}
104+
]);
105+
106+
console.log(session.summary);
107+
108+
const stream = createFlightStreamParser();
109+
stream.onFinding((finding) => console.log(finding.title));
110+
stream.write('0:{"later":"$L1"}\n');
111+
stream.write('1:{"name":"Ada"}\n');
112+
stream.end();
113+
```
114+
115+
## MVP Security Rules
116+
117+
| Rule | Detects | Default risk |
118+
| --- | --- | --- |
119+
| `S001` | Prototype chain traversal via property selection | Critical |
120+
| `S002` | Suspicious thenable object | Critical |
121+
| `S003` | Function constructor access | Critical |
122+
| `S004` | Dangerous Node/system module references | Warning |
123+
| `S005` | Deep reference chains | Info |
124+
| `S006` | Oversized chunks and overfetching | Info |
125+
| `S007` | Secret exposure: JWT, bearer token, API key, private key, database URL | Critical |
126+
| `S008` | PII exposure: common PII and high-sensitivity PII use separate impact variants | Warning |
127+
| `S009` | Broad or suspicious Server Action boundary, escalated for RCE/high-sensitivity context | Warning/Critical |
128+
| `S010` | Source, stack, or internal diagnostic exposure | Warning |
129+
130+
## Current Status
131+
132+
This is an alpha implementation of the vertical MVP from `FLIGHT_DEVTOOLS_SPEC.md`. The parser is best-effort and uses lenient recovery by default: malformed rows become parser errors and protocol-anomaly findings instead of crashing the UI.
133+
134+
Completed in this alpha:
135+
136+
- TypeScript strict parser core
137+
- Complete response parser and streaming parser
138+
- Server Action request body parser
139+
- Session grouping primitives
140+
- Boundary risk scoring
141+
- Redaction and sensitive data detection
142+
- Chrome DevTools panel scaffold
143+
- Parser Worker integration
144+
- Tree, Raw, Timeline, Boundary Map, Actions, Security, and What Changed views
145+
- Tests for lexer, decoder, resolver, stream parser, sessionizer, and security rules
146+
147+
Planned next:
148+
149+
- Larger React 18/19 and Next.js 14/15 fixture corpus
150+
- More precise Flight version strategies
151+
- Virtualized tree rendering for very large payloads
152+
- CI/CLI workflows for boundary review
153+
- Sanitized HTML report export
154+
- Playwright-driven extension screenshot tests
155+
156+
## Development Commands
157+
158+
```bash
159+
npm run typecheck
160+
npm test
161+
npm run build
162+
node examples/node-script/index.mjs
163+
```
164+
165+
## Author
166+
167+
Evgeny Balyakin<br>
168+
GitHub: [github.com/balyakin](https://github.com/balyakin)
169+
170+
## License
171+
172+
MIT (c) Evgeny Balyakin

docs/api/parser.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Parser API
2+
3+
```ts
4+
parseFlightResponse(body, options?)
5+
parseFlightRequest(body, options?)
6+
createFlightSession(inputs, options?)
7+
createFlightStreamParser(options?)
8+
detectFlightVersion(body, options?)
9+
createBoundaryMap(tree)
10+
```
11+
12+
Default parsing mode is `lenient`; invalid chunks produce recoverable parser errors and protocol-anomaly findings instead of crashing the caller.

docs/assets/app-screenshot.svg

Lines changed: 134 additions & 0 deletions
Loading

docs/guide/flight-protocol.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Flight Protocol Notes
2+
3+
Flight responses are parsed as newline-delimited rows:
4+
5+
```text
6+
<id>:<tag?><payload>
7+
```
8+
9+
The MVP parser supports model/JSON rows, `J`, `H`, `I`, `E`, `T`, `D`, `S`, `P`, `B`, and `C` tags. It decodes common `$` encodings including chunk refs, lazy refs, promises, dates, bigints, maps, sets, server functions, and property selections.
10+
11+
Unknown or malformed rows are recorded as recoverable parser errors in lenient mode. The UI keeps raw evidence available so unsupported React versions still have useful diagnostics.

0 commit comments

Comments
 (0)