Skip to content

Latest commit

 

History

History
890 lines (713 loc) · 29.9 KB

File metadata and controls

890 lines (713 loc) · 29.9 KB

🔐 Security by Design Skill

Strategic Principle

Security must be built into every phase of development, not bolted on afterward.

This skill embodies the "Security by Design" principle from Hack23 AB's ISMS framework, ensuring all code changes follow secure development practices from conception to deployment.

Core Rules

1. Threat Modeling (ALWAYS REQUIRED)

BEFORE writing any code that handles:

  • User input
  • Authentication/Authorization
  • Sensitive data
  • External APIs
  • File operations

YOU MUST:

  1. Identify potential threats (STRIDE model: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege)
  2. Assess attack surface
  3. Design security controls
  4. Document threat mitigation strategy

Example:

// ❌ BAD: Writing code without threat assessment
function processUserInput(data: string) {
  return eval(data); // Critical vulnerability!
}

// ✅ GOOD: Threat-aware implementation
/**
 * Process user input with security controls
 * Threats mitigated:
 * - Code injection: Input validation + no eval()
 * - XSS: Output encoding
 * - DoS: Input size limits
 */
function processUserInput(data: string): string {
  // Validate input
  if (typeof data !== 'string' || data.length > 1000) {
    throw new Error('Invalid input');
  }
  
  // Sanitize using DOMPurify
  return DOMPurify.sanitize(data);
}

2. Input Validation (MANDATORY)

RULE: Never trust user input. Validate at boundaries.

Implementation:

  • Use allowlists (not denylists)
  • Validate type, format, length, range
  • Sanitize before use
  • Reject invalid input (fail secure)
// ✅ GOOD: Comprehensive input validation
import { z } from 'zod';

const SecurityLevelSchema = z.enum(['critical', 'high', 'moderate', 'low', 'public']);

function setSecurityLevel(level: unknown): SecurityLevel {
  // Validate using schema
  return SecurityLevelSchema.parse(level);
}

3. Principle of Least Privilege

RULE: Grant minimum necessary permissions.

Application:

  • Limit function/component access to only required data
  • Use TypeScript's readonly, private, protected
  • Implement role-based access control
  • Time-bound permissions where possible
// ✅ GOOD: Least privilege in action
interface UserData {
  readonly id: string;
  readonly email: string;
  // Sensitive fields not exposed
}

function displayUser(user: Pick<UserData, 'id' | 'email'>): JSX.Element {
  // Can only access id and email, nothing else
  return <div>{user.email}</div>;
}

4. Defense in Depth

RULE: Multiple layers of security controls.

Implementation:

// ✅ GOOD: Multiple security layers
async function handlePayment(data: PaymentData) {
  // Layer 1: Authentication check
  if (!isAuthenticated()) throw new AuthError();
  
  // Layer 2: Authorization check
  if (!hasPermission('payment:create')) throw new PermissionError();
  
  // Layer 3: Input validation
  validatePaymentData(data);
  
  // Layer 4: Rate limiting
  await checkRateLimit(userId);
  
  // Layer 5: Encryption
  const encryptedData = encrypt(data);
  
  // Layer 6: Audit logging
  await auditLog('payment:create', userId, data.amount);
  
  return processPayment(encryptedData);
}

5. Secure Error Handling

RULE: Never expose sensitive information in errors.

// ❌ BAD: Leaking sensitive information
catch (error) {
  console.log(`Database connection failed: ${dbPassword}`);
  throw new Error(`SQL error: ${error.stack}`);
}

// ✅ GOOD: Secure error handling
catch (error) {
  // Log detailed error securely (server-side only)
  logger.error('Database operation failed', { 
    errorCode: error.code, 
    userId 
  });
  
  // Return generic user-facing message
  throw new Error('An error occurred. Please try again later.');
}

6. Cryptography Best Practices

RULE: Use proven cryptographic libraries. Never roll your own crypto.

// ❌ BAD: Custom encryption
function encrypt(data: string): string {
  return btoa(data); // Not encryption!
}

