Files
Kunthawat Greethong 7edf5bc4d0 feat: Import 35+ skills, merge duplicates, add openclaw installer
Major updates:
- Added 35+ new skills from awesome-opencode-skills and antigravity repos
- Merged SEO skills into seo-master
- Merged architecture skills into architecture
- Merged security skills into security-auditor and security-coder
- Merged testing skills into testing-master and testing-patterns
- Merged pentesting skills into pentesting
- Renamed website-creator to thai-frontend-dev
- Replaced skill-creator with github version
- Removed Chutes references (use MiniMax API instead)
- Added install-openclaw-skills.sh for cross-platform installation
- Updated .env.example with MiniMax API credentials
2026-03-26 11:37:39 +07:00

7.4 KiB

name, description
name description
security-coder Master secure coding skill combining frontend, backend, and mobile security coding. XSS prevention, injection prevention, authentication, API security. Use when writing secure code or fixing security vulnerabilities.

Security Coder

Comprehensive secure coding skill combining: frontend security, backend security, and mobile security coding practices.


Quick Reference

Task Use Section
Prevent XSS Frontend Security
Secure APIs Backend Security
Mobile app security Mobile Security
Fix vulnerabilities Common Fixes
Input validation Input Security
Auth implementation Authentication

Frontend Security (XSS Prevention)

Output Handling

Unsafe Safe
element.innerHTML = userInput element.textContent = userInput
document.write(userInput) element.appendChild(safeEl)
eval(userInput) Never eval user input
href=userInput (javascript:) Validate protocol, use # for unknown

Sanitization

// Use DOMPurify for HTML content
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(dirty, { ALLOWED_TAGS: ['b', 'i'] });

// Always use textContent for user data
element.textContent = userData;

// Encode for context
// HTML: < > & "
// JS: \x3C \x3E \u2028 \u2029
// URL: encodeURIComponent()
// CSS: escape or use allowlist

Content Security Policy (CSP)

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{random}' https://trusted-cdn.com;
  style-src 'self' 'nonce-{random}';
  img-src 'self' https: data:;
  font-src 'self';
  connect-src 'self' https://api.example.com;
  frame-ancestors 'none';
  base-uri 'self';
  form-action 'self';

Safe DOM Manipulation

  • Always prefer textContent over innerHTML
  • Use document.createElement() over document.write()
  • Validate URLs before setting href, src, action
  • Use srcdoc only with sanitized content

Backend Security (Injection Prevention)

SQL Injection Prevention

# BAD - vulnerable
query = f"SELECT * FROM users WHERE id = {user_id}"

# GOOD - parameterized
query = "SELECT * FROM users WHERE id = %s"
cursor.execute(query, (user_id,))

# GOOD - ORM
user = User.query.filter_by(id=user_id).first()

NoSQL Injection Prevention

# Validate input types
if not isinstance(user_id, int):
    raise ValueError("Invalid ID type")

# Use parameterized queries
result = db.users.find_one({"_id": ObjectId(user_id)})

Command Injection Prevention

# NEVER use user input in shell commands
# BAD
os.system(f"grep {user_input} file")

# GOOD - subprocess with list
subprocess.run(["grep", user_input, "file"], shell=False)

# GOOD - shlex.quote
os.system(f"grep {shlex.quote(user_input)} file")

Input Validation

# Allowlist validation
import re
def validate_email(email):
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    return re.match(pattern, email) is not None

# Type validation
def get_user_id(user_id):
    if isinstance(user_id, str) and user_id.isdigit():
        return int(user_id)
    raise ValueError("Invalid user ID")

# Range validation
def get_page(page, max_page=100):
    page = int(page)
    if page < 1:
        page = 1
    return min(page, max_page)

API Security

Authentication Headers

Authorization: Bearer <jwt_token>
X-API-Key: <api_key>

Rate Limiting

# Implement rate limiting
from functools import wraps
import time

def rate_limit(max_calls, period):
    def decorator(func):
        calls = {}
        @wraps(func)
        def wrapper(*args, **kwargs):
            now = time.time()
            key = func.__name__
            if key not in calls:
                calls[key] = []
            calls[key] = [t for t in calls[key] if now - t < period]
            if len(calls[key]) >= max_calls:
                raise TooManyRequestsError()
            calls[key].append(now)
            return func(*args, **kwargs)
        return wrapper
    return decorator

Security Headers

response.headers.update({
    'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
    'X-Content-Type-Options': 'nosniff',
    'X-Frame-Options': 'DENY',
    'X-XSS-Protection': '1; mode=block',
    'Referrer-Policy': 'strict-origin-when-cross-origin',
    'Permissions-Policy': 'geolocation=(), microphone=(), camera=()',
    'Content-Security-Policy': "default-src 'self'"
})

CORS Configuration

# Strict CORS
ALLOWED_ORIGINS = ['https://app.example.com']

@app.after_request
def add_cors(response):
    origin = request.headers.get('Origin')
    if origin in ALLOWED_ORIGINS:
        response.headers['Access-Control-Allow-Origin'] = origin
        response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
        response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
        response.headers['Access-Control-Allow-Credentials'] = 'true'
    return response

Authentication Security

Password Hashing

# Use bcrypt or Argon2
import bcrypt

def hash_password(password):
    return bcrypt.hashpw(password.encode(), bcrypt.gensalt())

def verify_password(password, hashed):
    return bcrypt.checkpw(password.encode(), hashed)

# Or Argon2
from argon2 import PasswordHasher
ph = PasswordHasher()
hash = ph.hash("secret")
ph.verify(hash, "secret")

JWT Security

# Sign with RS256 (asymmetric)
# Verify with public key
import jwt

# Token structure
payload = {
    'sub': user_id,
    'exp': datetime.utcnow() + timedelta(hours=1),
    'iat': datetime.utcnow(),
    'scope': ['read', 'write']  # Minimal scopes
}

# Short expiration, no sensitive data
token = jwt.encode(payload, private_key, algorithm='RS256')

Session Management

# Secure session config
SESSION_COOKIE = {
    'httponly': True,      # No JS access
    'secure': True,        # HTTPS only
    'samesite': 'Lax',     # CSRF protection
    'max-age': 3600,       # 1 hour
}

Mobile Security

iOS Security

  • Keychain for sensitive data
  • Certificate pinning
  • jailbreak detection
  • Biometric auth (Face ID, Touch ID)
  • Obfuscate API keys

Android Security

  • Keystore for keys
  • Network security config
  • ProGuard/R8 obfuscation
  • Safe browsing API
  • Biometric auth

React Native

// Secure storage
import * as Keychain from 'react-native-keychain';

// Certificate pinning
const sslPinning = {
  certs: ['cert1', 'cert2']
};

Common Security Fixes

IDOR Prevention

# Always verify ownership
def get_document(doc_id, user_id):
    doc = Document.query.get(doc_id)
    if doc.owner_id != user_id:
        abort(403)  # Forbidden
    return doc

CSRF Prevention

# Use CSRF tokens
from flask_wtf import FlaskForm
from wtforms import SubmitField

class MyForm(FlaskForm):
    csrf_token = HiddenField()
    submit = SubmitField()

XXE Prevention

# Disable XML external entities
import defusedxml
ET = defusedxml.ElementSafeTypes

Security Checklist

  • Input validation on all user data
  • Parameterized queries (no string interpolation)
  • Output encoding for context
  • CSRF tokens on forms
  • Secure session configuration
  • HTTPS only
  • Security headers
  • Rate limiting
  • Logging without sensitive data
  • Error messages without stack traces