mcpField
S
secure-development

secure-development

github.com/hack23Security1335 installsUpdated today
Repository

About secure-development

A secure development skill for software teams, based on the Hack23 ISMS Secure Development Policy. It covers practices from input validation and access control to testing, dependencies, and code review.

Key features

  1. 01Defines input validation and output encoding
  2. 02Covers authentication and access control
  3. 03Sets cryptography and configuration rules
  4. 04Specifies error handling and security testing
  5. 05Addresses dependencies and code review

Use cases

  1. 01Set secure development practices for web apps and APIs
  2. 02Review authentication, authorization, and input handling
  3. 03Plan security tests before commits and releases
  4. 04Manage dependency updates and sensitive configuration

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/hack23/homepage --skill secure-development

After installing, type/secure-developmentin Claude Code to confirm it loaded.

Details

From the project README

Secure Development Skill

Purpose

This skill ensures all code development follows security-by-design principles as defined in the Hack23 ISMS Secure Development Policy. It applies to all software development activities including web applications, APIs, infrastructure code, and scripts.

Rules

Input Validation

MUST:

  • Validate ALL user input at the point of entry (server-side validation is mandatory)
  • Use allowlist validation (define what IS allowed, not what ISN'T)
  • Validate data type, length, format, and range
  • Encode output before rendering to prevent XSS
  • Sanitize input before use in queries, commands, or file operations
  • Reject invalid input with clear error messages (without exposing system details)

MUST NOT:

  • Rely solely on client-side validation
  • Trust data from external sources (APIs, databases, files) without validation
  • Use blocklist validation as the primary defense
  • Echo raw user input back to the browser
  • Expose stack traces or system information in error messages
Authentication and Authorization

MUST:

  • Enforce authentication for all non-public resources
  • Implement multi-factor authentication (MFA) for administrative access
  • Use secure session management (HTTPOnly, Secure, SameSite cookies)
  • Enforce strong password policies (minimum 12 characters, complexity requirements)
  • Implement account lockout after failed login attempts (5 attempts)
  • Log all authentication events (success and failure)
  • Use the principle of least privilege for all access controls
  • Verify authorization at each access point, not just at entry

MUST NOT:

  • Store passwords in plaintext or reversible encryption
  • Use weak hashing algorithms (MD5, SHA-1) for passwords
  • Implement custom authentication schemes without security review
  • Share authentication credentials between users or systems
  • Grant broad access by default
Cryptography

MUST:

  • Use AES-256 for symmetric encryption
  • Use RSA-2048 or higher for asymmetric encryption
  • Use SHA-256 or higher for hashing
  • Enforce TLS 1.2 or higher for all network communications
  • Store cryptographic keys securely (use key management systems, not code)
  • Use cryptographically secure random number generators (not Math.random())
  • Rotate encryption keys according to policy

MUST NOT:

  • Hard-code encryption keys, passwords, or secrets in source code
  • Use deprecated algorithms (DES, 3DES, MD5, SHA-1, SSL, TLS 1.0/1.1)
  • Implement custom cryptographic algorithms
  • Store secrets in version control (use secret management tools)
  • Use weak or predictable initialization vectors (IVs)
Secure Error Handling

MUST:

  • Implement centralized error handling
  • Log all security-relevant errors with sufficient detail for investigation
  • Return generic error messages to users
  • Fail securely (deny access on error, don't fall back to insecure state)
  • Clean up resources in finally blocks or using equivalent patterns
  • Monitor and alert on unusual error patterns

MUST NOT:

  • Expose stack traces to users
  • Include sensitive data in error messages (passwords, keys, tokens, PII)
  • Log sensitive data (passwords, credit card numbers, SSNs)
  • Continue processing after critical security errors
  • Suppress security exceptions without logging
Secure Configuration

MUST:

  • Use environment variables or secret management for sensitive configuration
  • Implement secure defaults (disable debug mode, enable security headers)
  • Document all security-relevant configuration options
  • Review configuration changes for security implications
  • Use principle of least privilege for service accounts and API keys
  • Disable unnecessary features, services, and endpoints

MUST NOT:

  • Commit configuration files with secrets to version control
  • Use default credentials in production
  • Enable debug/verbose logging in production
  • Expose administrative interfaces to public networks
  • Use overly permissive CORS policies
Security Testing

MUST:

  • Perform static application security testing (SAST) on every commit
  • Perform dynamic application security testing (DAST) before production deployment
  • Include security test cases in test suites
  • Perform dependency vulnerability scanning
  • Test authentication and authorization controls
  • Test input validation for injection vulnerabilities
  • Document security test results

MUST NOT:

  • Deploy code without passing security scans
  • Ignore or suppress security findings without proper justification and approval
  • Test security controls in production environments
  • Use production data in testing environments
Dependency Management

MUST:

  • Use dependency scanning tools (e.g., Dependabot, Snyk)
  • Keep dependencies up to date with security patches
  • Review dependencies for known vulnerabilities before use
  • Use package lock files to ensure reproducible builds
  • Document approved dependencies and their versions
  • Remove unused dependencies

MUST NOT:

  • Use dependencies with known critical vulnerabilities
  • Use abandoned or unmaintained dependencies
  • Download dependencies from untrusted sources
  • Bypass dependency version constraints without security review
Code Review

MUST:

  • Require peer review for all code changes
  • Include security review in code review process
  • Use automated security scanning in PR pipelines
  • Document security decisions in PR comments
  • Verify security requirements are met before approval

MUST NOT:

  • Merge code without required approvals
  • Bypass security checks in CI/CD pipeline
  • Approve your own security-critical changes

Examples

Example 1: Secure Input Validation (JavaScript)
// GOOD: Allowlist validation with type checking
function validateUsername(username) {
  // Define what IS allowed
  const usernameRegex = /^[a-zA-Z0-9_-]{3,20}$/;
  
  // Validate type
  if (typeof username !== 'string') {
    throw new Error('Invalid input type');
  }
  
  // Validate format and length
  if (!usernameRegex.test(username)) {
    throw new Error('Username must be 3-20 characters and contain only letters, numbers, hyphens, and underscores');
  }
  
  return username;
}

// BAD: No validation
function validateUsernameBad(username) {
  return username; // Accepts anything!
}

// BAD: Blocklist validation
function validateUsernameBad2(username) {
  if (username.includes('<') || username.includes('>')) {
    throw new Error('Invalid characters');
  }
  return username; // Still vulnerable to many attacks
}
Example 2: Secure Password Hashing (Node.js)
const bcrypt = require('bcrypt');

// GOOD: Use strong hashing with salt
async function hashPassword(password) {
  // MUST use at least 12 rounds (2^12 iterations)
  const saltRounds = 12;
  const hashedPassword = await bcrypt.hash(password, saltRounds);
  return hashedPassword;
}

async function verifyPassword(password, hashedPassword) {
  return await bcrypt.compare(password, hashedPassword);
}

// BAD: Using weak hashing
const crypto = require('crypto');
function hashPasswordBad(password) {
  // NEVER use MD5 or SHA-1 for passwords!
  return crypto.createHash('md5').update(password).digest('hex');
}

// BAD: Storing plaintext
function storePasswordBad(password) {
  return password; // NEVER store passwords in plaintext!
}
Example 3: Secure Session Management (Express.js)
const session = require('express-session');
const RedisStore = require('connect-redis')(session);

// GOOD: Secure session configuration
app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET, // From environment, not hardcoded
  name: 'sessionId', // Don't use default 'connect.sid'
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,      // MUST use HTTPS
    httpOnly: true,    // MUST prevent JavaScript access
    maxAge: 1800000,   // 30 minutes
    sameSite: 'strict' // CSRF protection
  }
}));