// ✅ GOOD: Use proven libraries
import { webcrypto } from 'crypto';

async function encrypt(data: string, key: CryptoKey): Promise<ArrayBuffer> {
  const encoder = new TextEncoder();
  const dataBuffer = encoder.encode(data);
  
  return await webcrypto.subtle.encrypt(
    { name: 'AES-GCM', iv: generateIV() },
    key,
    dataBuffer
  );
}

7. Secure Dependencies

RULE: Minimize attack surface through dependencies.

Implementation:

  • Run npm audit before adding dependencies
  • Use GitHub Advisory Database check
  • Keep dependencies updated
  • Remove unused dependencies
  • Pin dependency versions
# ✅ GOOD: Security checks before adding dependencies
npm audit
npm audit fix
# Check for known vulnerabilities in new package
npm view <package-name> security

8. Security Testing (REQUIRED)

RULE: Security must be tested, not assumed.

Test Categories:

  1. Input validation tests: Malicious inputs, edge cases
  2. Authentication tests: Bypass attempts, token validation
  3. Authorization tests: Privilege escalation, access control
  4. Injection tests: SQL, XSS, command injection
  5. Cryptography tests: Key management, encryption/decryption
// ✅ GOOD: Security-focused tests
describe('Security: Input Validation', () => {
  it('should reject SQL injection attempts', () => {
    const maliciousInput = "'; DROP TABLE users; --";
    expect(() => validateInput(maliciousInput)).toThrow();
  });
  
  it('should reject XSS payloads', () => {
    const xssPayload = '<script>alert("XSS")</script>';
    expect(() => validateInput(xssPayload)).toThrow();
  });
  
  it('should enforce input length limits', () => {
    const tooLong = 'a'.repeat(10001);
    expect(() => validateInput(tooLong)).toThrow();
  });
});

Hack23 Secure Development Policy

  • Section 4.1: Secure coding practices mandatory
  • Section 4.3: Security testing in all phases
  • Section 4.5: Vulnerability management

ISO 27001:2022 Controls

  • 8.25: Secure development lifecycle
  • 8.26: Application security requirements
  • 8.27: Secure system architecture

NIST CSF 2.0

  • PR.DS: Data Security (protection of data at rest/transit)
  • PR.IP: Information Protection Processes
  • DE.CM: Security Continuous Monitoring

CIS Controls v8

  • Control 16: Application Software Security
  • Control 18: Penetration Testing

Enforcement Rules

MUST (Critical - Block PR if violated)

  1. All user inputs MUST be validated
  2. Authentication/authorization MUST be tested
  3. Secrets MUST NOT be hardcoded
  4. Sensitive data MUST be encrypted
  5. Error messages MUST NOT leak sensitive information

SHOULD (High priority - Require justification if not followed)

  1. Use proven security libraries (not custom implementations)
  2. Implement defense in depth
  3. Follow principle of least privilege
  4. Include security test cases
  5. Document threat model for sensitive operations

MAY (Recommended - Best practice)

  1. Use security linters (ESLint security plugins)
  2. Implement audit logging for sensitive operations
  3. Use TypeScript strict mode
  4. Add security-focused code comments
  5. Perform threat modeling workshops

Quick Decision Guide

When handling user input: → Validate type, format, length, range → Sanitize before use → Test with malicious payloads

When implementing authentication: → Use proven libraries (OAuth, JWT) → Implement multi-factor authentication → Test bypass scenarios

When storing data: → Encrypt sensitive data at rest → Use secure key management → Implement access controls

When communicating: → Use TLS for all connections → Validate certificates → Implement certificate pinning (mobile)

When logging: → Never log passwords, tokens, or PII → Log security events (auth failures, permission denials) → Implement log retention policies

🔄 Secure Development Lifecycle (SDLC) Integration

RULE: Security must be integrated into every phase of the development lifecycle.

📋 Phase 1: Planning & Design

Security Activities:

  • Threat modeling (STRIDE analysis)
  • Security requirements definition
  • Data classification and protection requirements
  • Architecture security review
  • Third-party component risk assessment

