All skills
getsentry avatar

/security-review

@3482d8d official
by Sentrygetsentry/skills1k stars
53

Security code review for vulnerabilities. Use when asked to "security review", "find vulnerabilities", "check for security issues", "audit security", "OWASP review", or review code for injection, XSS, authentication, authorization, cryptography issues. Provides systematic review with confidence-based reporting.

Use this Skill: https://skilld.dev/gh/getsentry/skills/security-review

This session only. Nothing lands on disk.

referencesdata-protection.md

≈2.4k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Data Protection Reference

Overview

Data protection encompasses safeguarding sensitive information throughout its lifecycle: collection, processing, storage, transmission, and disposal. Security failures at any stage can lead to data breaches.

Sensitive Data Categories

Personal Identifiable Information (PII)

  • Full names, addresses, phone numbers
  • Email addresses
  • Social Security Numbers, national IDs
  • Dates of birth
  • Biometric data

Financial Information

  • Credit card numbers (PAN)
  • Bank account numbers
  • Financial transactions
  • Payment credentials

Authentication Credentials

  • Passwords (plaintext or weakly hashed)
  • API keys and tokens
  • Session identifiers
  • Private keys

Health Information (PHI/HIPAA)

  • Medical records
  • Health conditions
  • Treatment information
  • Insurance data

Sensitive Data Exposure Prevention

1. Data Classification

Classify all data by sensitivity level:

Level Examples Handling
Public Marketing content No restrictions
Internal Employee directory Access controls
Confidential Customer data Encryption + access controls
Restricted Passwords, keys, PCI data Strong encryption + audit logs

2. Minimize Data Collection

# VULNERABLE: Collecting unnecessary data
user_data = {
    'name': form.name,
    'email': form.email,
    'ssn': form.ssn,  # Why do you need this?
    'mother_maiden_name': form.mother_maiden_name,  # Security risk
    'password': form.password,  # Never store plaintext
}

# SAFE: Collect only what's needed
user_data = {
    'name': form.name,
    'email': form.email,
}

3. Encryption at Rest

# Database-level encryption
# Configure in database settings (TDE for SQL Server, etc.)

# Application-level encryption for specific fields
from cryptography.fernet import Fernet

def encrypt_ssn(ssn):
    f = Fernet(get_encryption_key())
    return f.encrypt(ssn.encode())

def decrypt_ssn(encrypted_ssn):
    f = Fernet(get_encryption_key())
    return f.decrypt(encrypted_ssn).decode()

4. Encryption in Transit

# VULNERABLE: HTTP endpoint
app.run(host='0.0.0.0', port=80)

# SAFE: HTTPS required
app.run(host='0.0.0.0', port=443, ssl_context='adhoc')

# BETTER: Proper TLS configuration
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain('cert.pem', 'key.pem')
ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2

Information Disclosure Prevention

Error Messages

# VULNERABLE: Detailed error messages
@app.errorhandler(Exception)
def handle_error(e):
    return {
        'error': str(e),
        'traceback': traceback.format_exc(),
        'sql_query': last_query,
        'server': socket.gethostname()
    }, 500

# SAFE: Generic error messages
@app.errorhandler(Exception)
def handle_error(e):
    # Log full details server-side
    app.logger.error(f"Error: {e}", exc_info=True)

    # Return generic message to client
    return {'error': 'An unexpected error occurred'}, 500

Stack Traces

# VULNERABLE: Debug mode in production
app.run(debug=True)

# SAFE: Debug off, custom error pages
app.run(debug=False)

@app.errorhandler(404)
def not_found(e):
    return render_template('404.html'), 404

@app.errorhandler(500)
def server_error(e):
    return render_template('500.html'), 500

API Response Filtering

# VULNERABLE: Returning all fields
@app.route('/api/users/<id>')
def get_user(id):
    user = User.query.get(id)
    return jsonify(user.__dict__)  # Includes password_hash, internal_id, etc.

