pact-security-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

PACT Security Patterns

PACT 安全模式

Security guidance for PACT development phases. This skill provides essential security patterns and links to detailed references for comprehensive implementation.
PACT开发阶段的安全指南。本技能提供核心安全模式以及指向详细参考资料的链接,供完整落地实现使用。

SACROSANCT Rules (Non-Negotiable)

SACROSANCT 规则(不可协商)

These rules are ABSOLUTE and must NEVER be violated.
这些规则是绝对要求,绝不可违反。

Rule 1: Credential Protection

规则1:凭证保护

NEVER ALLOW in version control:
  • Actual API keys, tokens, passwords, or secrets
  • Credentials in frontend code (VITE_, REACT_APP_, NEXT_PUBLIC_ prefixes)
  • Real credential values in documentation or code examples
  • Hardcoded secrets in any file committed to git
ONLY acceptable locations for actual credentials:
LocationExampleSecurity Level
.env
files in
.gitignore
API_KEY=sk-xxx
Development
Server-side
process.env
process.env.API_KEY
Runtime
Deployment platform secretsRailway, Vercel, AWSProduction
Secrets managersVault, AWS Secrets ManagerEnterprise
In Documentation - Always Use Placeholders:
markdown
undefined
版本控制中绝对禁止出现:
  • 真实的API密钥、令牌、密码或私密信息
  • 前端代码中的凭证(带VITE_、REACT_APP_、NEXT_PUBLIC_前缀的变量)
  • 文档或代码示例中的真实凭证值
  • 提交到git的任意文件中硬编码的私密信息
真实凭证唯一可接受的存储位置:
位置示例安全级别
被列入
.gitignore
.env
文件
API_KEY=sk-xxx
开发环境
服务端
process.env
process.env.API_KEY
运行时
部署平台的私密配置Railway、Vercel、AWS生产环境
密钥管理服务Vault、AWS Secrets Manager企业级
文档中请始终使用占位符:
markdown
undefined

Configuration

Configuration

Set your API key in
.env
: API_KEY=your_api_key_here
undefined
Set your API key in
.env
: API_KEY=your_api_key_here
undefined

Rule 2: Backend Proxy Pattern

规则2:后端代理模式

WRONG:  Frontend --> External API (credentials in frontend)
CORRECT: Frontend --> Backend Proxy --> External API
Architecture Requirements:
  • Frontend MUST NEVER have direct access to API credentials
  • ALL API credentials MUST exist exclusively on server-side
  • Frontend calls backend endpoints (
    /api/resource
    ) without credentials
  • Backend handles ALL authentication with external APIs
  • Backend validates and sanitizes ALL requests from frontend