Deliverables:

// ✅ GOOD: Security requirements documented
interface SecurityRequirements {
  readonly authentication: {
    readonly method: 'OAuth2' | 'JWT' | 'SAML';
    readonly mfaRequired: boolean;
    readonly sessionTimeout: number;  // seconds
  };
  readonly authorization: {
    readonly model: 'RBAC' | 'ABAC';
    readonly defaultDeny: boolean;
  };
  readonly dataProtection: {
    readonly encryptionAtRest: boolean;
    readonly encryptionInTransit: boolean;
    readonly keyManagement: 'AWS_KMS' | 'Azure_KeyVault';
  };
  readonly auditLogging: {
    readonly enabled: boolean;
    readonly retentionDays: number;
  };
}

const PROJECT_SECURITY_REQUIREMENTS: SecurityRequirements = {
  authentication: {
    method: 'OAuth2',
    mfaRequired: true,
    sessionTimeout: 3600,
  },
  authorization: {
    model: 'RBAC',
    defaultDeny: true,
  },
  dataProtection: {
    encryptionAtRest: true,
    encryptionInTransit: true,
    keyManagement: 'AWS_KMS',
  },
  auditLogging: {
    enabled: true,
    retentionDays: 365,
  },
};

Reference: Secure Development Policy - Phase 1: Planning & Design

💻 Phase 2: Development

Security Activities:

  • Secure coding practices (OWASP Top 10 prevention)
  • Code review with security focus
  • Static Application Security Testing (SAST)
  • Dependency vulnerability scanning
  • Secret scanning and prevention

Secure Coding Standards:

// ✅ GOOD: Secure TypeScript patterns

// 1. Input Validation
import { z } from 'zod';

const UserInputSchema = z.object({
  email: z.string().email().max(254),
  password: z.string().min(12).max(128),
  displayName: z.string().min(1).max(100).regex(/^[a-zA-Z0-9\s]+$/),
});

function registerUser(input: unknown): Promise<User> {
  // Validate input structure
  const validated = UserInputSchema.parse(input);
  
  // Additional security checks
  if (await isEmailBlacklisted(validated.email)) {
    throw new Error('Email not allowed');
  }
  
  // Hash password with bcrypt
  const hashedPassword = await bcrypt.hash(validated.password, 12);
  
  return createUser({
    ...validated,
    password: hashedPassword,
  });
}

// 2. SQL Injection Prevention
import { sql } from 'kysely';

// ❌ BAD: String concatenation
const badQuery = `SELECT * FROM users WHERE email = '${email}'`;

// ✅ GOOD: Parameterized queries
const users = await db
  .selectFrom('users')
  .selectAll()
  .where('email', '=', email)
  .execute();

// 3. XSS Prevention
import DOMPurify from 'dompurify';

function renderUserContent(html: string): string {
  // Sanitize HTML before rendering
  return DOMPurify.sanitize(html, {
    ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
    ALLOWED_ATTR: ['href'],
  });
}

// 4. CSRF Protection
import { generateToken, validateToken } from 'csrf';

const csrfToken = generateToken(req);
res.cookie('XSRF-TOKEN', csrfToken, {
  httpOnly: false,  // JavaScript needs to read this
  secure: true,
  sameSite: 'strict',
});

// Validate on state-changing requests
if (!validateToken(req.body._csrf, req.cookies['XSRF-TOKEN'])) {
  throw new Error('CSRF validation failed');
}

// 5. Secure Session Management
const sessionConfig = {
  secret: process.env.SESSION_SECRET!,
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,
    secure: true,  // HTTPS only
    sameSite: 'strict' as const,
    maxAge: 3600000,  // 1 hour
  },
};

Code Review Checklist:

  • All user inputs validated
  • No hardcoded secrets or credentials
  • Parameterized queries used (no string concatenation)
  • Output encoding applied
  • Authentication and authorization implemented
  • Sensitive data encrypted
  • Error messages don't leak information
  • Security test cases included

Reference: Secure Development Policy - Phase 2: Development

🧪 Phase 3: Security Testing

