-
Notifications
You must be signed in to change notification settings - Fork 0
Add case study and architecture documentation #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
Comment on lines
+108
to
+110
|
||
|
|
||
| ### 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. | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -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] | ||||||||||||||||||||||||||||
|
Comment on lines
+18
to
+22
|
||||||||||||||||||||||||||||
| 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] | |
| B[login.php] | |
| C[auth_check.php] | |
| D[index.php] | |
| E[add_product.php] | |
| F[edit_product.php] | |
| G[delete_product.php] | |
| D & E & F & G --> C | |
| C --> B |
Copilot
AI
Mar 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The “Product Creation” step list mentions a description field, but admin/add_product.php only collects/stores name, condition, price, and image (it inserts into condition_desc and image_path). Please align the documentation with the actual form fields/DB columns.
Copilot
AI
Mar 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This products table schema doesn’t match the code: the app reads/writes condition_desc and image_path (and does not use description or image columns). Please update the schema table to reflect the actual column names used by the application.
| | description | TEXT | Product details | | |
| | image | VARCHAR | Filename in uploads/ | | |
| | condition_desc | TEXT | Product condition/details | | |
| | image_path | VARCHAR | Image path/filename in uploads/ | |
Copilot
AI
Mar 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The admin credentials table name appears to be admins (see the query in admin/login.php), not users. Please update this line so the documentation matches the implementation/database naming.
| Admin credentials are stored in a separate `users` table with bcrypt-hashed passwords. | |
| Admin credentials are stored in a separate `admins` table with bcrypt-hashed passwords. |
Copilot
AI
Mar 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Several items in the security threat table don’t match the current implementation: there is no session ID regeneration on login, and hashing passwords is not a brute-force mitigation (there’s no rate limiting/lockout). Also, output escaping is not applied to all rendered user-controlled values (e.g., some form fields echo raw values). Please adjust the mitigations to reflect what the code actually does (or implement the missing defenses).
| | 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()` | | |
| | XSS | `htmlspecialchars()` on public product listing; some admin outputs still echo raw values | | |
| | Session Hijacking | Session-based access control via `auth_check.php`; no session ID regeneration on login | | |
| | Brute Force | Credentials stored with bcrypt (`password_hash`); no login rate limiting or lockout implemented | | |
| | File Upload Attacks | Images uploaded via `move_uploaded_file()`; additional type/size validation required | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the Mermaid architecture diagram,
auth_check.phpand the CRUD pages are referenced without theadmin/prefix, but they live underadmin/in the repo. Updating these node labels/links toadmin/auth_check.php,admin/add_product.php, etc. will prevent confusion and broken references.