# BankPro Security Quick Reference Guide

## 🔒 For Developers

### When Querying Database - ALWAYS USE PARAMETERIZED QUERIES

❌ **WRONG** (Vulnerable to SQL Injection):
```php
$sql = "SELECT * FROM users WHERE id = '$id'";
$stmt = $conn->prepare($sql);
$stmt->execute();
```

✅ **CORRECT** (Safe):
```php
$sql = "SELECT * FROM users WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->execute([':id' => $id]);
```

### When Accepting User Input - ALWAYS VALIDATE

❌ **WRONG**:
```php
$email = $_POST['email'];
$age = $_POST['age'];
```

✅ **CORRECT**:
```php
$email = SecurityUtils::validateInput($_POST['email'], 'email');
$age = SecurityUtils::validateInput($_POST['age'], 'integer');
```

### When Creating Forms - ALWAYS ADD CSRF TOKENS

❌ **WRONG**:
```html
<form method="POST">
    <input name="email" type="email">
    <button type="submit">Submit</button>
</form>
```

✅ **CORRECT**:
```html
<form method="POST">
    <?php echo SecurityUtils::getCSRFField(); ?>
    <input name="email" type="email">
    <button type="submit">Submit</button>
</form>
```

### When Verifying POST Requests - ALWAYS CHECK CSRF TOKEN

❌ **WRONG**:
```php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Process form
}
```

✅ **CORRECT**:
```php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!SecurityUtils::verifyCSRFToken($_POST['csrf_token'] ?? '')) {
        die('CSRF validation failed');
    }
    // Process form
}
```

### When Protecting Pages - ALWAYS CHECK SESSION

❌ **WRONG** (No checks):
```php
<?php
// Code that should be protected
?>
```

✅ **CORRECT** (With authentication):
```php
<?php
if (!isset($_SESSION['user_id'])) {
    header('Location: login.php');
    exit;
}

// Only authenticated users reach here
?>
```

### When Displaying User Data - ALWAYS SANITIZE

❌ **WRONG** (XSS Vulnerability):
```php
echo $user_input;
echo $_POST['name'];
```

✅ **CORRECT** (Safe):
```php
echo SecurityUtils::sanitizeOutput($user_input);
echo sanitize($_POST['name']);
```

---

## 🔧 For System Administrators

### Pre-Deployment Checklist

- [ ] Update `.env` with real database credentials
- [ ] Set HTTPS/SSL certificate
- [ ] Enable `display_errors = Off` in php.ini
- [ ] Set proper file permissions (750 for logs, 644 for PHP)
- [ ] Create `/include/security_logs/` directory
- [ ] Test all authentication flows
- [ ] Verify CSRF tokens work
- [ ] Check database connection is secure
- [ ] Set up monitoring for security logs
- [ ] Perform penetration testing

### Daily Tasks

- Review `/include/security_logs/` for suspicious activity
- Check for failed login attempts
- Verify backups completed successfully

### Weekly Tasks

- Review authentication logs
- Check for unauthorized access attempts
- Update any security policies if needed

### Monthly Tasks

- Full security audit
- Update dependencies if available
- Review and test disaster recovery plan

---

## 🚨 If Something Goes Wrong

### Database Connection Fails
```
Check /include/security_logs/ for error details
Verify credentials in .env file
Check database server is running
Ensure PHP has PDO extension
```

### CSRF Token Errors
```
Ensure session is started at page top
Check browser cookies are enabled
Verify $_SESSION is initialized
Clear browser cache and try again
```

### Session Expires Too Quickly
```
Check LAST_ACTIVITY is being updated
Verify SESSION_TIMEOUT in .env (default: 1800 seconds)
Check server time is correct
```

### Password Reset Not Working
```
Verify SMTP/email configuration
Check rate limiting isn't blocking (3 attempts/5 min)
Verify database has reset token fields
Check token format is valid
```

---

## 📝 Common Tasks

### Create New Admin Page
```php
<?php
// ALWAYS start with these checks
if (!isset($_SESSION['user_id']) || $_SESSION['user_role'] !== 'admin') {
    header('Location: login.php');
    exit('Unauthorized');
}

// ALWAYS validate input
$id = SecurityUtils::validateInput($_GET['id'] ?? '', 'integer');
if (!$id) die('Invalid input');

// ALWAYS use parameterized queries
$sql = "SELECT * FROM table WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->execute([':id' => $id]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);

// ALWAYS verify ownership if needed
if ($result['user_id'] != $_SESSION['user_id']) {
    die('Access denied');
}

// ALWAYS sanitize output
echo SecurityUtils::sanitizeOutput($result['name']);
?>
```

