An interactive educational visualization explaining the React2Shell vulnerability - a critical CVSS 10.0 remote code execution flaw in React Server Components.
A 5-step narrated walkthrough that explains:
- Traditional SSR - How server-side rendering works and the "JSON bottleneck" problem
- RSC Streaming - How React Server Components solve this with streaming
- The Exploit - How prototype pollution + gadget chains enable RCE
- The Fix - The one-line
hasOwnPropertycheck that prevents the attack - Key Takeaways - Lessons learned for secure architecture
Each step features:
- Synced audio narration with word-by-word captions
- Keyframe-driven animations timed to the narration
- Video player controls (play/pause, seek, speed, captions)
- Visual highlighting of key concepts
The visualization is fully responsive with a mobile-optimized experience:
- Auto-scrolling: On mobile viewports (≤1000px), the page automatically scrolls to follow the animation. Scroll targets are driven by Whisper timestamp data, keeping the focal point (browser → network → server → explanation) in view as the narration progresses.
- Sticky video controls: Play/pause and timeline controls stay fixed at the bottom for easy access while scrolling.
- Mobile captions: Word-by-word captions appear in the video controls area on mobile.
- Responsive layouts: Grids stack vertically, font sizes scale appropriately, and touch-friendly controls.
The visualization supports three audience levels, each with tailored narration:
| Level | Audience | Style |
|---|---|---|
| Expert | Security engineers, senior devs | Precise terminology, deep mechanics |
| Practitioner | Developers, IT pros | Concepts with practical examples |
| Stakeholder | Leadership, PMs | Business impact, key takeaways |
Users can switch between levels in real-time via the "Target Audience" dropdown in the video controls.
- SvelteKit with Svelte 5 runes
- ElevenLabs for AI voice generation
- OpenAI Whisper for audio transcription & timestamp extraction
- TypeScript throughout
├── scripts/ # Narration scripts (source of truth)
│ ├── expert/
│ │ ├── ssr-narration.txt
│ │ ├── rsc-narration.txt
│ │ ├── exploit-narration.txt
│ │ ├── fix-narration.txt
│ │ └── lessons-narration.txt
│ ├── practitioner/
│ │ └── ... (same files)
│ ├── stakeholder/
│ │ └── ... (same files)
│ └── transcribe.py # Whisper transcription script
├── static/audio/ # Generated MP3 files
│ ├── expert/
│ │ ├── ssr.mp3
│ │ ├── rsc.mp3
│ │ ├── exploit.mp3
│ │ ├── fix.mp3
│ │ └── lessons.mp3
│ ├── practitioner/
│ │ └── ... (same files)
│ └── stakeholder/
│ └── ... (same files)
├── src/lib/data/ # Whisper JSON output (word timestamps)
│ ├── expert/
│ │ ├── ssr-whisper.json
│ │ └── ...
│ ├── practitioner/
│ │ └── ...
│ └── stakeholder/
│ └── ...
└── src/lib/utils/triggers/ # Animation trigger phrases per level
├── expert/
├── practitioner/
└── stakeholder/
npm install
npm run devScripts are in scripts/{level}/:
ssr-narration.txtrsc-narration.txtexploit-narration.txtfix-narration.txtlessons-narration.txt
Each script includes trigger phrase comments at the bottom for animation sync.
Upload the script to ElevenLabs and download the MP3.
Drop the MP3 in static/audio/{level}/ with the step name (e.g., static/audio/expert/ssr.mp3).
Single file:
python scripts/transcribe.py ssr expert
python scripts/transcribe.py rsc practitionerBatch mode (all files for a level):
python scripts/transcribe.py --batch expert
python scripts/transcribe.py --batch practitioner
python scripts/transcribe.py --batch stakeholder
python scripts/transcribe.py --batch all # All 15 filesOptions:
--model small- Use a larger Whisper model for better accuracy--dry-run- Preview what would be transcribed without running
The script outputs JSON to src/lib/data/{level}/ with word-level timestamps.
If the narration wording changed significantly, update the trigger phrases in src/lib/utils/triggers/{level}/ to match the new script.
- Whisper JSON contains word-level timestamps for each audience level
- Trigger extraction (
src/lib/utils/triggers/) finds key phrases per level - Keyframes map timestamps to animation states
- Timeline controller (
src/lib/stores/timeline.svelte.ts) syncs audio with animation - Components derive visual state from
currentTimeusinggetAnimationState() - Lazy loading fetches whisper data on-demand and caches it
npm run build
npm run preview- react2shell.com - Original disclosure
- Wiz Deep Dive
- Datadog Security Labs
Educational purposes. Created for security awareness.