| name | security-testing |
| description | Security best practices (OWASP Top 10) and testing strategies for software development. Covers secure coding, vulnerability prevention, testing pyramid, API design, and observability patterns. Use when reviewing code for security, writing tests, designing APIs, or when asking about security vulnerabilities, testing strategies, logging, or monitoring. |
Security & Testing
Security Principles
- Defense in Depth: Multiple layers of security
- Least Privilege: Minimum necessary permissions
- Fail Secure: Default to deny
- Zero Trust: Never trust, always verify
OWASP Top 10 Quick Reference
| # | Vulnerability | Prevention |
|---|
| 1 | Broken Access Control | RBAC, deny by default, audit logs |
| 2 | Cryptographic Failures | TLS, strong algorithms, key management |
| 3 | Injection | Parameterized queries, input validation |
| 4 | Insecure Design | Threat modeling, secure patterns |
| 5 | Security Misconfiguration | Hardened defaults, minimal services |
| 6 | Vulnerable Components | Dependency scanning, updates |
| 7 | Auth/Identity Failures | MFA, session management |
| 8 | Software/Data Integrity | Signed artifacts, CI/CD security |
| 9 | Logging/Monitoring Failures | Centralized logs, alerting |
| 10 | SSRF | Input validation, allowlists |
Security Checklist
Testing Pyramid
/\
/ \ E2E Tests (few)
/----\
/ \ Integration Tests
/--------\
/ \ Unit Tests (many)
/------------\
| Type | Purpose | Speed | Coverage |
|---|
| Unit | Test isolated logic | Fast | High |
| Integration | Test component interaction | Medium | Medium |
| E2E | Test full user flows | Slow | Low |
Testing Best Practices
def test_user_creation():
user_data = {"name": "Alice", "email": "alice@acme.com"}
user = create_user(user_data)
assert user.name == "Alice"
assert user.email == "alice@acme.com"
def test_empty_input():
with pytest.raises(ValueError):
create_user({})
def test_invalid_email():
with pytest.raises(ValidationError):
create_user({"name": "Bob", "email": "invalid"})
API Security
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Strict-Transport-Security: max-age=31536000; includeSubDomains
from flask_limiter import Limiter
limiter = Limiter(key_func=get_remote_address)
@app.route("/api/login")
@limiter.limit("5 per minute")
def login():
pass
Observability
Three Pillars
| Pillar | Purpose | Tools |
|---|
| Logs | Event records | ELK, CloudWatch |
| Metrics | Numerical measurements | Prometheus, DataDog |
| Traces | Request flows | Jaeger, X-Ray |
Structured Logging
logger.info("User action", extra={
"user_id": user.id,
"action": "login",
"ip": request.remote_addr,
"timestamp": datetime.utcnow().isoformat()
})
Detailed References