Security Testing Types:

🕷️ Static Application Security Testing (SAST)

# ✅ GOOD: CodeQL SAST configuration
name: Security Scanning - SAST

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  codeql:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: javascript, typescript
          queries: security-and-quality
      
      - name: Autobuild
        uses: github/codeql-action/autobuild@v3
      
      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3

🌐 Dynamic Application Security Testing (DAST)

// ✅ GOOD: OWASP ZAP integration
import { ZapClient } from 'zaproxy';

async function runDAST(targetUrl: string): Promise<DastResults> {
  const zap = new ZapClient({
    apiKey: process.env.ZAP_API_KEY,
    proxy: 'http://localhost:8080',
  });
  
  // Spider the application
  await zap.spider.scan(targetUrl);
  await zap.spider.waitForComplete();
  
  // Active scan for vulnerabilities
  await zap.ascan.scan(targetUrl);
  await zap.ascan.waitForComplete();
  
  // Get alerts
  const alerts = await zap.core.alerts();
  
  return {
    targetUrl,
    scanDate: new Date(),
    alerts: alerts.filter(a => a.risk !== 'Informational'),
  };
}

🔍 Software Composition Analysis (SCA)

# ✅ GOOD: Multi-tool dependency scanning
npm audit --audit-level=high
npm run snyk-test
trivy fs --scanners vuln .

🧪 IAST & Penetration Testing

IAST: Use runtime security monitoring (e.g., Contrast agent) during test environments to detect vulnerabilities at execution time.

Penetration Testing Checklist:

  • Pre-engagement: scope definition, rules of engagement, legal authorization
  • Testing: recon, vuln scanning, exploitation, privilege escalation, lateral movement, data exfiltration
  • Reporting: executive summary, CVSS-scored findings, PoC, remediation, retest

Reference: Secure Development Policy - Phase 3: Security Testing

🚀 Phase 4: Deployment

Secure Deployment Checklist:

// ✅ GOOD: Secure deployment configuration
interface DeploymentSecurityConfig {
  readonly environment: 'development' | 'staging' | 'production';
  readonly securityHeaders: Record<string, string>;
  readonly corsPolicy: {
    readonly allowedOrigins: readonly string[];
    readonly allowedMethods: readonly string[];
  };
  readonly rateLimiting: {
    readonly enabled: boolean;
    readonly maxRequests: number;
    readonly windowMs: number;
  };
  readonly secretsManagement: {
    readonly provider: 'AWS_SecretsManager' | 'Azure_KeyVault';
    readonly rotationEnabled: boolean;
  };
}

const PRODUCTION_CONFIG: DeploymentSecurityConfig = {
  environment: 'production',
  securityHeaders: {
    'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
    'X-Content-Type-Options': 'nosniff',
    'X-Frame-Options': 'DENY',
    'Content-Security-Policy': "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';",
    'X-XSS-Protection': '1; mode=block',
  },
  corsPolicy: {
    allowedOrigins: ['https://cia-compliance-manager.com'],
    allowedMethods: ['GET', 'POST', 'PUT', 'DELETE'],
  },
  rateLimiting: {
    enabled: true,
    maxRequests: 100,
    windowMs: 60000,  // 1 minute
  },
  secretsManagement: {
    provider: 'AWS_SecretsManager',
    rotationEnabled: true,
  },
};

Deployment Security Gates:

  • All security tests passed
  • No critical or high vulnerabilities
  • Secrets rotated and not in code
  • Security headers configured
  • TLS/SSL certificates valid
  • Least privilege IAM roles
  • Monitoring and alerting enabled

Reference: Secure Development Policy - Phase 4: Deployment

🔧 Phase 5: Maintenance & Operations

Ongoing Security Activities:

  • Monitor security metrics (auth failures, rate limit exceeded, suspicious requests)
  • Track patch status (pending critical/high vulnerabilities)
  • Auto-response for critical threats (e.g., trigger incident response for potential DDoS)
  • Regular maintenance: rotate secrets, update dependencies, review access logs, validate backups

