# Security Documentation

This document describes the security measures implemented in SecureBank.

## Authentication Security

### Password Storage
- Passwords are hashed using bcrypt with 12 rounds (Laravel default)
- Plaintext passwords are never stored or logged
- Password fields are excluded from flash data in exception handlers

### Transfer PIN Storage
- Transfer PINs are hashed using bcrypt (same as passwords)
- PINs are never stored in plaintext
- The `TransferPin` model's `pin_hash` field is in the `$hidden` array
- PIN verification uses `password_verify()` for constant-time comparison

### OTP Codes
- OTP codes are hashed using bcrypt at rest
- OTPs have configurable expiry (default: 10 minutes)
- Maximum attempt limits prevent brute-force (default: 5)
- Resend cooldown prevents abuse (default: 60 seconds)
- Previous unverified OTPs are invalidated when a new one is generated

### Session Security
- Sessions are stored in the database (not files)
- Session data is encrypted (`SESSION_ENCRYPT=true`)
- Session timeout is configurable (default: 120 minutes)
- `logoutOtherDevices()` available for "logout from all devices"
- CSRF tokens on all forms

## Transaction Security

### Atomic Transfers
- All balance mutations happen inside a database transaction (`DB::transaction`)
- Balance rows are locked using `SELECT ... FOR UPDATE` (pessimistic locking)
- This prevents concurrent modification race conditions

### Double-Entry Ledger
- Every transfer creates paired debit/credit `LedgerEntry` records
- This provides a complete audit trail of all money movement
- The ledger records the balance after each entry for verification

### Idempotency
- Each transaction has a unique `idempotency_key`
- Duplicate transfer requests with the same key are rejected
- Transaction references are globally unique

### Server-Side Validation
- Balance validation happens on the server, never the client
- Transfer limits are enforced server-side
- Account status is checked server-side before processing
- The frontend cannot manipulate balances — all mutations go through `TransferService`

## Account Restrictions

### Enforcement Layers
1. **Middleware:** `CheckAccountRestriction` blocks transfer routes for restricted accounts
2. **Service Layer:** `TransferService::validateTransfer()` re-checks account status under lock
3. **Controller:** `TransferController` applies the `restricted` middleware to transfer routes

### Restricted Accounts
- Blocked, suspended, frozen, inactive, and dormant accounts cannot transfer
- The restriction is enforced on the backend — URL manipulation cannot bypass it
- Customers see a premium modal popup with support contact options

## Data Protection

### Sensitive Data Hidden
- Passwords, PINs, OTP hashes, and SMTP passwords are in model `$hidden` arrays
- SMTP passwords are encrypted at rest using Laravel's `Crypt::encryptString()`
- SMTP passwords are never returned in API responses or views
- Exception handler's `$dontFlash` prevents sensitive fields from being exposed in errors

### PWA Cache Safety
- The service worker only caches static assets (CSS, JS, icons)
- No private data (balances, tokens, transactions) is ever cached
- All authenticated routes bypass the service worker cache
- API responses are never cached

## Authorization

### Role-Based Access Control
- Admin routes are protected by `AdminMiddleware` (checks the `admin` guard)
- Specific admin actions are gated by `RoleMiddleware` (role-based)
- The `auth` guard protects customer routes
- Email verification is required for customer dashboard access

### Admin Account Checks
- Inactive admin accounts are automatically logged out
- Admin login history and audit logs track all administrative actions

## Input Validation

- All form inputs are validated server-side using Laravel Form Requests
- CSRF tokens are required on all POST/PUT/DELETE requests
- SQL injection is prevented by using Eloquent ORM (parameterized queries)
- XSS prevention: Blade's `{{ }}` syntax auto-escapes output
- File uploads (if any) are validated for type and size

## Verification vs Settlement

- 100% verification progress means verification is complete
- It does NOT mean funds have settled
- Settlement status is tracked separately (`settlement_status` column)
- Transactions are only labelled SUCCESSFUL when settlement is confirmed
- The simulated environment clearly labels all transactions as simulated

## Security Configuration

All security settings are configurable from the admin dashboard:
- OTP expiry, max attempts, resend cooldown, length
- Password requirements (length, uppercase, lowercase, numbers, symbols)
- Login rate limiting
- Session timeout
- Transfer limits (min, max, daily)
- Two-factor authentication requirement
- Transfer PIN requirement
- Email verification requirement

## What Was NOT Verified (Limitations)

- The application has not been penetration-tested
- Rate limiting relies on Laravel's built-in throttle middleware
- The simulated settlement process does not use a real payment provider
- Two-factor authentication is scaffolded but requires additional setup for full implementation
- HTTPS must be configured at the web server level (not application code)