Verification Checklist:
bash
undefined
错误写法: 前端 --> 外部API(凭证暴露在前端)
正确写法: 前端 --> 后端代理 --> 外部API
架构要求:
  • 前端绝对不能直接访问API凭证
  • 所有API凭证必须仅存在于服务端
  • 前端无需携带凭证调用后端接口(
    /api/resource
  • 后端处理所有与外部API的身份认证逻辑
  • 后端验证并清洗所有来自前端的请求
验证检查清单:
bash
undefined

Build the application

Build the application

npm run build
npm run build

Search for exposed credentials in bundle

Search for exposed credentials in bundle

grep -r "sk-" dist/assets/.js grep -r "api_key" dist/assets/.js grep -r "VITE_" dist/assets/*.js
grep -r "sk-" dist/assets/.js grep -r "api_key" dist/assets/.js grep -r "VITE_" dist/assets/*.js

All above should return NO results

All above should return NO results

undefined
undefined

Quick Security Reference

快速安全参考

Input Validation

输入验证

Always validate on the server side:
javascript
// Express.js example
const { body, validationResult } = require('express-validator');

app.post('/api/user',
  body('email').isEmail().normalizeEmail(),
  body('name').trim().escape().isLength({ min: 1, max: 100 }),
  body('age').isInt({ min: 0, max: 150 }),
  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    // Process validated input
  }
);
请始终在服务端进行验证:
javascript
// Express.js example
const { body, validationResult } = require('express-validator');

app.post('/api/user',
  body('email').isEmail().normalizeEmail(),
  body('name').trim().escape().isLength({ min: 1, max: 100 }),
  body('age').isInt({ min: 0, max: 150 }),
  (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }
    // Process validated input
  }
);

Output Encoding

输出编码

Prevent XSS by encoding output:
javascript
// React (automatic encoding)
return <div>{userInput}</div>; // Safe - React escapes

// Dangerous - avoid unless absolutely necessary
return <div dangerouslySetInnerHTML={{__html: userInput}} />; // UNSAFE

// Node.js HTML response
const escapeHtml = (str) => str
  .replace(/&/g, '&amp;')
  .replace(/</g, '&lt;')
  .replace(/>/g, '&gt;')
  .replace(/"/g, '&quot;')
  .replace(/'/g, '&#039;');
通过输出编码防范XSS攻击:
javascript
// React (automatic encoding)
return <div>{userInput}</div>; // Safe - React escapes

// Dangerous - avoid unless absolutely necessary
return <div dangerouslySetInnerHTML={{__html: userInput}} />; // UNSAFE

// Node.js HTML response
const escapeHtml = (str) => str
  .replace(/&/g, '&amp;')
  .replace(/</g, '&lt;')
  .replace(/>/g, '&gt;')
  .replace(/"/g, '&quot;')
  .replace(/'/g, '&#039;');

SQL Injection Prevention

SQL注入防护

Always use parameterized queries:
javascript
// WRONG - SQL Injection vulnerable
const query = `SELECT * FROM users WHERE id = ${userId}`;

// CORRECT - Parameterized query
const query = 'SELECT * FROM users WHERE id = $1';
const result = await db.query(query, [userId]);

// ORM example (Prisma)
const user = await prisma.user.findUnique({
  where: { id: userId }  // Safe - Prisma handles escaping
});
始终使用参数化查询:
javascript
// WRONG - SQL Injection vulnerable
const query = `SELECT * FROM users WHERE id = ${userId}`;

// CORRECT - Parameterized query
const query = 'SELECT * FROM users WHERE id = $1';
const result = await db.query(query, [userId]);

// ORM example (Prisma)
const user = await prisma.user.findUnique({
  where: { id: userId }  // Safe - Prisma handles escaping
});

Authentication Security

认证安全

Password Storage:
javascript
const bcrypt = require('bcrypt');

// Hashing password
const saltRounds = 12;  // Minimum recommended
const hashedPassword = await bcrypt.hash(password, saltRounds);

// Verifying password
const isValid = await bcrypt.compare(password, hashedPassword);
Session Configuration:
javascript
app.use(session({
  secret: process.env.SESSION_SECRET,  // Strong, random secret
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,       // HTTPS only
    httpOnly: true,     // No JavaScript access
    sameSite: 'strict', // CSRF protection
    maxAge: 3600000     // 1 hour
  }
}));
密码存储:
javascript
const bcrypt = require('bcrypt');

// Hashing password
const saltRounds = 12;  // Minimum recommended
const hashedPassword = await bcrypt.hash(password, saltRounds);

// Verifying password
const isValid = await bcrypt.compare(password, hashedPassword);
会话配置:
javascript
app.use(session({
  secret: process.env.SESSION_SECRET,  // Strong, random secret
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true,       // HTTPS only
    httpOnly: true,     // No JavaScript access
    sameSite: 'strict', // CSRF protection
    maxAge: 3600000     // 1 hour
  }
}));

Security Headers

安全头部

Essential HTTP headers:
javascript
const helmet = require('helmet');

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:", "https:"],
      connectSrc: ["'self'"],
      frameSrc: ["'none'"],
      objectSrc: ["'none'"]
    }
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true
  }
}));
必备HTTP头配置:
javascript
const helmet = require('helmet');

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:", "https:"],
      connectSrc: ["'self'"],
      frameSrc: ["'none'"],
      objectSrc: ["'none'"]
    }
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true
  }
}));

Rate Limiting

限流配置

Protect against abuse:
javascript
const rateLimit = require('express-rate-limit');

// General API rate limit
const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100,
  message: { error: 'Too many requests, please try again later' }
});

// Stricter limit for auth endpoints
const authLimiter = rateLimit({
  windowMs: 60 * 60 * 1000, // 1 hour
  max: 5,
  message: { error: 'Too many login attempts' }
});

app.use('/api/', apiLimiter);
app.use('/api/auth/', authLimiter);
防范接口滥用:
javascript
const rateLimit = require('express-rate-limit');

// General API rate limit
const apiLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100,
  message: { error: 'Too many requests, please try again later' }
});

// Stricter limit for auth endpoints
const authLimiter = rateLimit({
  windowMs: 60 * 60 * 1000, // 1 hour
  max: 5,
  message: { error: 'Too many login attempts' }
});

app.use('/api/', apiLimiter);
app.use('/api/auth/', authLimiter);

Security Checklist

安全检查清单

Before any commit or deployment, verify:
在任何提交或部署前,验证以下项:

Credential Protection

凭证保护

  • No credentials in staged files (
    git diff --staged | grep -i "key\|secret\|password"
    )
  • .env
    files listed in
    .gitignore
  • Placeholders used in all documentation
  • No hardcoded API keys in source code
  • 暂存文件中无凭证(执行
    git diff --staged | grep -i "key\|secret\|password"
    检查)
  • .env
    文件已列入
    .gitignore
  • 所有文档中都使用占位符
  • 源码中无硬编码的API密钥

Architecture

架构

  • Frontend makes NO direct external API calls with credentials
  • Backend proxy pattern implemented for all external integrations
  • All credentials loaded from environment variables
  • 前端没有携带凭证直接调用外部API的行为
  • 所有外部集成都实现了后端代理模式
  • 所有凭证都从环境变量加载

Input/Output

输入/输出

  • All user inputs validated server-side
  • SQL queries use parameterized statements
  • HTML output properly encoded
  • File uploads validated for type and size
  • 所有用户输入都在服务端完成验证
  • SQL查询使用参数化语句
  • HTML输出已正确编码
  • 上传文件的类型和大小都经过验证

Authentication

认证

  • Passwords hashed with bcrypt (12+ rounds)
  • Sessions configured with secure flags
  • Authentication endpoints rate-limited
  • JWT tokens have short expiration
  • 密码使用bcrypt哈希(轮次不低于12)
  • 会话配置了安全标识
  • 认证接口配置了限流
  • JWT令牌设置了较短的过期时间

Headers and Transport

头部与传输

  • Security headers configured (use Helmet.js or equivalent)
  • HTTPS enforced in production
  • CORS configured restrictively
  • 已配置安全头部(使用Helmet.js或同等方案)
  • 生产环境强制使用HTTPS
  • CORS配置遵循最小权限原则

Detailed References

详细参考

For comprehensive security guidance, see:
  • OWASP Top 10 Mitigations: references/owasp-top-10.md
    • Detailed vulnerability descriptions
    • Code examples for each mitigation
    • Testing approaches
  • Authentication Patterns: references/authentication-patterns.md
    • JWT implementation
    • Session management
    • OAuth 2.0 flows
    • Multi-factor authentication
  • Data Protection: references/data-protection.md
    • Encryption at rest and in transit
    • PII handling requirements
    • GDPR compliance patterns
    • Key management
如需完整的安全指南,可查看:
  • OWASP Top 10 缓解方案references/owasp-top-10.md
    • 详细的漏洞描述
    • 每项缓解措施的代码示例
    • 测试方法
  • 认证模式references/authentication-patterns.md
    • JWT实现
    • 会话管理
    • OAuth 2.0 流程
    • 多因素认证
  • 数据保护references/data-protection.md
    • 静态与传输中数据加密
    • PII处理要求
    • GDPR合规模式
    • 密钥管理