Share
## https://sploitus.com/exploit?id=0E3F3A8F-298D-5C14-8601-E03E42639573
# MediCare Portal
**Intentionally vulnerable healthcare patient portal for demonstrating the OWASP Top 10 (2021).**
Built for a Secure Programming final project. Every vulnerability has a hardened counterpart controlled by a single boolean in `config.php`. Flip it during a live demo to show the attack, then the fix, in real time.
---
# Setup (Arch Linux)
## 1. Install dependencies
```bash
sudo pacman -S php apache mariadb php-apache
```
## 2. Set up MariaDB
```bash
sudo mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
sudo systemctl start mariadb
sudo systemctl enable mariadb
sudo mariadb-secure-installation
```
Set a root password when prompted. Then import the schema:
```bash
mariadb -u root -p [!note]
> If you get `ERROR 1698 (28000): Access denied for user 'root'@'localhost'`,
> run `sudo mariadb-secure-installation` again and change the root password when prompted.
## 3. Configure Apache
All edits below go in `/etc/httpd/conf/httpd.conf`.
**Switch to prefork MPM** (required because Arch's PHP module is not thread-safe):
```apache
# Find this line and comment it out:
#LoadModule mpm_event_module modules/mod_mpm_event.so
# Add below it:
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
```
**Enable PHP and rewrite** (add at the end of the `LoadModule` list):
```apache
LoadModule php_module modules/libphp.so
AddHandler php-script .php
Include conf/extra/php_module.conf
```
**Uncomment mod_rewrite** (find the existing commented line):
```apache
LoadModule rewrite_module modules/mod_rewrite.so
```
**Set the document root** (find and replace the existing `DocumentRoot` and `` block):
```apache
DocumentRoot "/path/to/medicare-portal"
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
```
Replace `/path/to/medicare-portal` with the actual absolute path to the project.
## 4. Configure PHP
Edit `/etc/php/php.ini` and uncomment:
```ini
extension=pdo_mysql
extension=mysqli
```
## 5. Allow Apache to access your home directory
> [!note]
> Skip this step if your project is outside `/home` (e.g. in `/srv/http`).
Arch's systemd unit for Apache sets `ProtectHome=yes`, which blocks access to anything under `/home`. If your project lives there, override it:
```bash
sudo vim /etc/systemd/system/httpd.service.d/hardening.conf
```
Uncomment (or add) this line:
```ini
ProtectHome=no
```
Then reload the service config:
```bash
sudo systemctl daemon-reload
```
## 6. Set file permissions
```bash
chmod -R 755 /path/to/medicare-portal
chmod -R 777 /path/to/medicare-portal/uploads
```
## 7. Update database credentials
Edit `config.php`:
```php
define('DB_PASS', 'your_password_here'); // whatever you set in step 2
```
## 8. Start Apache
```bash
sudo systemctl restart httpd
```
Open `http://localhost` โ you should see the login page.
## Alternative: PHP built-in server (no Apache)
For quick testing without Apache config:
```bash
cd /path/to/medicare-portal
php -S localhost:8080
```
This works for most features but `.htaccess` rules won't apply, and the webshell upload demo (A08) won't auto-execute PHP files in `/uploads/`.
---
# Test Accounts
All seed passwords are stored as MD5 in vulnerable mode. These are the plaintext values:
| Role | Email | Password |
|---------|-------------------|-------------|
| Patient | alice@demo.com | password123 |
| Patient | bob@demo.com | password123 |
| Doctor | drsmith@demo.com | password123 |
| Admin | admin@demo.com | admin123 |
---
# How SECURE_MODE Works
Every vulnerable code path checks a single constant in `config.php`:
```php
define('SECURE_MODE', false); // vulnerable
define('SECURE_MODE', true); // hardened
```
Each feature file contains two functions - one vulnerable, one secure - and dispatches to the right one based on this flag. Change the value, refresh the browser, and the behavior flips instantly. No restart needed.
---
# OWASP Top 10 Coverage
| # | Category | File | Vulnerable Behavior | Secure Fix |
|-----|---------------------------------|------------------------------|-----------------------------------------|----------------------------------------------|
| A01 | Broken Access Control | `patient/records.php` | IDOR via `?patient_id=` parameter | Session ownership check + role gating |
| A02 | Cryptographic Failures | `auth/register.php` | Passwords stored as plain MD5 | `password_hash()` with bcrypt |
| A03 | Injection (SQLi) | `shared/search.php` | Raw string concatenation in query | PDO prepared statements |
| A03 | Injection (XSS) | `patient/chat.php` | Raw `echo $msg['body']` | `htmlspecialchars()` on output |
| A04 | Insecure Design | `patient/appointments.php` | No rate limit, no conflict checks | Slot conflict + daily booking cap |
| A05 | Security Misconfiguration | `.htaccess`, Apache config | Verbose errors, directory listing | Error suppression, `Options -Indexes` |
| A06 | Vulnerable Components | `composer.json` | PHPMailer 5.2.23 (CVE-2016-10033) | Reference patched version in slides |
| A07 | Auth & Session Failures | `auth/login.php` | No `session_regenerate_id()` on login | Session regeneration + login timestamp |
| A08 | Software & Data Integrity | `shared/upload.php` | No MIME check, `.php` files execute | MIME whitelist + random rename |
| A09 | Logging & Monitoring Failures | `admin/audit_log.php` | No audit entries written | All sensitive actions logged to `audit_log` |
| A10 | SSRF | `shared/insurance_fetch.php` | `file_get_contents()` on any URL | Domain whitelist + private IP blocking |
> [!note]
> This project was built against the **OWASP Top 10 (2021)** classification. OWASP released an
> updated **2025 edition** in November 2025 that reshuffles the ranking and introduces two new
> categories. The vulnerabilities demonstrated here remain the same โ only the numbering changed:
>
> | This Project (2021) | OWASP 2025 Equivalent |
> |---------------------------------------|----------------------------------------------------------|
> | A01 โ Broken Access Control | A01:2025 โ Broken Access Control (unchanged) |
> | A02 โ Cryptographic Failures | A04:2025 โ Cryptographic Failures (moved to `#4`) |
> | A03 โ Injection (SQLi, XSS) | A05:2025 โ Injection (moved to `#5`) |
> | A04 โ Insecure Design | A06:2025 โ Insecure Design (moved to `#6`) |
> | A05 โ Security Misconfiguration | A02:2025 โ Security Misconfiguration (moved to `#2`) |
> | A06 โ Vulnerable Components | A03:2025 โ Software Supply Chain Failures (expanded) |
> | A07 โ Auth & Session Failures | A07:2025 โ Authentication Failures (unchanged) |
> | A08 โ Software & Data Integrity | A08:2025 โ Software & Data Integrity Failures (unchanged)|
> | A09 โ Logging & Monitoring Failures | A09:2025 โ Security Logging & Alerting Failures (renamed)|
> | A10 โ SSRF | Merged into A01:2025 โ Broken Access Control |
---
# Project Structure
```
medicare-portal/
โโโ config.php โ SECURE_MODE toggle + DB connection + shared helpers
โโโ helpers.php โ Layout rendering (sidebar, header, footer)
โโโ index.php โ Redirects to login or dashboard
โ
โโโ auth/
โ โโโ login.php โ A02 (MD5), A07 (session fixation)
โ โโโ register.php โ A02 (MD5 vs bcrypt)
โ โโโ logout.php
โ
โโโ patient/
โ โโโ dashboard.php โ Appointments + messages overview
โ โโโ records.php โ A01 (IDOR)
โ โโโ appointments.php โ A04 (insecure design)
โ โโโ chat.php โ A03 (stored XSS)
โ
โโโ doctor/
โ โโโ dashboard.php โ Upcoming appointments + messages
โ โโโ patients.php โ Patient list for this doctor
โ โโโ chat.php โ A03 (stored XSS, doctor side)
โ
โโโ admin/
โ โโโ dashboard.php โ System stats + user overview
โ โโโ users.php โ User management (delete)
โ โโโ audit_log.php โ A09 (logging failures)
โ
โโโ shared/
โ โโโ search.php โ A03 (SQL injection)
โ โโโ upload.php โ A08 (unrestricted file upload)
โ โโโ insurance_fetch.php โ A10 (SSRF)
โ
โโโ uploads/ โ Uploaded files land here (writable)
โโโ assets/
โ โโโ style.css โ Full custom CSS (~300 lines)
โ โโโ main.js โ Chat scroll + nav highlighting
โ
โโโ db/
โ โโโ schema.sql โ Full schema + seed data
โ
โโโ composer.json โ A06 (vulnerable dependency)
โโโ .htaccess โ A05 (misconfiguration surface)
โโโ .gitignore
```
---
# Disclaimer
This application is **intentionally vulnerable**. Run it only in isolated environments - your local machine, a VM, or a container. Never expose it to a network you do not fully control.
---