Files
xamxam/docs/SECURITY.md
2026-02-05 17:37:07 +01:00

4.8 KiB

Security Improvements

Changes Made

1. Critical Vulnerability Fixes

Path Traversal in thanks.php (CRITICAL)

  • Before: User could access ANY file on the system via ?file=../../../../etc/passwd
  • After:
    • Validates file path using realpath() to resolve symlinks
    • Ensures file is within allowed data/yaml/ directory
    • Verifies file extension is .yaml
    • Proper error handling without exposing system paths

CSRF Protection

  • Before: Form could be submitted from any website
  • After:
    • Session-based CSRF tokens generated for each form load
    • Token validated on submission using timing-safe comparison (hash_equals())
    • Token cleared after successful submission

2. Input Validation & Sanitization

Deprecated Functions Replaced

  • Before: Used FILTER_SANITIZE_STRING (deprecated in PHP 8.1+)
  • After: Custom sanitize_string() function using htmlspecialchars() and strip_tags()

Enhanced Validation

  • Required fields properly validated with custom validate_required() function
  • Email validation using FILTER_VALIDATE_EMAIL
  • URL validation using FILTER_VALIDATE_URL
  • Year validation with reasonable range checking (2000 to current year + 1)
  • Comprehensive error messages for validation failures

3. File Upload Security

Random Filenames

  • Before: Used original or predictable filenames (author + timestamp)
  • After:
    • Generates cryptographically secure random filenames using random_bytes()
    • Prevents file overwrites
    • Prevents path traversal attacks via malicious filenames
    • Stores mapping to original filename for reference

Enhanced File Validation

  • MIME type checking using finfo
  • File extension whitelist
  • File size limits (50MB max)
  • Proper error handling for upload errors
  • Cover image restricted to JPEG/PNG only

4. Bug Fixes

  • Fixed undefined variable $memoireFolder (used before definition)
  • Fixed undefined variable $resume (should be $description)
  • Fixed variable ordering (generate $uniqueId before using it)
  • Added proper __DIR__ prefix for absolute paths

5. Error Handling

  • Try-catch block wraps entire form processing
  • Detailed error logging (not exposed to users)
  • User-friendly error messages
  • Proper exit after redirect
  • No system path exposure in error messages

Nginx Configuration Notes

Since this form is behind nginx password authentication, additional security layers:

location /formulaire {
    auth_basic "Restricted Access";
    auth_basic_user_file /etc/nginx/.htpasswd;

    # Rate limiting
    limit_req zone=form_limit burst=5 nodelay;

    # File upload size
    client_max_body_size 100M;

    # Timeout settings
    client_body_timeout 60s;

    # Prevent access to sensitive files
    location ~ /\. {
        deny all;
    }

    location ~ /(vendor|composer\.(json|lock)|error\.log)$ {
        deny all;
    }
}

Additional Recommendations

1. Database Migration (In Progress)

Moving to SQLite will provide:

  • Structured data storage
  • Better query capabilities
  • Easier data management
  • Prepared statements for SQL injection prevention

2. File Storage

  • Consider moving uploaded files outside web root
  • Serve files through PHP script with access control
  • Implement file scanning for malware if possible

3. Monitoring

  • Regularly review error.log for suspicious activity
  • Monitor file upload patterns
  • Set up alerts for failed CSRF validations

4. Backup Strategy

  • Regular backups of data/ directory
  • Version control for code changes
  • Test restore procedures

5. PHP Configuration

Ensure these settings in php.ini:

file_uploads = On
upload_max_filesize = 100M
post_max_size = 100M
max_execution_time = 60
max_input_time = 60
memory_limit = 256M

# Security
expose_php = Off
allow_url_fopen = Off
allow_url_include = Off
display_errors = Off
log_errors = On

Testing Checklist

  • Form submission with all fields
  • Form submission with minimal required fields
  • Invalid email format
  • Invalid URL format
  • Invalid year
  • File upload (various formats)
  • Large file upload (>50MB, should fail)
  • Invalid file types
  • Multiple file uploads
  • Cover image upload
  • CSRF token validation (try submitting with wrong token)
  • Path traversal attempt in thanks.php
  • Error handling for missing directories

Known Limitations

  1. No atomic transactions: File operations and YAML save not atomic
  2. No rollback: Failed submissions may leave partial files
  3. Session storage: CSRF tokens in default PHP session (consider database sessions)
  4. No upload progress: Large files have no progress indicator
  5. No duplicate detection: Same submission can be made multiple times

These limitations will be addressed in the SQLite migration.