// BAD: Insecure session configuration
app.use(session({
  secret: 'mysecret123', // Hardcoded secret!
  cookie: {
    secure: false,    // Allows HTTP
    httpOnly: false   // Vulnerable to XSS
  }
}));
Example 4: Preventing SQL Injection (Node.js)
const mysql = require('mysql2/promise');

// GOOD: Parameterized queries
async function getUserByEmail(email) {
  const [rows] = await connection.execute(
    'SELECT * FROM users WHERE email = ?',
    [email]
  );
  return rows[0];
}

// BAD: String concatenation
async function getUserByEmailBad(email) {
  // NEVER concatenate user input into SQL!
  const query = `SELECT * FROM users WHERE email = '${email}'`;
  const [rows] = await connection.execute(query);
  return rows[0];
}
Example 5: Secure Error Handling (Python)
import logging

# GOOD: Generic error messages to users, detailed logging
def process_payment(user_id, amount):
    try:
        # Process payment logic
        charge_credit_card(user_id, amount)
        return {"success": True, "message": "Payment processed"}
    except CreditCardError as e:
        # Log detailed error securely
        logging.error(f"Payment failed for user {user_id}: {str(e)}", 
                     extra={"user_id": user_id, "amount": amount})
        # Return generic message to user
        return {"success": False, "message": "Payment processing failed. Please try again."}
    except Exception as e:
        # Log unexpected errors
        logging.exception(f"Unexpected error processing payment for user {user_id}")
        # Return generic message
        return {"success": False, "message": "An error occurred. Please contact support."}

