pact-security-patterns
npx skills add https://github.com/profsynapse/pact-plugin --skill pact-security-patterns
Agent 安装分布
Skill 文档
PACT Security Patterns
Security guidance for PACT development phases. This skill provides essential security patterns and links to detailed references for comprehensive implementation.
SACROSANCT Rules (Non-Negotiable)
These rules are ABSOLUTE and must NEVER be violated.
Rule 1: Credential Protection
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:
| Location | Example | Security Level |
|---|---|---|
.env files in .gitignore |
API_KEY=sk-xxx |
Development |
Server-side process.env |
process.env.API_KEY |
Runtime |
| Deployment platform secrets | Railway, Vercel, AWS | Production |
| Secrets managers | Vault, AWS Secrets Manager | Enterprise |
In Documentation – Always Use Placeholders:
# Configuration
Set your API key in `.env`:
API_KEY=your_api_key_here
Rule 2: Backend Proxy Pattern
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:
# Build the application
npm run build
# 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
# All above should return NO results
Quick Security Reference
Input Validation
Always validate on the server side:
// 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:
// 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, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
SQL Injection Prevention
Always use parameterized queries:
// 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:
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:
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:
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:
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") -
.envfiles listed in.gitignore - Placeholders used in all documentation
- No hardcoded API keys in source code
Architecture
- Frontend makes NO direct external API calls with credentials
- Backend proxy pattern implemented for all external integrations
- All credentials loaded from environment variables
Input/Output
- All user inputs validated server-side
- SQL queries use parameterized statements
- HTML output properly encoded
- File uploads validated for type and size
Authentication
- Passwords hashed with bcrypt (12+ rounds)
- Sessions configured with secure flags
- Authentication endpoints rate-limited
- JWT tokens have short expiration
Headers and Transport
- Security headers configured (use Helmet.js or equivalent)
- HTTPS enforced in production
- CORS configured restrictively
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