Security Analysis Skills
Purpose: Universal security knowledge framework for threat modeling, vulnerability assessment, risk scoring, and secure coding. Designed to be applied by ALL development agents (security-agent, developer-agent, devops-agent, rust-expert, python-ml-expert) to ensure security-first development practices.
Created: 2025-11-08
When to Use Security Analysis Skills
✅ Use this skill when:
-
Conducting threat modeling for new features/systems
-
Performing security code review
-
Assessing vulnerabilities and scoring risk
-
Implementing authentication/authorization
-
Handling sensitive data (PII, credentials, payment info)
-
Deploying to production (security checklist)
-
Investigating security incidents
-
Designing secure architectures
❌ NOT required for:
-
Pure documentation tasks with no code
-
Read-only data analysis with public data
-
Internal tools with no network exposure (but still recommended)
Target Audience: Security specialists AND general developers integrating security into daily work
Core Security Frameworks
- STRIDE Threat Modeling
Purpose: Systematic identification of threats by category
STRIDE Categories:
S - Spoofing Identity
-
Definition: Attacker pretends to be someone else
-
Examples: Stolen credentials, session hijacking, JWT forgery
-
Mitigations: MFA, certificate pinning, signed tokens
T - Tampering with Data
-
Definition: Unauthorized modification of data
-
Examples: Man-in-the-middle, SQL injection, XSS
-
Mitigations: HTTPS/TLS, input validation, integrity checks (HMAC)
R - Repudiation
-
Definition: User denies performing an action
-
Examples: Missing audit logs, unsigned transactions
-
Mitigations: Audit logging, digital signatures, timestamps
I - Information Disclosure
-
Definition: Exposure of confidential information
-
Examples: Directory traversal, verbose errors, unencrypted data
-
Mitigations: Encryption at rest/transit, least privilege, sanitized errors
D - Denial of Service
-
Definition: Service becomes unavailable
-
Examples: Resource exhaustion, infinite loops, DDoS attacks
-
Mitigations: Rate limiting, resource quotas, circuit breakers
E - Elevation of Privilege
-
Definition: Unauthorized permission escalation
-
Examples: Privilege escalation bugs, insecure defaults
-
Mitigations: Principle of least privilege, role-based access control
How to Apply STRIDE:
-
For each component/feature, ask: "What STRIDE threats apply?"
-
Fill out threat modeling worksheet (see reference section)
-
Prioritize threats by impact × likelihood
-
Document mitigations for each identified threat
- OWASP Top 10 (2021 Edition)
Purpose: Most critical web application security risks
A01: Broken Access Control
Description: Users can act outside their intended permissions
Examples:
-
Direct object references: /user/1234/profile → change to /user/5678/profile
-
Missing function-level access control: Regular user accesses /admin/delete
-
IDOR (Insecure Direct Object Reference): Manipulating IDs in URLs/APIs
Secure Patterns:
❌ VULNERABLE: No ownership check
@app.route('/document/<doc_id>') def get_document(doc_id): doc = Document.query.get(doc_id) return render_template('doc.html', doc=doc)
✅ SECURE: Verify ownership
@app.route('/document/<doc_id>') @login_required def get_document(doc_id): doc = Document.query.get(doc_id) if not doc or doc.owner_id != current_user.id: abort(403) # Forbidden return render_template('doc.html', doc=doc)
Checklist:
-
All endpoints verify user permissions
-
Object ownership validated before access
-
Default deny (whitelist not blacklist)
-
Disable directory listing
-
Invalidate sessions on logout
A02: Cryptographic Failures
Description: Sensitive data exposed due to weak/missing encryption
Examples:
-
Storing passwords in plaintext
-
Using weak algorithms (MD5, SHA1 for passwords)
-
Transmitting sensitive data over HTTP
-
Hardcoded encryption keys
Secure Patterns:
❌ VULNERABLE: Weak hashing
import hashlib password_hash = hashlib.md5(password.encode()).hexdigest()
✅ SECURE: Proper password hashing
import bcrypt password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
❌ VULNERABLE: Hardcoded key
AES_KEY = "mysecretkey12345"
✅ SECURE: Environment variable
import os AES_KEY = os.environ['AES_ENCRYPTION_KEY']
Checklist:
-
Use TLS 1.2+ for all data in transit
-
Hash passwords with bcrypt/Argon2 (not MD5/SHA1)
-
Never hardcode secrets (use env vars/vaults)
-
Encrypt sensitive data at rest
-
Use strong key generation (crypto.randomBytes, secrets module)
A03: Injection
Description: Untrusted data sent to interpreter as command/query
Types: SQL Injection, NoSQL Injection, Command Injection, LDAP Injection, XPath Injection
SQL Injection Example:
❌ VULNERABLE: String concatenation
username = request.form['username'] query = f"SELECT * FROM users WHERE username = '{username}'"
Attacker inputs: ' OR '1'='1' --
Result: SELECT * FROM users WHERE username = '' OR '1'='1' --'
✅ SECURE: Parameterized query
username = request.form['username'] query = "SELECT * FROM users WHERE username = ?" cursor.execute(query, (username,))
Command Injection Example:
❌ VULNERABLE: Shell injection
filename = request.form['filename'] os.system(f"cat {filename}") # Attacker: "; rm -rf /"
✅ SECURE: Avoid shell, use safe APIs
import subprocess subprocess.run(['cat', filename], check=True, capture_output=True)
Checklist:
-
Use parameterized queries (prepared statements)
-
Avoid dynamic query construction with string concat
-
Validate input against whitelist (not blacklist)
-
Escape special characters for context
-
Use ORM frameworks (with parameterization)
A04: Insecure Design
Description: Missing or ineffective security controls in design phase
Examples:
-
No rate limiting on login (brute force)
-
Password reset without identity verification
-
Predictable session IDs
-
No transaction verification (CSRF)
Secure Design Patterns:
-
Defense in depth (multiple security layers)
-
Principle of least privilege
-
Fail securely (default deny)
-
Separation of duties
-
Security by default (opt-in for risky features)
Checklist:
-
Threat model created during design
-
Rate limiting on authentication/sensitive endpoints
-
CSRF tokens for state-changing operations
-
Cryptographically secure random IDs (not sequential)
-
Security requirements defined before coding
A05: Security Misconfiguration
Description: Insecure default configurations, incomplete setups, exposed admin interfaces
Examples:
-
Default admin credentials (admin/admin)
-
Verbose error messages revealing stack traces
-
Unnecessary features enabled (debug mode in production)
-
Missing security headers
-
Outdated software versions
Secure Configuration:
❌ VULNERABLE: Debug mode in production
app = Flask(name) app.config['DEBUG'] = True # Exposes code, allows RCE
✅ SECURE: Environment-based config
import os app.config['DEBUG'] = os.environ.get('FLASK_ENV') == 'development'
✅ SECURE: Security headers
@app.after_request def set_security_headers(response): response.headers['X-Content-Type-Options'] = 'nosniff' response.headers['X-Frame-Options'] = 'DENY' response.headers['X-XSS-Protection'] = '1; mode=block' response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains' return response
Checklist:
-
Change all default credentials
-
Disable debug mode in production
-
Remove unnecessary features/services
-
Configure security headers (CSP, HSTS, X-Frame-Options)
-
Regular security updates applied
A06: Vulnerable and Outdated Components
Description: Using libraries/frameworks with known vulnerabilities
Examples:
-
Unmaintained dependencies (no security patches)
-
Using deprecated crypto libraries
-
Outdated frameworks (old Rails, Django, Spring)
Secure Practices:
Check for vulnerabilities
npm audit # Node.js pip-audit # Python bundle audit # Ruby cargo audit # Rust
Update dependencies
npm update pip install --upgrade -r requirements.txt cargo update
Checklist:
-
Dependency scanning in CI/CD
-
Regular updates (monthly for deps, immediate for critical CVEs)
-
Remove unused dependencies
-
Pin versions (avoid wildcards like *)
-
Monitor CVE databases (NVD, GitHub Security Advisories)
A07: Identification and Authentication Failures
Description: Weak authentication allows attackers to compromise accounts
Examples:
-
Weak password policy (no complexity requirements)
-
Session fixation
-
Missing MFA
-
Predictable session tokens
-
No account lockout on brute force
Secure Authentication:
Password Policy
MIN_LENGTH = 12 REQUIRE_UPPERCASE = True REQUIRE_DIGIT = True REQUIRE_SPECIAL = True
Session Management
from secrets import token_urlsafe session_id = token_urlsafe(32) # Cryptographically secure
Rate Limiting
from flask_limiter import Limiter limiter = Limiter(app, default_limits=["5 per minute"])
@app.route('/login', methods=['POST']) @limiter.limit("5 per minute") def login(): # Login logic with rate limiting pass
Checklist:
-
Strong password policy enforced
-
MFA available (TOTP, WebAuthn)
-
Account lockout after N failed attempts
-
Session timeout configured
-
Secure session cookie flags (HttpOnly, Secure, SameSite)
A08: Software and Data Integrity Failures
Description: Code/infrastructure relies on untrusted sources without integrity verification
Examples:
-
Downloading dependencies without checksum verification
-
Auto-update without signature validation
-
Insecure CI/CD pipeline
-
Deserialization of untrusted data
Secure Practices:
❌ VULNERABLE: Deserialize untrusted data
import pickle data = pickle.loads(request.data) # RCE risk!
✅ SECURE: Use safe serialization
import json data = json.loads(request.data) # Only deserializes JSON primitives
Verify package integrity
pip install --require-hashes -r requirements.txt
Checklist:
-
Use signed commits (GPG)
-
Verify package checksums/signatures
-
Secure CI/CD pipeline (no secrets in logs)
-
Avoid insecure deserialization (pickle, YAML.unsafe_load)
-
Implement software bill of materials (SBOM)
A09: Security Logging and Monitoring Failures
Description: Insufficient logging prevents detection of breaches
Examples:
-
No logging of authentication events
-
Logs not reviewed/alerted
-
Sensitive data in logs (passwords, tokens)
-
No integrity protection (logs can be tampered)
Secure Logging:
import logging import hashlib
✅ SECURE: Log security events
logger = logging.getLogger('security')
@app.route('/login', methods=['POST']) def login(): username = request.form['username'] password = request.form['password']
if authenticate(username, password):
logger.info(f"Successful login: user={username}, ip={request.remote_addr}")
return "Success"
else:
logger.warning(f"Failed login: user={username}, ip={request.remote_addr}")
return "Invalid credentials", 401
❌ VULNERABLE: Log sensitive data
logger.info(f"User {username} logged in with password {password}") # DON'T!
✅ SECURE: Redact sensitive data
logger.info(f"User {username} logged in")
Checklist:
-
Log all authentication events (success/failure)
-
Log authorization failures
-
Log input validation failures
-
Never log passwords, tokens, PII
-
Centralized logging with alerting
-
Tamper-evident logs (write-once storage)
A10: Server-Side Request Forgery (SSRF)
Description: Web app fetches remote resource without validating user-supplied URL
Examples:
-
Fetching arbitrary URLs from user input
-
Accessing internal services (localhost, 169.254.169.254)
-
Port scanning via web app
SSRF Example:
❌ VULNERABLE: Fetch arbitrary URL
import requests url = request.args.get('url') response = requests.get(url) # Attacker: http://localhost:6379/
✅ SECURE: Whitelist domains
ALLOWED_DOMAINS = ['api.example.com', 'cdn.example.com'] from urllib.parse import urlparse
url = request.args.get('url') parsed = urlparse(url) if parsed.hostname not in ALLOWED_DOMAINS: abort(400, "Invalid domain") response = requests.get(url)
Checklist:
-
Whitelist allowed domains/IPs
-
Block private IP ranges (10.0.0.0/8, 192.168.0.0/16, 127.0.0.1)
-
Disable URL redirects or validate redirect targets
-
Use network segmentation (no internet access from app servers)
- Risk Scoring (CVSS v3.1)
Purpose: Quantify vulnerability severity for prioritization
CVSS Formula: Base Score (0-10) = f(Impact, Exploitability)
Severity Levels:
-
Critical (9.0-10.0): Immediate action required, exploit in the wild
-
High (7.0-8.9): High priority, exploitable remotely
-
Medium (4.0-6.9): Medium priority, requires user interaction
-
Low (0.1-3.9): Low priority, limited impact
Impact Scoring:
-
Confidentiality Impact: None / Low / High
-
Integrity Impact: None / Low / High
-
Availability Impact: None / Low / High
Exploitability Scoring:
-
Attack Vector: Network (highest) / Adjacent / Local / Physical (lowest)
-
Attack Complexity: Low (easy) / High (difficult)
-
Privileges Required: None (highest) / Low / High (lowest)
-
User Interaction: None (highest) / Required (lower)
Quick Risk Matrix (Impact × Likelihood):
Impact / Likelihood Low Medium High
High Med High Crit
Medium Low Med High
Low Low Low Med
Example Scoring:
Vulnerability: SQL Injection in login endpoint
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
- Attack Vector: Network (AV:N) - remotely exploitable
- Attack Complexity: Low (AC:L) - easy to exploit
- Privileges Required: None (PR:N) - unauthenticated
- User Interaction: None (UI:N) - no user action needed
- Confidentiality: High (C:H) - all user data exposed
- Integrity: High (I:H) - data can be modified
- Availability: None (A:N) - no DoS
Base Score: 9.1 (CRITICAL)
Checklist:
-
Score all identified vulnerabilities using CVSS
-
Prioritize remediation: Critical → High → Medium → Low
-
Define risk acceptance criteria (e.g., no Critical in production)
-
Track vulnerabilities in registry (Jira, GitHub Security)
- Security Code Review Patterns
Purpose: Identify common vulnerabilities during code review
Input Validation
Rule: Never trust user input
Patterns:
Whitelist validation (preferred)
ALLOWED_EXTENSIONS = {'.jpg', '.png', '.pdf'} file_ext = os.path.splitext(filename)[1].lower() if file_ext not in ALLOWED_EXTENSIONS: raise ValueError("Invalid file type")
Regex validation
import re EMAIL_PATTERN = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$') if not EMAIL_PATTERN.match(email): raise ValueError("Invalid email")
Type validation
from pydantic import BaseModel, validator
class UserInput(BaseModel): age: int email: str
@validator('age')
def age_must_be_positive(cls, v):
if v < 0 or v > 150:
raise ValueError('Invalid age')
return v
Authentication & Authorization
Rule: Verify identity and permissions at every access point
Patterns:
Decorator-based authorization
from functools import wraps
def require_role(role): def decorator(f): @wraps(f) def decorated_function(*args, **kwargs): if not current_user.has_role(role): abort(403) return f(*args, **kwargs) return decorated_function return decorator
@app.route('/admin/users') @require_role('admin') def list_users(): return render_template('users.html', users=User.query.all())
Resource ownership check
def check_ownership(resource, user): if resource.owner_id != user.id and not user.is_admin(): abort(403, "Not authorized to access this resource")
Cryptography Best Practices
Rules:
-
Don't roll your own crypto
-
Use standard libraries (cryptography, libsodium)
-
Use authenticated encryption (AES-GCM, ChaCha20-Poly1305)
Patterns:
✅ SECURE: Modern authenticated encryption
from cryptography.hazmat.primitives.ciphers.aead import AESGCM import os
key = AESGCM.generate_key(bit_length=256) aesgcm = AESGCM(key) nonce = os.urandom(12) # 96-bit nonce ciphertext = aesgcm.encrypt(nonce, plaintext, associated_data=None)
✅ SECURE: Password hashing
import bcrypt hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
✅ SECURE: Secure random token
import secrets token = secrets.token_urlsafe(32)
Secrets Management
Rule: Never hardcode secrets
Patterns:
❌ VULNERABLE
API_KEY = "sk_live_abc123xyz789"
✅ SECURE: Environment variables
import os API_KEY = os.environ['API_KEY']
✅ SECURE: Secrets manager (AWS Secrets Manager)
import boto3 client = boto3.client('secretsmanager') response = client.get_secret_value(SecretId='prod/api-key') API_KEY = response['SecretString']
✅ SECURE: Configuration file (gitignored)
import json with open('/etc/secrets/config.json') as f: config = json.load(f) API_KEY = config['api_key']
Checklist:
-
No secrets in source code
-
No secrets in git history (use git-secrets)
-
Secrets in environment variables or vault
-
Rotate secrets regularly
-
Use different secrets per environment (dev/staging/prod)
STRIDE Threat Modeling Worksheet
Use this template for every new feature/component:
Threat Model: [Feature/Component Name]
Description: [Brief description of functionality]
Date: [YYYY-MM-DD]
Reviewer: [Your name]
Components
List all components involved:
- [Component 1: e.g., Login API endpoint]
- [Component 2: e.g., User database]
- [Component 3: e.g., Session store]
Data Flow
Describe how data flows:
- User submits credentials → Login API
- Login API queries User DB
- On success, create session in Session Store
- Return session token to user
Threats Identified
Spoofing
- Threat: Attacker uses stolen credentials
- Mitigation: Implement MFA
- Priority: High
Tampering
- Threat: Man-in-the-middle modifies login request
- Mitigation: Enforce HTTPS/TLS 1.3
- Priority: Critical
Repudiation
- Threat: User denies login action
- Mitigation: Log all authentication events with timestamp
- Priority: Medium
Information Disclosure
- Threat: Verbose error reveals username existence
- Mitigation: Generic error message "Invalid credentials"
- Priority: Medium
Denial of Service
- Threat: Brute force attack exhausts server resources
- Mitigation: Rate limiting (5 attempts/minute)
- Priority: High
Elevation of Privilege
- Threat: Session fixation allows privilege escalation
- Mitigation: Regenerate session ID on login
- Priority: High
Risk Summary
Total threats identified: [N]
- Critical: [N]
- High: [N]
- Medium: [N]
- Low: [N]
Overall Risk Level: [Critical/High/Medium/Low]
Security Checklist (Pre-Deployment)
Use this before deploying any code to production:
Authentication & Authorization
-
Strong password policy enforced (12+ chars, complexity)
-
MFA available for sensitive accounts
-
Session timeout configured (15-30 minutes)
-
Secure session cookies (HttpOnly, Secure, SameSite)
-
Authorization checks on all endpoints
-
Default deny (whitelist approach)
Input Validation
-
All user input validated (whitelist preferred)
-
Parameterized queries used (no string concatenation)
-
File upload restrictions (type, size, content)
-
Output encoding for XSS prevention
Cryptography
-
TLS 1.2+ enforced for all connections
-
Passwords hashed with bcrypt/Argon2
-
No hardcoded secrets
-
Secrets in environment variables or vault
-
Secure random generators used (secrets module)
Error Handling
-
Generic error messages (no stack traces)
-
Errors logged with context (user, IP, timestamp)
-
No sensitive data in logs
Security Headers
-
Content-Security-Policy configured
-
X-Content-Type-Options: nosniff
-
X-Frame-Options: DENY or SAMEORIGIN
-
Strict-Transport-Security (HSTS)
-
X-XSS-Protection: 1; mode=block
Logging & Monitoring
-
Authentication events logged
-
Authorization failures logged
-
Security alerts configured
-
Log retention policy defined
Dependencies
-
No known vulnerabilities (npm audit, pip-audit)
-
Dependencies up to date
-
Unused dependencies removed
-
CI/CD includes security scanning
Infrastructure
-
Debug mode disabled in production
-
Default credentials changed
-
Unnecessary services disabled
-
Network segmentation implemented
-
Rate limiting configured
Reference Materials
Detailed Guides:
-
OWASP Top 10: https://owasp.org/www-project-top-ten/
-
STRIDE Methodology: https://learn.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats
-
CVSS Calculator: https://www.first.org/cvss/calculator/3.1
-
CWE Database: https://cwe.mitre.org/
Secure Coding Guides:
-
OWASP Cheat Sheet Series: https://cheatsheetseries.owasp.org/
-
NIST Secure Software Development Framework: https://csrc.nist.gov/projects/ssdf
Tools:
-
Static Analysis: Bandit (Python), ESLint (JS), cargo-audit (Rust)
-
Dependency Scanning: Snyk, Dependabot, npm audit
-
Dynamic Analysis: OWASP ZAP, Burp Suite
Self-Assessment
After applying security analysis, verify:
-
STRIDE Coverage: All 6 threat categories considered for this component
-
OWASP Awareness: Top 10 vulnerabilities reviewed and mitigated
-
Risk Scoring: Vulnerabilities scored and prioritized
-
Secure Patterns: Code review patterns applied
-
Checklist Completion: Pre-deployment checklist 100% complete
-
Documentation: Threat model and mitigations documented
-
Testing: Security tests written (auth bypass, injection, etc.)
Confidence Level:
-
High (90%+): All frameworks applied, threat model complete, security tests passing
-
Medium (70-89%): Main threats addressed, some edge cases remain
-
Low (<70%): Significant security gaps identified - continue working
Summary
Security Analysis Skills provide systematic frameworks for integrating security into all development work:
-
STRIDE Threat Modeling: Identify threats by category (Spoofing, Tampering, Repudiation, Information Disclosure, DoS, Elevation of Privilege)
-
OWASP Top 10: Address most critical web vulnerabilities
-
CVSS Risk Scoring: Quantify and prioritize vulnerability remediation
-
Secure Coding Patterns: Apply proven security patterns in code review
Remember: Security is not a feature, it's a requirement. Apply these frameworks proactively during design and development, not reactively after incidents.
Target: Zero Critical/High vulnerabilities in production deployments.