Skip to content

Latest commit

 

History

62 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🛡️ DroidGuard Quest

"From vulnerability to fortress — your Android security journey, gamified."

Live → https://droidguard.vercel.app


Principle

DroidGuard Quest is a free, study-only single-page app that turns Android security knowledge into a Duolingo-style journey. The goal is to take a developer or aspiring pentester from Junior to Senior through ten themed levels, one topic at a time, with quick feedback and a memorable shape — not another wall of text.

What the experience looks like. The map is a winding path with ten circular nodes. Tapping the next unlocked node opens a short knowledge briefing, then five randomly-drawn questions from a pool of eight to ten per level. Each correct answer is worth 100 XP and the result screen shows stars (1–5), a badge, the running streak, and a level-up celebration when a new tier unlocks. A bonus Codex library — six themed areas, twenty books, sixty short chapters — pays out extra XP for off-quiz reading, and a reading history page tracks what you've gone through.

What it teaches. Across the ten levels you cover Android architecture and the APK internals (classes.dex, META-INF, res/), data storage and EncryptedSharedPreferences, the Keystore and modern crypto, HTTPS and certificate pinning, IPC and component exploitation (WebView XSS/LFI, ContentProvider SQL injection, Activity hijacking, tapjacking), authentication with BiometricPrompt and OAuth/PKCE, R8 and reverse engineering, the canonical pentest stack (Frida, Objection, MobSF, Drozer, Burp, QARK, AndroBugs, ClassyShark, APKLeaks, HTTP Toolkit, Pidcat), root and tamper detection, and the OWASP MASVS / Mobile Top 10 (2024) catalogue. The full pool sits at 121 quiz questions, all sourced from the references in the Credits section.

Design decisions you will notice in the code.

  • Source vs. served. Everything that lives in src/ is the development source. Everything that lives in public/ is the static, minified and obfuscated bundle that the local server (and the live host) actually serves. Source is never reachable at runtime.
  • No build framework, no client framework. Plain JavaScript, plain SVG, plain CSS. The entire bundle is around 67 KB gzipped and boots in well under a second on a cold connection.
  • App-side hardening. The app is free for studies, but it is not for casual cheating. A small defensive layer ships with the bundle: localStorage payloads are XOR-masked, checksum-stamped and bounds-validated, the production bundle drops console.* to no-ops, runs a periodic debugger trap, and flags Frida-style hooks, DevTools and userscript injection. Localhost skips all of this so dev DX stays normal. A ?dev=1 query string opens a session-scoped bypass for the maintainer.
  • Privacy by default. All progress lives in your browser's localStorage. Nothing leaves the device. There is no analytics, no tracking, no remote sync.

How to run

You need Node.js 18 or newer.

# 1. install runtime + build dependencies
npm install

# 2. build the static bundle (src/ -> public/)
npm run build

# 3. serve the bundle on http://localhost:3000
npm start

Or in a single command for iterative work:

npm run dev          # build, then start

Other scripts:

Script What it does
npm run build Minifies, obfuscates and compresses into public/
npm start Serves public/ on port 3000 (Express)
npm run dev build followed by start
npm run preview Alias of start, for post-build QA
npm run clean Removes public/

Project layout

DroidGuard Quest/
├── src/                       # source — never served
│   ├── index.html
│   ├── css/styles.css
│   ├── js/anti-tamper.js
│   ├── js/data.js             # 10 levels, 121 questions
│   ├── js/library.js          # Codex catalog
│   ├── js/markdown.js         # tiny markdown renderer
│   ├── js/integrity.js        # XOR + FNV-1a localStorage wrapper
│   ├── js/state.js            # progression with bounds validation
│   ├── js/quiz.js             # session builder & scoring
│   ├── js/fx.js               # CRT + glitch presets
│   ├── js/map.js              # winding SVG path map
│   ├── js/app.js              # views, modals, toast
│   └── assets/
│       ├── favicon.svg
│       ├── library/           # 20 .md books across 6 areas
│       └── paths/             # six themeable journey-path SVGs + preview
├── api/
│   └── health.js              # /api/health serverless function
├── build.js                   # src/ → public/ pipeline
├── server.js                  # local Express server, public/ only
├── package.json
├── vercel.json
└── README.md

Build pipeline

npm run build reads src/ and writes public/:

Stage Tool Notes
JS minify terser drops console.*, mangles names, two passes
JS obfuscate javascript-obfuscator heavy profile (string-array, control-flow flattening, self-defending) on data, library, integrity, state, quiz; light profile elsewhere
HTML html-minifier-terser removeOptionalTags, collapseBooleanAttributes, removeAttributeQuotes, inline CSS/JS minified
CSS csso restructured + compressed
Names (custom rename pass) every CSS class and id is rewritten to _a-style aliases across CSS, HTML and JS
Static (verbatim copy) src/assets/ (path SVGs, library .md)

OS metadata such as .DS_Store is filtered out. The HTML ends up around 2.4 KB raw / under 1 KB gzipped.

App-side security

  • Strict CSP (default-src 'self', no unsafe-eval, no external origins).
  • X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy: camera=(), microphone=(), geolocation=().
  • localStorage payloads are XOR-masked with a baked-in salt and stamped with an FNV-1a checksum; tampered or out-of-range values trigger a silent reset.
  • In production hosts: console.* no-op'd, periodic debugger; trap, DevTools and Frida heuristics, userscript / extension scan. Soft signals (window-size delta, console probe) need correlation; strong signals (Frida toString-tamper, userscript globals, extension script srcs) replace the entire DOM with a warning stub. Localhost / 127.* hosts skip the layer; ?dev=1 opens a per-session bypass for the maintainer.

Credits

DroidGuard Quest is built on top of work generously shared by people in the security community. If the content here helped you, please go read the originals.

Quiz curriculum

Codex sources — Jackson Mafra

Every book in the in-app Codex is a companion summary of one of these original articles or repos.

Book Source
Android Overlay Attacks Medium
GhostTouch GitHub
Hackers Gonna Hack Medium
Mobile Security Dumpster Fire (Top 10) Medium
Bulletproof Security Medium
Fingerprinting Android Devices Medium
Device Attestation 101 Medium
Trust No One Medium
Attestation & Fingerprinting Series Medium
Privacy vs. Security Medium
Mobile Security: Hackers Need Hobbies Medium
Custom ROMs and Rooted Devices Medium
Android Goes Undercover Medium
The Manufacturer's Dilemma Medium
Android Command-Line Tools Medium
Cuttlefish 🦑 Medium
Exploring AVDs 🚀 Medium
Automating Input Events Medium
Verifying Installer Source Medium
Hackdroid (vulnerable lab app) GitHub

Practice apps for hands-on labs

DIVA · InsecureBankv2 · Injured Android · OWASP UnCrackable · InsecureShop · AndroGoat · DVHMA · Vuldroid · ovaa


DroidGuard Quest is licensed under the MIT License. It is intended for education only.

About

DroidGuard Quest is a free, study-only single-page app that turns Android security knowledge into a Duolingo-style journey.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages