# Security Testing Guide

This guide provides step-by-step instructions for performing the manual security tests from `references/MANUAL_SECURITY_TESTING_CHECKLIST.md`.

## Prerequisites

- You are logged in as **User A (ID: 5195)**
- **User B (ID: 5196)** exists as the victim account
- **Organization A** and **Organization B** exist
- **Bank A** exists (optional)

## Test Accounts

| Profile | ID | Email |
|---------|-------|-------|
| User A (you) | 5195 | user-a@test.nl |
| User B (victim) | 5196 | user-b@test.nl |
| Organization A | TBD | TBD |
| Organization B | TBD | TBD |

## How to Manipulate Session

Since Laravel stores sessions server-side (not in browser Session Storage), use this command:

```bash
cd /home/r/Websites/timebank_cc_2
php manipulate-session.php <profile_id> <type>
```

**Examples:**
```bash
# Change to User B
php manipulate-session.php 5196 user

# Change to Organization A (ID 1)
php manipulate-session.php 1 org

# Change to Bank A (ID 1)
php manipulate-session.php 1 bank

# Change back to User A
php manipulate-session.php 5195 user
```

After running the command, **refresh your browser** to apply the changes.

---

## Test Category 1: Profile Deletion Authorization

### Test 1.1: Unauthorized User Profile Deletion
**Risk Level:** CRITICAL

**Steps:**
1. Login as User A (already done)
2. Note User A's profile ID: **5195**
3. Run session manipulation:
   ```bash
   php manipulate-session.php 5196 user
   ```
4. Refresh browser
5. Navigate to Settings → Delete Account
6. Attempt to delete the profile

**Expected Result:** ✅ HTTP 403 Forbidden error
**Security Failure:** ❌ Profile deletion succeeds

**Log Verification:**
```bash
tail -f storage/logs/laravel.log | grep "ProfileAuthorizationHelper"
```
Should show: "Unauthorized User access attempt"

**Reset Session After Test:**
```bash
php manipulate-session.php 5195 user  # Change back to User A
```

---

### Test 1.2: Unauthorized Organization Profile Deletion
**Risk Level:** CRITICAL

**Prerequisites:** Find Organization A and B IDs first:
```bash
mysql -u timebank_cc_dev -p'zea2A8sd{QA,9^pS*2^@Xcltuk.vgV' timebank_cc_2 -e \
"SELECT id, name, email FROM organizations WHERE name LIKE '%Organization%' LIMIT 5;"
```

**Steps:**
1. Login as User A (member of Organization A)
2. Switch to Organization A profile using the profile switcher
3. Note Organization A's ID
4. Run session manipulation:
   ```bash
   php manipulate-session.php <org_b_id> org
   ```
5. Refresh browser
6. Navigate to organization settings → Delete Account
7. Attempt deletion

**Expected Result:** ✅ HTTP 403 Forbidden
**Security Failure:** ❌ Organization B deleted

**Reset:**
```bash
php manipulate-session.php 5195 user
```

---

### Test 1.3: Legitimate Profile Deletion (Control Test)
**Purpose:** Verify legitimate operations still work

**Steps:**
1. Login as User A
2. Ensure session is NOT manipulated (reset if needed):
   ```bash
   php manipulate-session.php 5195 user
   ```
3. Refresh browser
4. Navigate to Settings → Delete Account
5. Complete deletion process (⚠️ Use a test account, not your main account!)

**Expected Result:** ✅ Profile deletion succeeds
**Security Failure:** ❌ Legitimate deletion blocked

---

## Test Category 2: Profile Modification Authorization

### Test 2.1: Unauthorized Profile Settings Modification
**Risk Level:** CRITICAL

**Steps:**
1. Login as User A
2. Navigate to profile settings page
3. Run session manipulation:
   ```bash
   php manipulate-session.php 5196 user
   ```
4. Refresh browser
5. Attempt to modify profile details (name, email, about, etc.)
6. Click Save

**Expected Result:** ✅ HTTP 403 Forbidden
**Security Failure:** ❌ User B's profile modified

**Reset:**
```bash
php manipulate-session.php 5195 user
```

---

### Test 2.2: Unauthorized Organization Settings Modification
**Risk Level:** CRITICAL

**Steps:**
1. Login as User A
2. Switch to Organization A
3. Run session manipulation:
   ```bash
   php manipulate-session.php <org_b_id> org
   ```
4. Refresh browser
5. Navigate to organization settings
6. Attempt to modify organization details
7. Click Save

**Expected Result:** ✅ HTTP 403 Forbidden
**Security Failure:** ❌ Organization B modified

**Reset:**
```bash
php manipulate-session.php 5195 user
```

---

## Test Category 3: Message Settings Authorization

### Test 3.1: Unauthorized Message Settings Access
**Risk Level:** CRITICAL

**Steps:**
1. Login as User A
2. Navigate to Settings → Message Settings
3. Note current notification preferences
4. Run session manipulation:
   ```bash
   php manipulate-session.php 5196 user
   ```
5. Refresh browser
6. Toggle notification settings (email, push, etc.)
7. Click Save

**Expected Result:** ✅ HTTP 403 Forbidden
**Security Failure:** ❌ User B's message settings changed

**Reset:**
```bash
php manipulate-session.php 5195 user
```

---

## Test Category 4: Chat/Conversation Authorization

### Test 4.1: Unauthorized Conversation Access
**Risk Level:** HIGH

**Prerequisites:**
1. Create a conversation between User B and another user
2. Note the conversation ID from the URL

**Steps:**
1. Login as User A
2. Manually navigate to: `/chat/{conversation_id}`
3. Attempt to view conversation
4. Attempt to send messages

**Expected Result:** ✅ HTTP 403 Forbidden or redirect
**Security Failure:** ❌ User A can read/send messages

---

## Test Category 5: Transaction/Payment Authorization

### Test 5.1: Unauthorized Transaction Viewing
**Risk Level:** HIGH

**Prerequisites:**
1. User B creates transaction with User C
2. Note transaction ID

**Steps:**
1. Login as User A
2. Navigate to `/transaction/{transaction_id}`

**Expected Result:** ✅ HTTP 403 Forbidden
**Security Failure:** ❌ User A can view transaction

---

### Test 5.2: Session Manipulation for Transaction Access
**Risk Level:** CRITICAL

**Steps:**
1. Login as User A
2. Run session manipulation:
   ```bash
   php manipulate-session.php 5196 user
   ```
3. Refresh browser
4. Navigate to Transactions page
5. Check which transactions are visible

**Expected Result:** ✅ Only User A's transactions visible (or 403 error)
**Security Failure:** ❌ User B's transactions visible

**Reset:**
```bash
php manipulate-session.php 5195 user
```

---

## Useful Commands

### View Current Sessions
```bash
mysql -u timebank_cc_dev -p'zea2A8sd{QA,9^pS*2^@Xcltuk.vgV' timebank_cc_2 -e \
"SELECT id, user_id, ip_address, FROM_UNIXTIME(last_activity) as last_active \
FROM sessions WHERE last_activity > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 2 HOUR)) \
ORDER BY last_activity DESC LIMIT 5;"
```

### Find Profile IDs
```bash
# Users
mysql -u timebank_cc_dev -p'zea2A8sd{QA,9^pS*2^@Xcltuk.vgV' timebank_cc_2 -e \
"SELECT id, name, email FROM users WHERE name LIKE '%User%' ORDER BY id LIMIT 10;"

# Organizations
mysql -u timebank_cc_dev -p'zea2A8sd{QA,9^pS*2^@Xcltuk.vgV' timebank_cc_2 -e \
"SELECT id, name, email FROM organizations WHERE name LIKE '%Organization%' LIMIT 10;"

# Banks
mysql -u timebank_cc_dev -p'zea2A8sd{QA,9^pS*2^@Xcltuk.vgV' timebank_cc_2 -e \
"SELECT id, name, email FROM banks LIMIT 10;"
```

### Monitor Authorization Logs
```bash
# Watch for authorization attempts
tail -f storage/logs/laravel.log | grep "ProfileAuthorizationHelper"

# Watch for unauthorized access attempts
tail -f storage/logs/laravel.log | grep -i "Unauthorized.*access attempt"
```

### Reset Session to User A
```bash
php manipulate-session.php 5195 user
```

---

## Troubleshooting

**Problem:** Session manipulation doesn't work
**Solution:** Make sure you refresh the browser after running the command

**Problem:** Can't find profile IDs
**Solution:** Use the MySQL commands above to query the database

**Problem:** Script permission denied
**Solution:** Run `chmod +x manipulate-session.php`

**Problem:** Need to restore your original session
**Solution:** Run `php manipulate-session.php 5195 user` and refresh browser

---

## Important Notes

1. **Always refresh your browser** after manipulating the session
2. **Reset your session** back to User A after each test: `php manipulate-session.php 5195 user`
3. **Monitor logs** during testing: `tail -f storage/logs/laravel.log | grep ProfileAuthorizationHelper`
4. **Don't delete important accounts** - use test accounts for deletion tests
5. These tests are for **security testing only** - never use in production

---

## Test Category 6: AccountInfoModal — IDOR (Balance Leakage)

### Test 6.1: Unauthorized Balance Viewing via Session Manipulation
**Risk Level:** HIGH — **Fixed 2026-03-23**
**Component:** `app/Http/Livewire/AccountInfoModal.php`
**Fix:** `ProfileAuthorizationHelper::authorize($profile)` added to `loadAccounts()` after profile resolution. Manipulated session now returns HTTP 403.

**Steps:**
1. Login as User A
2. Open the Account Info modal (click the balance link in the navigation) — note your own balances
3. Run session manipulation:
   ```bash
   php manipulate-session.php 5196 user
   ```
4. Refresh browser
5. Open the Account Info modal again

**Expected Result:** ✅ HTTP 403 Forbidden OR modal shows zero/no accounts
**Security Failure:** ❌ User B's account balances are visible

