Files
orion/docs/development/security-rules.md
Samir Boulahtit 7a9dda282d refactor(scripts): reorganize scripts/ into seed/ and validate/ subfolders
Move 9 init/seed scripts into scripts/seed/ and 7 validation scripts
(+ validators/ subfolder) into scripts/validate/ to reduce clutter in
the root scripts/ directory. Update all references across Makefile,
CI/CD configs, pre-commit hooks, docs (~40 files), and Python imports.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:35:53 +01:00

13 KiB

Security Rules Reference

This document provides a comprehensive reference for all security rules enforced by the scripts/validate/validate_security.py validator.

Overview

The security validator identifies potential security vulnerabilities and enforces security best practices across the codebase. Rules are organized by category and severity level.

Version: 1.0 Total Rules: 60 Configuration Directory: .security-rules/

Running the Validator

Using Python Directly

# Check all files
python scripts/validate/validate_security.py

# Verbose output
python scripts/validate/validate_security.py -v

# Errors only
python scripts/validate/validate_security.py --errors-only

# JSON output (for CI/CD)
python scripts/validate/validate_security.py --json

Using the Unified Validator

# Run security checks only
python scripts/validate/validate_all.py --security

# Run all validators
python scripts/validate/validate_all.py

Severity Levels

Severity Description Exit Code Action Required
Error Critical security vulnerability 1 Must fix immediately
Warning Security concern 0 Should fix
Info Security suggestion 0 Consider implementing

Authentication Rules (SEC-001 to SEC-010)

SEC-001: No Hardcoded Credentials

Severity: Error

Credentials must never be hardcoded in source code. Use environment variables or secret management.

# Bad
api_key = "sk-1234567890abcdef"
password = "admin123"

# Good
api_key = os.environ.get("API_KEY")
password = settings.admin_password

SEC-002: JWT Expiry Enforcement

Severity: Error

All JWT tokens must have expiration claims. Access tokens should expire in 15-60 minutes.

SEC-003: Password Hashing Required

Severity: Error

Passwords must be hashed using bcrypt, argon2, or scrypt. Never store or compare passwords in plain text.

# Bad
if user.password == password:
    ...

# Good
if bcrypt.checkpw(password.encode(), user.hashed_password):
    ...

SEC-004: Session Regeneration After Auth

Severity: Warning

Session IDs should be regenerated after authentication to prevent session fixation attacks.

SEC-005: Brute Force Protection

Severity: Warning

Login endpoints should implement rate limiting or account lockout after failed attempts.

SEC-006: Secure Password Reset

Severity: Warning

Password reset tokens must be cryptographically random, expire within 1 hour, and be single-use.

SEC-007: Authentication on Sensitive Endpoints

Severity: Error

All endpoints except public ones must require authentication.

SEC-008: Token in Authorization Header

Severity: Warning

JWT tokens should be sent in Authorization header, not in URL parameters.

SEC-009: Logout Invalidates Tokens

Severity: Warning

Logout should invalidate or blacklist tokens.

SEC-010: Multi-Factor Authentication Support

Severity: Info

Consider implementing MFA for sensitive operations.


Injection Prevention Rules (SEC-011 to SEC-020)

SEC-011: No Raw SQL Queries

Severity: Error

Use SQLAlchemy ORM or parameterized queries only. Never concatenate user input into SQL strings.

# Bad
db.execute(f"SELECT * FROM users WHERE name = '{name}'")

# Good
db.query(User).filter(User.name == name)

SEC-012: No Shell Command Injection

Severity: Error

Never use shell=True with subprocess. Use subprocess with list arguments.

# Bad
subprocess.run(f"convert {filename}", shell=True)
os.system(f"rm {filename}")

# Good
subprocess.run(["convert", filename])

SEC-013: No Code Execution

Severity: Error

Never use eval() or exec() with user input.

SEC-014: Path Traversal Prevention

Severity: Error

Validate file paths to prevent directory traversal. Use secure_filename() for uploads.

# Bad
path = f"/uploads/{filename}"

# Good
from werkzeug.utils import secure_filename
path = f"/uploads/{secure_filename(filename)}"

SEC-015: XSS Prevention in Templates