### Create New Form
```html
<form method="POST" action="process.php">
    <!-- ALWAYS add CSRF token -->
    <?php echo SecurityUtils::getCSRFField(); ?>
    
    <!-- Form fields -->
    <input type="email" name="email" required>
    <input type="password" name="password" required>
    
    <button type="submit">Submit</button>
</form>
```

### Process Form Submission
```php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // ALWAYS verify CSRF
    if (!SecurityUtils::verifyCSRFToken($_POST['csrf_token'] ?? '')) {
        die('CSRF validation failed');
    }
    
    // ALWAYS validate input
    $email = SecurityUtils::validateInput($_POST['email'] ?? '', 'email');
    $password = $_POST['password'] ?? '';
    
    if (!$email || !$password) {
        echo "Invalid input";
        exit;
    }
    
    // ALWAYS use parameterized queries
    $sql = "SELECT * FROM users WHERE email = :email";
    $stmt = $conn->prepare($sql);
    $stmt->execute([':email' => $email]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if ($user && SecurityUtils::verifyPassword($password, $user['password'])) {
        $_SESSION['user_id'] = $user['id'];
        header('Location: dashboard.php');
    } else {
        SecurityUtils::logSecurityEvent('LOGIN_FAILURE', ['email' => $email]);
        echo "Invalid credentials";
    }
}
?>
```

---

## 🔐 Password Policy Reminder

Users must create passwords with:
- ✓ 8+ characters
- ✓ 1 uppercase letter (A-Z)
- ✓ 1 lowercase letter (a-z)
- ✓ 1 number (0-9)
- ✓ 1 special character (!@#$%^&*)

**Example**: `SecurePass#2024`

---

## 📊 SecurityUtils Quick Reference

### Most Common Methods

```php
// Input Validation
SecurityUtils::validateInput($value, 'email')       // Validate email
SecurityUtils::validateInput($value, 'phone')       // Validate phone
SecurityUtils::validateInput($value, 'numeric')     // Validate number
SecurityUtils::validateInput($value, 'integer')     // Validate integer
SecurityUtils::validateInput($value, 'string', 100) // Validate string

// CSRF Protection
SecurityUtils::generateCSRFToken()    // Generate token
SecurityUtils::verifyCSRFToken($token) // Verify token
SecurityUtils::getCSRFField()         // Get hidden form field

// Password Security
SecurityUtils::hashPassword($pass)     // Hash password
SecurityUtils::verifyPassword($pass, $hash) // Verify password
SecurityUtils::validatePassword($pass) // Check password strength

// Output Safety
SecurityUtils::sanitizeOutput($text)  // Safe output in HTML

// Security Logging
SecurityUtils::logSecurityEvent('EVENT_NAME', ['data' => 'value'])

// Rate Limiting
SecurityUtils::isRateLimited('action', 5, 300) // Check if rate limited

// Email Validation
SecurityUtils::validateEmail($email)  // Validate email format

// Phone Validation
SecurityUtils::validatePhone($phone)  // Validate phone format
```

---

## ⚠️ NEVER DO THESE

1. ❌ Never concatenate user input directly into SQL
   ```php
   // WRONG: $sql = "WHERE id = '$id'";
   ```

2. ❌ Never skip CSRF tokens on POST requests
   ```php
   // WRONG: Process POST without checking token
   ```

3. ❌ Never trust `$_GET` or `$_POST` directly
   ```php
   // WRONG: $email = $_GET['email'];
   ```

4. ❌ Never display user input without sanitizing
   ```php
   // WRONG: echo $_POST['name'];
   ```

5. ❌ Never store passwords in plain text
   ```php
   // WRONG: $password = $_POST['password'];
   ```

6. ❌ Never expose database errors to users
   ```php
   // WRONG: catch(Exception $e) { echo $e->getMessage(); }
   ```

7. ❌ Never hardcode credentials in source code
   ```php
   // WRONG: $password = "mydbpass123";
   ```

8. ❌ Never skip session validation on protected pages
   ```php
   // WRONG: Direct access without session check
   ```

---

## 🆘 Emergency Contacts

**Security Issue?** Check `SECURITY.md` first  
**Can't Deploy?** Review `.env.example` and deployment checklist  
**Database Error?** Check logs at `/include/security_logs/`

---

**Last Updated**: December 29, 2025  
**Version**: 2.0