# SAFE: Explicit field selection
@app.route('/api/users/<id>')
def get_user(id):
    user = User.query.get(id)
    return jsonify({
        'id': user.public_id,
        'name': user.name,
        'email': user.email
    })

Server Headers

# VULNERABLE: Technology disclosure
# Response headers reveal:
# Server: Apache/2.4.41 (Ubuntu)
# X-Powered-By: PHP/7.4.3
# X-AspNet-Version: 4.0.30319

# SAFE: Remove or genericize headers
# In nginx:
# server_tokens off;

# In Express.js:
app.disable('x-powered-by');

# In Flask:
@app.after_request
def remove_headers(response):
    response.headers.pop('Server', None)
    return response

Logging Security

What NOT to Log

# VULNERABLE: Logging sensitive data
logger.info(f"User login: {username}, password: {password}")
logger.info(f"API call with key: {api_key}")
logger.info(f"Credit card: {card_number}")
logger.debug(f"Session token: {session_id}")

# SAFE: Sanitized logging
logger.info(f"User login: {username}")
logger.info(f"API call with key: {api_key[:4]}****")
logger.info(f"Credit card: ****{card_number[-4:]}")
logger.debug(f"Session token: {hash_for_logging(session_id)}")

Sensitive Data Patterns to Avoid in Logs

Data Type Pattern
Passwords password, passwd, pwd, secret
API Keys api_key, apikey, token, bearer
Credit Cards 16-digit numbers, card_number
SSN \d{3}-\d{2}-\d{4}, ssn, social
Session IDs session, sess_id, jsessionid

Log Injection Prevention

# VULNERABLE: User input directly in logs
logger.info(f"Search query: {user_input}")
# Attack: user_input = "test\nINFO: Admin logged in"

# SAFE: Sanitize before logging
def sanitize_for_log(text):
    return text.replace('\n', '\\n').replace('\r', '\\r')

logger.info(f"Search query: {sanitize_for_log(user_input)}")

Secure Data Disposal

Memory Handling

# Python strings are immutable - difficult to clear
# Use bytearray for sensitive data when possible

# BETTER: Clear sensitive data
import ctypes

def secure_zero(data):
    """Zero out sensitive data in memory."""
    if isinstance(data, bytearray):
        for i in range(len(data)):
            data[i] = 0
    elif isinstance(data, bytes):
        # Can't modify bytes, but can overwrite the reference
        pass

# In Java:
# char[] password = getPassword();
# try { ... }
# finally { Arrays.fill(password, '\0'); }

File Deletion

# VULNERABLE: Simple delete (data recoverable)
os.remove(sensitive_file)

# SAFER: Overwrite before delete
def secure_delete(filepath):
    with open(filepath, 'ba+') as f:
        length = f.tell()
        f.seek(0)
        f.write(os.urandom(length))  # Random overwrite
        f.flush()
        os.fsync(f.fileno())
    os.remove(filepath)

Database Retention

# Implement data retention policies
def cleanup_old_data():
    cutoff = datetime.now() - timedelta(days=RETENTION_DAYS)

    # Delete old records
    OldRecord.query.filter(OldRecord.created_at < cutoff).delete()

    # Or anonymize instead of delete
    User.query.filter(User.last_login < cutoff).update({
        'email': func.concat('deleted_', User.id, '@example.com'),
        'name': 'Deleted User',
        'phone': None
    })

Cache Security

# VULNERABLE: Caching sensitive data
@cache.cached(timeout=3600)
def get_user_with_ssn(user_id):
    return User.query.get(user_id)  # Includes SSN

# SAFE: Don't cache sensitive data
def get_user_with_ssn(user_id):
    return User.query.get(user_id)  # Not cached

# Or cache only non-sensitive parts
@cache.cached(timeout=3600)
def get_user_profile(user_id):
    user = User.query.get(user_id)
    return {
        'id': user.id,
        'name': user.name,
        # SSN excluded
    }