Severity: Error

Use safe output methods in templates. Prefer x-text over x-html in Alpine.js.

<!-- Bad - vulnerable to XSS -->
<div x-html="userInput"></div>

<!-- Good - safe from XSS -->
<div x-text="userInput"></div>

SEC-016: LDAP Injection Prevention

Severity: Error

Escape special characters in LDAP queries.

SEC-017: XML External Entity Prevention

Severity: Error

Disable external entities when parsing XML. Use defusedxml.

# Bad
import xml.etree.ElementTree as ET
tree = ET.parse(user_file)

# Good
import defusedxml.ElementTree as ET
tree = ET.parse(user_file)

SEC-018: Template Injection Prevention

Severity: Error

Never render user input as template code.

SEC-019: SSRF Prevention

Severity: Warning

Validate URLs before making external requests. Whitelist allowed domains.

SEC-020: Deserialization Safety

Severity: Error

Never deserialize untrusted data with pickle. Use yaml.safe_load() instead of yaml.load().

# Bad
data = pickle.loads(user_data)
config = yaml.load(user_config)

# Good
config = yaml.safe_load(user_config)
data = json.loads(user_data)

Data Protection Rules (SEC-021 to SEC-030)

SEC-021: PII Logging Prevention

Severity: Error

Never log passwords, tokens, credit cards, or sensitive PII.

# Bad
logger.info(f"User login: {username}, password: {password}")

# Good
logger.info(f"User login: {username}")

SEC-022: Sensitive Data in URLs

Severity: Error

Sensitive data should not appear in URL query parameters. Use POST body or headers instead.

SEC-023: Mass Assignment Prevention

Severity: Warning

Use explicit field assignment, not **kwargs from user input.

# Bad
user = User(**request.json)

# Good
user = User(
    name=request.json.get("name"),
    email=request.json.get("email")
)

SEC-024: Error Message Information Leakage

Severity: Error

Error messages should not reveal internal details. No stack traces to users.

Severity: Error

Cookies must have Secure, HttpOnly, SameSite attributes.

SEC-026: Encryption for Sensitive Data at Rest

Severity: Info

Consider encrypting sensitive data stored in the database.

SEC-027: Data Retention Limits

Severity: Info

Implement data retention policies.

SEC-028: Response Data Filtering

Severity: Warning

API responses should not include sensitive internal fields. Use Pydantic response models.

SEC-029: File Upload Validation

Severity: Error

Validate uploaded files by extension AND content type. Limit file size.

SEC-030: Backup Encryption

Severity: Info

Database backups should be encrypted.


API Security Rules (SEC-031 to SEC-040)

SEC-031: CORS Origin Validation

Severity: Error

CORS must not allow all origins in production. Specify allowed origins explicitly.

# Bad
allow_origins=["*"]

# Good
allow_origins=["https://example.com", "https://api.example.com"]

SEC-032: Rate Limiting on Sensitive Endpoints

Severity: Warning

Auth, password reset, and payment endpoints need rate limiting.

SEC-033: Security Headers

Severity: Warning

Configure security headers like X-Content-Type-Options, X-Frame-Options, Content-Security-Policy.

SEC-034: HTTPS Enforcement

Severity: Error

External URLs must use HTTPS. HTTP is only acceptable for localhost.

SEC-035: Request Size Limits

Severity: Warning

Limit request body size to prevent DoS attacks.

SEC-036: Input Validation with Pydantic

Severity: Warning

All API inputs should be validated using Pydantic models.

SEC-037: API Versioning

Severity: Info

APIs should be versioned for security update isolation.

SEC-038: Method Restrictions

Severity: Warning

Endpoints should only allow necessary HTTP methods.

SEC-039: Authentication Bypass Prevention

Severity: Error

Ensure authentication cannot be bypassed.

SEC-040: Timeout Configuration

Severity: Warning

All external calls must have timeouts configured.


Cryptography Rules (SEC-041 to SEC-050)

SEC-041: Strong Hashing Algorithms

Severity: Error

Use bcrypt, argon2, scrypt for passwords. Use SHA-256 or stronger for general hashing. Never use MD5 or SHA1.

