Skip to content

Security Testing

This document outlines security testing practices and procedures for the tracker REST API system.

Overview

Security testing is a critical component of the development lifecycle, ensuring that the application is protected against common vulnerabilities and attack vectors.

Authentication & Authorization Testing

JWT Token Security

Token Validation Tests

def test_jwt_token_validation():
    """Test JWT token validation with various scenarios"""
    # Valid token test
    valid_token = create_access_token(user_id=1)
    assert validate_token(valid_token) is not None

    # Expired token test
    expired_token = create_expired_token(user_id=1)
    with pytest.raises(TokenExpiredError):
        validate_token(expired_token)

    # Invalid signature test
    invalid_token = "invalid.jwt.token"
    with pytest.raises(InvalidTokenError):
        validate_token(invalid_token)

Token Refresh Security

def test_refresh_token_security():
    """Test refresh token security mechanisms"""
    # Test refresh token rotation
    refresh_token = create_refresh_token(user_id=1)
    new_tokens = refresh_access_token(refresh_token)

    # Old refresh token should be invalidated
    with pytest.raises(InvalidTokenError):
        refresh_access_token(refresh_token)

Role-Based Access Control (RBAC)

def test_admin_only_endpoints():
    """Test that admin-only endpoints reject non-admin users"""
    user_token = create_access_token(user_id=1, role="user")
    admin_token = create_access_token(user_id=2, role="admin")

    # User should be denied access
    response = client.get("/api/v1/admin/users", headers={"Authorization": f"Bearer {user_token}"})
    assert response.status_code == 403

    # Admin should have access
    response = client.get("/api/v1/admin/users", headers={"Authorization": f"Bearer {admin_token}"})
    assert response.status_code == 200

Input Validation & Sanitization

SQL Injection Prevention

def test_sql_injection_prevention():
    """Test that SQL injection attempts are prevented"""
    malicious_input = "'; DROP TABLE users; --"

    response = client.get(f"/api/v1/users?search={malicious_input}")
    assert response.status_code in [200, 400]  # Should not cause server error

    # Verify database integrity
    users_count = db.query(User).count()
    assert users_count > 0  # Table should still exist

XSS Prevention

def test_xss_prevention():
    """Test that XSS attempts are sanitized"""
    xss_payload = "<script>alert('xss')</script>"

    response = client.post("/api/v1/trackers", json={
        "name": xss_payload,
        "description": "Test tracker"
    })

    if response.status_code == 201:
        tracker = response.json()
        assert "<script>" not in tracker["name"]
        assert "&lt;script&gt;" in tracker["name"]  # Should be escaped

API Security Testing

Rate Limiting

def test_rate_limiting():
    """Test API rate limiting functionality"""
    # Make multiple requests rapidly
    responses = []
    for _ in range(100):
        response = client.get("/api/v1/trackers")
        responses.append(response.status_code)

    # Should eventually hit rate limit
    assert 429 in responses  # Too Many Requests

CORS Security

def test_cors_security():
    """Test CORS configuration security"""
    # Test allowed origin
    response = client.options("/api/v1/trackers", headers={
        "Origin": "https://tracker-admin.glimpse.technology",
        "Access-Control-Request-Method": "GET"
    })
    assert response.status_code == 200
    assert "Access-Control-Allow-Origin" in response.headers

    # Test disallowed origin
    response = client.options("/api/v1/trackers", headers={
        "Origin": "https://malicious-site.com",
        "Access-Control-Request-Method": "GET"
    })
    assert "Access-Control-Allow-Origin" not in response.headers

Data Protection Testing

Sensitive Data Exposure

def test_password_not_exposed():
    """Test that passwords are never exposed in API responses"""
    response = client.get("/api/v1/users/1")
    user_data = response.json()

    assert "password" not in user_data
    assert "password_hash" not in user_data

Data Encryption

def test_sensitive_data_encryption():
    """Test that sensitive data is encrypted at rest"""
    user = create_test_user(password="plaintext_password")

    # Password should be hashed, not stored in plaintext
    assert user.password_hash != "plaintext_password"
    assert len(user.password_hash) > 50  # Bcrypt hash length
    assert user.password_hash.startswith("$2b$")  # Bcrypt prefix

