Overview
The Normo Unsecure PWA is a Flask-based progressive web application with an intentionally vulnerable architecture designed for educational security analysis. Understanding its structure is essential for identifying and exploiting security vulnerabilities.Technology Stack
Backend Framework
Flask - Python micro web framework
Database
SQLite - Lightweight SQL database
Frontend
HTML/CSS/JavaScript - Standard web technologies
PWA Features
Service Worker & Manifest - Progressive Web App capabilities
Application Structure
The application follows a simple Flask architecture with the following key components:Project Structure
Core Components
1. Flask Application (main.py)
The main Flask application defines three primary routes with multiple security vulnerabilities:
main.py
POST /index.html- User authentication (main.py:46-67)POST /signup.html- User registration (main.py:31-43)POST /success.html- Feedback submission (main.py:16-28)
2. Database Layer (user_management.py)
The database module handles all data operations with critical security flaws:
user_management.py
insertUser()- User registration (✅ secure)retrieveUsers()- Authentication (⚠️ SQL injection, timing attack)insertFeedback()- Feedback submission (⚠️ SQL injection)listFeedback()- Display feedback (⚠️ XSS vulnerability)
3. Database Schema
The SQLite database contains two simple tables:- users table
- feedback table
4. Templates & Frontend
The application uses Jinja2 templates with minimal client-side validation: Template Structure:layout.html- Base template with PWA metadataindex.html- Login form (no CSRF protection, minimal validation)signup.html- Registration form (no input validation)success.html- User dashboard with feedback display
manifest.json- PWA configuration- CSS/JavaScript - Basic styling and interactivity
- Icons - PWA installable app icons
The app is a Progressive Web App (PWA) that can be installed on mobile devices, but this doesn’t add any security - all the backend vulnerabilities remain.
Configuration & Deployment
Flask Configuration
main.py:70-73
debug=True- Exposes detailed error messages and stack traceshost="0.0.0.0"- Accepts connections from any network interface- No secret key configured for sessions
- No HTTPS/SSL configuration
- No rate limiting or request throttling
Dependencies
requirements.txt
Many security-focused dependencies are included in
requirements.txt but not actually used in the code. This is intentional - students must implement these security measures themselves.Request Flow
User Authentication Flow
- User submits credentials via POST to
/index.html - Flask receives form data (username, password)
dbHandler.retrieveUsers()queries database with SQL injection vulnerability- If credentials match, user is “authenticated” (no session created)
- User is redirected to
/success.htmlwith username passed in template
Feedback Submission Flow
- Authenticated user submits feedback via POST to
/success.html - Flask receives form data (feedback)
dbHandler.insertFeedback()inserts feedback with SQL injection vulnerabilitydbHandler.listFeedback()regenerates HTML with XSS vulnerability- Feedback displayed on success page without sanitization
Attack Surface Analysis
The application has multiple attack vectors across all layers:Network Layer Attacks
Network Layer Attacks
- No HTTPS: All traffic is HTTP (port 5000)
- CORS misconfiguration: Accepts requests from any origin
- No rate limiting: Vulnerable to brute force attacks
- Open to all interfaces:
host="0.0.0.0"exposes to network
Application Layer Attacks
Application Layer Attacks
- SQL Injection: 3 vulnerable queries in
user_management.py - XSS: Unescaped user input in
listFeedback() - CSRF: No token validation on any forms
- Open Redirect: 3 unvalidated redirects in
main.py - No input validation: All form inputs accepted without checks
Authentication & Session Attacks
Authentication & Session Attacks
- Plaintext passwords: No hashing or encryption
- No session management: Authentication state not maintained
- No logout functionality: Users cannot terminate sessions
- Timing attacks: Variable response times reveal valid usernames
- No 2FA: Single-factor authentication only
Data Protection Attacks
Data Protection Attacks
- No encryption at rest: Database unencrypted
- No encryption in transit: HTTP instead of HTTPS
- Debug mode enabled: Stack traces exposed to attackers
- File write vulnerability:
listFeedback()writes arbitrary content
Architectural Anti-Patterns
This application intentionally violates secure architecture principles:| Anti-Pattern | Location | Impact |
|---|---|---|
| No separation of concerns | All business logic in routes | Hard to secure, test, and maintain |
| Direct database access | Routes call DB functions directly | No abstraction or validation layer |
| No input validation layer | Throughout application | Every endpoint is vulnerable |
| No authentication middleware | No session management | Anyone can access “protected” pages |
| No error handling | No try-except blocks | Crashes expose internal details |
| Mixing GET and POST | All routes accept all methods | CSRF and unintended operations |
Next Steps
Security Testing
Learn how to test this architecture for vulnerabilities
Security by Design
Understand how this app violates security principles
Vulnerabilities
Explore specific vulnerability documentation
Mitigation Guides
Learn how to fix these architectural flaws