# Bad
import hashlib
password_hash = hashlib.md5(password.encode()).hexdigest()

# Good
import bcrypt
password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt())

SEC-042: Secure Random Generation

Severity: Error

Use the secrets module for security-sensitive randomness. Never use random module for tokens or keys.

# Bad
import random
token = ''.join(random.choices(string.ascii_letters, k=32))

# Good
import secrets
token = secrets.token_urlsafe(32)

SEC-043: No Hardcoded Encryption Keys

Severity: Error

Encryption keys must come from environment variables or secret management services.

SEC-044: Strong Encryption Algorithms

Severity: Error

Use AES-256 or ChaCha20. Never use DES, 3DES, or RC4.

SEC-045: Proper IV/Nonce Usage

Severity: Error

Encryption IVs and nonces must be randomly generated and unique per encryption.

SEC-046: TLS Version Requirements

Severity: Warning

Enforce TLS 1.2 or higher. Disable SSLv2, SSLv3, TLS 1.0, TLS 1.1.

SEC-047: Certificate Verification

Severity: Error

Always verify SSL certificates. Never disable verification in production.

# Bad
requests.get(url, verify=False)

# Good
requests.get(url, verify=True)

SEC-048: Key Derivation for Passwords

Severity: Warning

When deriving encryption keys from passwords, use PBKDF2 with 100K+ iterations, Argon2, or scrypt.

SEC-049: Secure Key Storage

Severity: Info

Encryption keys should be stored in environment variables, secret management, or HSMs.

SEC-050: Key Rotation Support

Severity: Info

Implement key rotation with multiple key versions.


Audit & Logging Rules (SEC-051 to SEC-060)

SEC-051: Authentication Event Logging

Severity: Warning

Log authentication events including successful logins, failed attempts, logouts, and password changes.

SEC-052: Admin Action Audit Trail

Severity: Warning

All admin operations should be logged with admin user ID, action performed, target resource, timestamp, and IP address.

SEC-053: Data Modification Logging

Severity: Info

Log create/update/delete on sensitive data like user accounts, roles, financial transactions, and configuration changes.

SEC-054: Security Event Logging

Severity: Warning

Log security-relevant events like authorization failures, input validation failures, rate limit triggers, and suspicious activity.

SEC-055: Log Injection Prevention

Severity: Warning

Sanitize user input before logging. Newlines and control characters can corrupt logs.

# Bad
logger.info(f"User search: {request.query}")

# Good
logger.info(f"User search: {request.query!r}")  # repr escapes

SEC-056: Centralized Logging

Severity: Info

Use centralized logging for correlation across services, tamper-evident storage, and alerting.

SEC-057: Log Level Appropriateness

Severity: Info

Use appropriate log levels: ERROR for security failures, WARNING for suspicious activity, INFO for successful events.

SEC-058: Structured Logging Format

Severity: Info

Use structured logging (JSON) for easy parsing and searchability.

SEC-059: Audit Log Integrity

Severity: Info

Protect audit logs from tampering with append-only storage and cryptographic chaining.

SEC-060: Privacy-Aware Logging

Severity: Warning

Comply with data protection regulations. No PII in logs without consent.


Configuration

All rules are defined in .security-rules/ directory:

.security-rules/
├── _main.yaml          # Main configuration
├── authentication.yaml # SEC-001 to SEC-010
├── injection.yaml      # SEC-011 to SEC-020
├── data_protection.yaml # SEC-021 to SEC-030
├── api_security.yaml   # SEC-031 to SEC-040
├── cryptography.yaml   # SEC-041 to SEC-050
└── audit.yaml          # SEC-051 to SEC-060

Suppressing Rules

Use noqa comments to suppress specific rules:

# noqa: SEC-001 - This is a test file with intentional test credentials
test_password = "test123"

Summary Statistics

Category Rules Errors Warnings Info
Authentication 10 4 5 1
Injection Prevention 10 9 1 0
Data Protection 10 4 3 3
API Security 10 4 5 1
Cryptography 10 6 2 2
Audit & Logging 10 0 5 5
Total 60 27 21 12

Last Updated: 2025-12-21 Version: 1.0