Infrastructure Security Testing

Database Security

def test_database_connection_security():
    """Test database connection security"""
    # Test that database connections use SSL in production
    if settings.ENVIRONMENT == "production":
        assert "sslmode=require" in settings.SQLALCHEMY_DATABASE_URI

Redis/Dragonfly Security

def test_redis_authentication():
    """Test Redis/Dragonfly authentication"""
    # Test that Redis requires authentication
    if settings.REDIS_PASSWORD:
        # Should fail without password
        with pytest.raises(ConnectionError):
            redis_client = Redis(host=settings.REDIS_HOST, port=settings.REDIS_PORT)
            redis_client.ping()

        # Should succeed with password
        authenticated_client = Redis(
            host=settings.REDIS_HOST,
            port=settings.REDIS_PORT,
            password=settings.REDIS_PASSWORD
        )
        assert authenticated_client.ping() is True

Security Headers Testing

def test_security_headers():
    """Test that proper security headers are set"""
    response = client.get("/api/v1/health")

    # Check for security headers
    assert "X-Content-Type-Options" in response.headers
    assert response.headers["X-Content-Type-Options"] == "nosniff"

    assert "X-Frame-Options" in response.headers
    assert response.headers["X-Frame-Options"] == "DENY"

    assert "X-XSS-Protection" in response.headers
    assert response.headers["X-XSS-Protection"] == "1; mode=block"

Vulnerability Scanning

Automated Security Scanning

# Run security vulnerability scan
bandit -r app/ -f json -o security-report.json

# Check for known vulnerabilities in dependencies
safety check --json --output vulnerability-report.json

# OWASP ZAP automated scan
zap-baseline.py -t http://localhost:8000 -J zap-report.json

Manual Security Testing

Authentication Bypass Attempts

  1. Token Manipulation
  2. Modify JWT payload
  3. Change user ID in token
  4. Use tokens from different users

  5. Session Management

  6. Test session fixation
  7. Test concurrent sessions
  8. Test session timeout

Authorization Testing

  1. Horizontal Privilege Escalation
  2. Access other users' data
  3. Modify other users' resources

  4. Vertical Privilege Escalation

  5. Access admin functions as regular user
  6. Bypass role restrictions

Security Test Automation

CI/CD Integration

# .github/workflows/security.yml
name: Security Tests

on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Run Bandit Security Scan
        run: |
          pip install bandit
          bandit -r app/ -f json -o bandit-report.json

      - name: Run Safety Check
        run: |
          pip install safety
          safety check --json --output safety-report.json

      - name: Upload Security Reports
        uses: actions/upload-artifact@v2
        with:
          name: security-reports
          path: |
            bandit-report.json
            safety-report.json

Security Testing Checklist

Pre-deployment Security Tests

  • Authentication mechanisms tested
  • Authorization controls verified
  • Input validation confirmed
  • SQL injection prevention tested
  • XSS prevention verified
  • CSRF protection enabled
  • Rate limiting functional
  • Security headers present
  • Sensitive data protection verified
  • Error handling secure (no information leakage)

Production Security Monitoring

  • Security logging enabled
  • Intrusion detection configured
  • Vulnerability scanning scheduled
  • Security incident response plan ready
  • Regular security audits planned

Security Testing Tools

Static Analysis

  • Bandit - Python security linter
  • Safety - Dependency vulnerability scanner
  • SonarQube - Code quality and security analysis

Dynamic Analysis

  • OWASP ZAP - Web application security scanner
  • Burp Suite - Web vulnerability scanner
  • Postman - API security testing

Infrastructure Security

  • Nmap - Network security scanner
  • Docker Bench - Docker security best practices
  • Trivy - Container vulnerability scanner

Reporting Security Issues

Internal Reporting

  1. Create security issue in internal tracker
  2. Mark as confidential/private
  3. Assign to security team
  4. Follow responsible disclosure timeline

External Reporting

  1. Contact security team via secure channel
  2. Provide detailed vulnerability description
  3. Include proof of concept (if safe)
  4. Allow reasonable time for fix before disclosure

This security testing framework ensures comprehensive coverage of potential vulnerabilities and maintains the security posture of the tracker REST API system.