Vulnerability Management SLA (from Vulnerability Management Policy):

  • 🔴 Critical: 24 hours
  • 🟠 High: 7 days
  • 🟡 Medium: 30 days
  • 🟢 Low: 90 days

Reference: Secure Development Policy - Phase 5: Maintenance & Operations

🤖 AI-Augmented Development Security Controls

CRITICAL: GitHub Copilot custom agents are used extensively in Hack23's development process. These controls ensure AI-generated code maintains security standards.

🔐 AI as Proposal Generator, Not Authority

RULE: AI-generated code is a proposal that MUST be reviewed by humans for security.

// ✅ GOOD: AI-generated code with human security review
/**
 * 🤖 COPILOT GENERATED - CEO REVIEW REQUIRED
 * 
 * Security Review Checklist:
 * - [x] Input validation implemented
 * - [x] No hardcoded secrets
 * - [x] Error handling doesn't leak information
 * - [x] Authentication required
 * - [x] Authorization enforced
 * - [x] Security tests included
 * 
 * Reviewed by: James Pether Sörling, CEO
 * Review Date: 2026-02-10
 */
async function processPayment(amount: number, userId: string): Promise<PaymentResult> {
  // AI-generated implementation with security controls
  // ... (code validated by human reviewer)
}

📋 PR Review Requirements for AI-Generated Code

MANDATORY: All AI-generated PRs require CEO approval before merge.

# ✅ GOOD: CODEOWNERS for AI agent PRs
# .github/CODEOWNERS

