diff --git a/README.md b/README.md index 3b038a9..d19e1e0 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,55 @@ Security is a top priority in this admin panel: - **Input Validation:** All user inputs are validated and sanitized - **XSS Prevention:** Output escaping prevents cross-site scripting +## Case Study + +### Problem + +Small phone retailers typically manage inventory in spreadsheets or handwritten ledgers. This leads to pricing errors, duplicate entries, no image tracking, and zero access control — anyone with the spreadsheet can modify records. + +### Solution + +PocketPhone provides a web-based inventory management system with a dedicated admin panel. Retailers can add, edit, and delete products with images through a clean interface. A public-facing showcase page displays the current inventory to customers automatically. + +### Architecture + +The system follows a traditional PHP MVC-like pattern: + +```mermaid +graph TD + A[Browser] -->|HTTP| B[index.php — Product Showcase] + A -->|Admin Login| C[admin/login.php] + C -->|Session Auth| D[auth_check.php] + D --> E[admin/index.php — Dashboard] + E --> F[add_product.php] + E --> G[edit_product.php] + E --> H[delete_product.php] + F & G & H -->|Prepared Statements| I[(MySQL)] + F & G -->|Image Upload| J[uploads/] + I --> B +``` + +- **Authentication layer** (`auth_check.php`) guards all admin routes via PHP sessions +- **Database layer** (`db_config.php`) centralizes connection logic with UTF-8 support +- **File uploads** are stored on disk in `uploads/` with validation + +### Security Considerations + +- Passwords are hashed with `password_hash()` (bcrypt) — never stored as plaintext +- All SQL queries use prepared statements to prevent injection +- Output is escaped with `htmlspecialchars()` to prevent XSS +- Session-based authentication with proper logout (session destruction) +- File upload validation checks type and size before storage + +### Lessons Learned + +- **Separation of concerns**: Even without a framework, keeping auth, config, and CRUD in separate files made the codebase manageable +- **Prepared statements from day one**: Retrofitting SQL injection prevention is harder than building it in +- **Bcrypt over MD5/SHA**: Using PHP's built-in `password_hash()` is simpler AND more secure than rolling custom hashing +- **Image storage**: Storing on disk with DB references is simpler than BLOB storage for a small-scale app + +See [docs/architecture.md](docs/architecture.md) for a deeper dive into the system components. + ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..450d74c --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,108 @@ +# PocketPhone — Architecture + +## System Overview + +PocketPhone is a PHP/MySQL inventory management application with two interfaces: + +1. **Public showcase** (`index.php`) — read-only product listing for customers +2. **Admin panel** (`admin/`) — authenticated CRUD interface for store managers + +## Component Diagram + +```mermaid +graph LR + subgraph Public + A[index.php] + end + subgraph Admin Panel + B[login.php] --> C[auth_check.php] + C --> D[index.php] + C --> E[add_product.php] + C --> F[edit_product.php] + C --> G[delete_product.php] + end + subgraph Storage + H[(MySQL)] + I[uploads/] + end + subgraph Config + J[db_config.php] + K[hashed.php] + end + A --> J --> H + D & E & F & G --> J + E & F --> I +``` + +## Data Flow + +### Product Creation + +1. Admin authenticates via `login.php` → session created +2. `auth_check.php` validates session on every admin page load +3. Admin fills form on `add_product.php` (name, price, description, image) +4. Server validates input, moves uploaded image to `uploads/` +5. Prepared INSERT statement writes to MySQL `products` table +6. Admin is redirected to dashboard with success message + +### Product Display (Public) + +1. `index.php` queries all products via `db_config.php` connection +2. Results are looped and rendered as HTML cards with escaped output +3. Product images are served from `uploads/` directory + +## Authentication Flow + +```mermaid +sequenceDiagram + participant U as User + participant L as login.php + participant A as auth_check.php + participant D as Dashboard + + U->>L: POST credentials + L->>L: password_verify(input, hash) + alt Valid + L->>L: session_start(), set $_SESSION + L->>D: redirect to admin/index.php + D->>A: include auth_check.php + A->>A: verify $_SESSION exists + A->>D: allow access + else Invalid + L->>U: error message + end +``` + +## Database Schema + +The application uses a single `products` table: + +| Column | Type | Description | +|--------|------|-------------| +| id | INT AUTO_INCREMENT | Primary key | +| name | VARCHAR | Product name | +| price | DECIMAL | Product price | +| description | TEXT | Product details | +| image | VARCHAR | Filename in uploads/ | + +Admin credentials are stored in a separate `users` table with bcrypt-hashed passwords. + +## Security Architecture + +| Threat | Mitigation | +|--------|-----------| +| SQL Injection | Prepared statements (`mysqli::prepare`) throughout | +| XSS | `htmlspecialchars()` on all output | +| Session Hijacking | Session regeneration on login | +| Brute Force | Password hashing with bcrypt (`password_hash`) | +| File Upload Attacks | Type/size validation before `move_uploaded_file()` | +| Direct File Access | `auth_check.php` included at top of every admin page | + +## Deployment + +The application runs on any LAMP/WAMP/XAMPP stack: + +1. Copy files to web server document root +2. Create MySQL database and import schema +3. Update `admin/db_config.php` with database credentials +4. Ensure `uploads/` directory is writable by the web server