**Log Verification:**
```bash
tail -f storage/logs/laravel.log | grep "ProfileAuthorizationHelper"
```

**Reset:**
```bash
php manipulate-session.php 5195 user
```

---

### Test 6.2: Cross-Profile-Type Balance Leakage (Organization)
**Risk Level:** HIGH

**Steps:**
1. Login as User A
2. Run session manipulation to switch to an organization you are NOT a member of:
   ```bash
   php manipulate-session.php <org_b_id> org
   ```
3. Refresh browser
4. Open the Account Info modal

**Expected Result:** ✅ HTTP 403 Forbidden OR modal shows zero accounts
**Security Failure:** ❌ Organization B's account balances are visible

**Reset:**
```bash
php manipulate-session.php 5195 user
```

---

## Test Category 7: Reports — Arbitrary File Write

### Test 7.1: Malformed Base64 Chart Image Upload
**Risk Level:** MEDIUM — **Fixed 2026-03-23**
**Component:** `app/Http/Livewire/Reports.php` — `exportPdfWithChart()` / `exportPdfWithCharts()`
**Fix:** `decodeChartImage()` helper validates PNG/JPEG magic bytes before writing. `base64_decode(..., strict: true)` used to reject malformed input. Non-image payloads abort with HTTP 422 and are logged.

**Steps:**
1. Login as User A
2. Navigate to the Reports page
3. Open browser DevTools → Network tab
4. Trigger any PDF export that invokes `exportPdfWithChart`
5. Locate the Livewire POST request and copy the payload
6. Modify the `chartImage` parameter to contain a PHP webshell encoded as base64:
   ```
   data:image/png;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+
   ```
   (This decodes to `<?php system($_GET['cmd']); ?>`)
7. Re-send the modified request (use DevTools "Copy as fetch" then paste in Console)

**Expected Result:** ✅ Request rejected (invalid MIME type), or file written but not web-executable
**Security Failure:** ❌ PHP file written to an accessible path and the application executes it

**Verify storage is not web-accessible:**
```bash
curl -I http://localhost/storage/temp/
# Should return 404 or 403, not 200
```

---

### Test 7.2: Unauthenticated Livewire Chart Export Action
**Risk Level:** MEDIUM — **Fixed 2026-03-23** (`abort_unless(Auth::check(), 403)` added)

**Steps:**
1. Log out entirely
2. POST a Livewire request to `exportPdfWithChart` with a valid-looking base64 payload

**Expected Result:** ✅ Redirected to login, or 401/403 response
**Security Failure:** ❌ File written to temp storage without authentication

---

## Test Category 8: ExportProfileData — Authorization Verification

### Test 8.1: Unauthorized Transaction Export via Session Manipulation
**Risk Level:** HIGH
**Component:** `app/Http/Livewire/Profile/ExportProfileData.php` — `exportTransactions()`
**Note:** This component DOES call `ProfileAuthorizationHelper::authorize()`. This test verifies the protection works correctly.

**Steps:**
1. Login as User A
2. Navigate to Profile → Export Data
3. Run session manipulation:
   ```bash
   php manipulate-session.php 5196 user
   ```
4. Refresh browser
5. Attempt to export transactions (any format)

**Expected Result:** ✅ HTTP 403 Forbidden
**Security Failure:** ❌ User B's transactions are exported

**Log Verification:**
```bash
tail -f storage/logs/laravel.log | grep "ProfileAuthorizationHelper"
```
Should show: "Unauthorized User profile access attempt"

**Reset:**
```bash
php manipulate-session.php 5195 user
```

---

### Test 8.2: Unauthorized Messages Export
**Risk Level:** HIGH

**Steps:**
1. Login as User A
2. Run session manipulation:
   ```bash
   php manipulate-session.php 5196 user
   ```
3. Refresh browser
4. Attempt to export messages

**Expected Result:** ✅ HTTP 403 Forbidden
**Security Failure:** ❌ User B's private messages exported

**Reset:**
```bash
php manipulate-session.php 5195 user
```

---

### Test 8.3: Unauthorized Contacts Export
**Risk Level:** MEDIUM

**Steps:**
1. Login as User A
2. Run session manipulation:
   ```bash
   php manipulate-session.php 5196 user
   ```
3. Refresh browser
4. Attempt to export contacts

**Expected Result:** ✅ HTTP 403 Forbidden
**Security Failure:** ❌ User B's contact list exported

**Reset:**
```bash
php manipulate-session.php 5195 user
```

---

## Quick Reference

| Action | Command |
|--------|---------|
| Change to User B | `php manipulate-session.php 5196 user` |
| Change to Org B (ID 1) | `php manipulate-session.php 1 org` |
| Change to Bank A (ID 1) | `php manipulate-session.php 1 bank` |
| Reset to User A | `php manipulate-session.php 5195 user` |
| Monitor logs | `tail -f storage/logs/laravel.log \| grep ProfileAuthorizationHelper` |
| Check temp dir not web-accessible | `curl -I http://localhost/storage/temp/` |