Cache Headers

# For sensitive pages
response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = '0'

Grep Patterns for Detection

# Sensitive data in logs
grep -rn "logger.*password\|log.*password\|print.*password" --include="*.py" --include="*.js"
grep -rn "logger.*token\|log.*api_key\|print.*secret" --include="*.py" --include="*.js"

# Debug mode
grep -rn "debug.*[Tt]rue\|DEBUG.*=.*1" --include="*.py" --include="*.js" --include="*.env"

# Stack traces in responses
grep -rn "traceback\|stack_trace\|exc_info" --include="*.py" | grep -i "return\|response\|json"

# Verbose errors
grep -rn "str(e)\|str(exception)" --include="*.py" | grep -i "return\|response"

# Technology disclosure
grep -rn "X-Powered-By\|Server:" --include="*.py" --include="*.js" --include="*.conf"

# Missing cache headers
grep -rn "Set-Cookie\|session" --include="*.py" | grep -v "Cache-Control"

Testing Checklist

  • Sensitive data encrypted at rest
  • All transmissions over TLS 1.2+
  • Error messages are generic (no stack traces, SQL errors, paths)
  • Logging excludes sensitive data (passwords, tokens, PII)
  • API responses filtered to necessary fields only
  • Server headers don't reveal technology stack
  • Sensitive pages have no-cache headers
  • Data retention policies implemented
  • Secure deletion procedures for sensitive files
  • Debug mode disabled in production

References

Source: SKILL.md on GitHub

3 alerts2d5 checks · Risk CRITICAL
  • Gen Agent Trust Hub2d

    The skill is a comprehensive security auditing tool designed to help AI agents identify vulnerabilities in codebases. It contains extensive documentation and examples of common security flaws (such as SQL injection, XSS, and supply chain attacks) to guide the analysis process. Automated scanner alerts regarding malware and code injection are false positives triggered by the inclusion of these educational examples within the documentation.

  • Socket2d

    1 alert: gptMalware

  • Snyk2d

    Risk: LOW · No issues

  • Runlayer7mo

    20/22 files flagged

  • ZeroLeaks5mo

    2 findings · Score: 80/100

Signed by skilld at 3482d8d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 3 days ago
All 1 allowed tools
Read Grep Glob Bash Task
  • Security
  • code-review
  • vulnerabilities
  • owasp
  • injection
  • xss
  • authentication
  • authorization

README badge

README badge for getsentry/skills/security-review

Performs systematic security code review to identify exploitable vulnerabilities in injection, XSS, authentication, authorization, and cryptography. Reports only high-confidence findings after researching the codebase to confirm attacker-controlled input and framework mitigations, following OWASP guidelines.

Generated from the current SKILL.md.

Does this skill flag theoretical vulnerabilities or only confirmed exploitable issues?
Only HIGH CONFIDENCE findings—clear vulnerable patterns with attacker-controlled input confirmed through codebase research. Theoretical, best-practice, or defense-in-depth issues are not reported.
Will this skill review test files and commented code?
No. Test files, dead code, and commented code are excluded from review unless explicitly requested. Documentation strings are also skipped.
Does this skill flag hardcoded URLs or configuration values as SSRF vulnerabilities?
No. Server-controlled values like Django settings, environment variables, and hardcoded configuration are considered safe. Only user-input URLs are flagged as SSRF.
What languages and frameworks does this skill cover?
Python (Django, Flask, FastAPI), JavaScript/TypeScript (Node, Express, React, Vue, Next.js), Go, Rust, and Java (Spring). It loads language-specific guides to check for framework-mitigated patterns before flagging.
Does this skill check for hardcoded secrets and credentials?
Yes. Hardcoded passwords, API keys, AWS secrets, and private keys are always flagged as Critical severity.

Generated from the current SKILL.md. These answers refresh after source changes.