# AI agent branches require CEO review
copilot/** @pethers

# Security-critical paths
src/auth/** @pethers
src/services/** @pethers
.github/workflows/** @pethers

🔧 Curator-Agent as Tooling Change

Context: The agent-curator org-level agent maintains agent configurations, not application code.

Security Boundary: Agent curator changes MUST NOT bypass security reviews for application code.

🛡️ Security Requirements for AI Usage

Data Protection: No PII in prompts, no secrets in context, ISMS context required. Code Generation: Human review required, security tests required, CEO approval for merge. Audit Trail: GitHub logs complete, PR description required, change justification required.

Reference:

📊 Testing Excellence Integration

🎯 Unit Test Coverage Standards

MUST Requirements:

  • 📊 80%+ overall test coverage
  • 📊 100% coverage for security-critical paths (authentication, authorization, data handling)
  • 📊 All edge cases and error scenarios tested
// ✅ GOOD: Comprehensive security test coverage
describe('UserAuthentication', () => {
  describe('Security Tests', () => {
    it('should reject invalid credentials', async () => {
      await expect(
        authenticateUser('user@example.com', 'wrong_password')
      ).rejects.toThrow('Invalid credentials');
    });
    
    it('should enforce rate limiting', async () => {
      // Attempt 6 failed logins (limit is 5)
      for (let i = 0; i < 6; i++) {
        try {
          await authenticateUser('user@example.com', 'wrong');
        } catch (e) {
          // Expected failures
        }
      }
      
      // 6th attempt should be rate limited
      await expect(
        authenticateUser('user@example.com', 'correct_password')
      ).rejects.toThrow('Rate limit exceeded');
    });
    
    it('should sanitize error messages', async () => {
      try {
        await authenticateUser('invalid-email', 'password');
      } catch (error) {
        // Should NOT reveal whether user exists
        expect(error.message).not.toContain('user not found');
        expect(error.message).toBe('Invalid credentials');
      }
    });
    
    it('should enforce session timeout', async () => {
      const session = await createSession('user@example.com');
      
      // Fast-forward time
      jest.advanceTimersByTime(3600000 + 1000);  // 1 hour + 1 second
      
      await expect(
        validateSession(session.token)
      ).rejects.toThrow('Session expired');
    });
  });
});

🌐 End-to-End Testing Strategy

Security E2E Tests:

// ✅ GOOD: E2E security testing with Cypress
describe('E2E Security Tests', () => {
  it('should enforce authentication on protected routes', () => {
    // Attempt to access protected route without auth
    cy.visit('/dashboard', { failOnStatusCode: false });
    
    // Should redirect to login
    cy.url().should('include', '/login');
  });
  
  it('should prevent XSS attacks', () => {
    const xssPayload = '<script>alert("XSS")</script>';
    
    cy.login('test@example.com', 'password');
    cy.visit('/profile');
    cy.get('[data-testid="display-name-input"]').type(xssPayload);
    cy.get('[data-testid="save-button"]').click();
    
    // Verify script tag was sanitized
    cy.get('[data-testid="display-name-display"]')
      .should('not.contain', '<script>');
  });
  
  it('should enforce CSRF protection', () => {
    cy.login('test@example.com', 'password');
    
    // Attempt state-changing request without CSRF token
    cy.request({
      method: 'POST',
      url: '/api/profile/update',
      failOnStatusCode: false,
      body: { name: 'Hacker' },
      headers: {
        // Missing CSRF token
      },
    }).then((response) => {
      expect(response.status).to.eq(403);
      expect(response.body.error).to.contain('CSRF');
    });
  });
});

Reference:

🕷️ Advanced Security Testing Framework

🐛 Bug Bounty & Vulnerability Disclosure

SHOULD: Maintain public vulnerability disclosure process. Report to security@hack23.com (24h SLA). Rewards: Critical €500-€2K, High €200-€500, Medium €50-€200, Low: Recognition. Scope: web app, API, open source repos. Out of scope: third-party services, social engineering, physical/DoS attacks.

Reference: Vulnerability Management Policy

When logging: Never log passwords/tokens/PII. Log security events (auth failures, permission denials). Implement log retention policies.

Remember

Security is not optional. Security is not an afterthought. Security is built-in from the first line of code.

Every code change is a potential attack vector. Think like an attacker, code like a defender.

Related Resources

📚 Hack23 ISMS Framework

🎯 Related Skills

🌐 External Standards & Resources

🎯 Compliance Framework Mapping

ISO 27001:2022 Controls

Control Description
A.5.23 Cloud services security
A.8.25 Secure development life cycle
A.8.26 Security requirements & threat modeling
A.8.27 Defense in depth architecture
A.8.28 Secure coding (OWASP Top 10)
A.8.29 Security testing (SAST/DAST/SCA/IAST/pentest)
A.8.30 Third-party component risk
A.8.31 Environment separation
A.8.32 Security gates in deployment
A.8.33 Test data protection

NIST CSF 2.0

GV.SC-01 (supply chain risk), ID.RA-01 (vulnerability docs), PR.DS-02 (data-in-transit/TLS), PR.DS-05 (data leak protection), PR.DS-06 (integrity/code signing), PR.IP-01 (secure defaults), PR.IP-02 (SDLC management), DE.CM-04 (malicious code detection), RS.AN-05 (vulnerability response)

CIS Controls v8.1

Control 2 (software asset inventory), Control 3 (data protection/encryption), Control 16 (application security: 16.1-16.14 covering secure dev process, vulnerability management, root cause analysis, third-party components, hardening, env separation, developer training, secure design, code-level checks, pentesting, threat modeling), Control 18 (penetration testing)

Information Security Policy Mapping (SDLC Phase Gates)

This skill operationalizes Information Security Policy + Secure Development Policy into concrete SDLC gates:

Phase Gate (MUST) Artifact
Plan Threat model (STRIDE) + CIA impact + policy citation on issue Issue body
Design Data classification, trust boundaries, crypto choices reviewed ADR + updated SECURITY_ARCHITECTURE.md
Build Input validation at boundaries, no any, no secrets in source CI: lint, strict TS, secret scanning
Test 80%+ cov (100% security-critical), negative/abuse tests, a11y Vitest + Cypress reports
Review Peer + security review, CodeQL + Dependabot green PR approvals, scan results
Release SBOM + SLSA provenance, CHANGELOG, version bump Release artifacts
Operate Vulnerability SLA tracking (24h/7d/30d/90d), incident runbook ready Dependabot, ZAP, Incident_Response_Plan

Related Resources