# BAD: Exposing detailed errors
def process_payment_bad(user_id, amount):
    try:
        charge_credit_card(user_id, amount)
        return {"success": True}
    except Exception as e:
        # NEVER expose stack traces or system details to users!
        return {"success": False, "error": str(e), "trace": traceback.format_exc()}
Example 6: Secure Configuration (Environment Variables)
// GOOD: Use environment variables for secrets
require('dotenv').config();

const config = {
  database: {
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD, // Never hardcode!
    database: process.env.DB_NAME
  },
  api: {
    key: process.env.API_KEY,
    secret: process.env.API_SECRET
  },
  // Secure defaults
  security: {
    httpsOnly: true,
    hstsEnabled: true,
    debugMode: false
  }
};

// Validate required environment variables
const required = ['DB_HOST', 'DB_USER', 'DB_PASSWORD', 'API_KEY'];
required.forEach(key => {
  if (!process.env[key]) {
    throw new Error(`Missing required environment variable: ${key}`);
  }
});

// BAD: Hardcoded secrets
const configBad = {
  database: {
    host: 'localhost',
    user: 'admin',
    password: 'P@ssw0rd123', // NEVER hardcode passwords!
    database: 'production'
  },
  api: {
    key: 'sk_live_abcdef123456' // NEVER commit API keys!
  }
};
Example 7: XSS Prevention (HTML Output Encoding)
// GOOD: Encode output before rendering
function escapeHtml(unsafe) {
  return unsafe
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;");
}

function displayUserComment(comment) {
  const safeComment = escapeHtml(comment);
  document.getElementById('comment').innerHTML = safeComment;
}

// Or use a trusted library
const DOMPurify = require('dompurify');
function displayUserContent(content) {
  const clean = DOMPurify.sanitize(content);
  document.getElementById('content').innerHTML = clean;
}

// BAD: Direct HTML insertion
function displayUserCommentBad(comment) {
  // NEVER insert unsanitized user input into HTML!
  document.getElementById('comment').innerHTML = comment;
}

Related ISMS Policies

This skill implements requirements from:

Related Documentation

Compliance Mapping

ISO 27001:2022
  • A.8.24 Use of cryptography
  • A.8.25 Secure development life cycle
  • A.8.26 Application security requirements
  • A.8.28 Secure coding
NIST Cybersecurity Framework
  • PR.DS-2: Data-in-transit is protected
  • PR.DS-6: Integrity checking mechanisms verify software integrity
  • PR.IP-2: A System Development Life Cycle to manage systems is implemented
CIS Controls
  • Control 16: Application Software Security
    • 16.1 Establish and Maintain a Secure Application Development Process
    • 16.2 Establish and Maintain a Process to Accept and Address Software Vulnerabilities
    • 16.10 Apply Secure Design Principles in Application Architectures

Enforcement

Violations of secure development rules:

  • Critical violations (hardcoded secrets, use of banned algorithms): Block deployment, require immediate remediation
  • High severity violations (missing input validation, weak authentication): Require remediation before merge
  • Medium severity violations: Require remediation within sprint
  • Low severity violations: Create technical debt tickets

All violations must be tracked and reported in security metrics.

Comments

Markdown supported