Security Patterns (packages/functions)
For API design patterns, see
api-designskill
Quick Reference
| Topic | Reference File |
|---|---|
| Ownership Checks, Audit Commands | references/idor-prevention.md |
| Webhook HMAC, Popup Signatures | references/hmac-verification.md |
| Endpoint Types, Session Handling | references/authentication.md |
Critical Vulnerabilities
| Vulnerability | Risk | Example |
|---|---|---|
| IDOR | High | User A accesses User B's data via /api/customer/123 |
| Unauthenticated PII | Critical | Returning email in public API response |
| Missing Auth | Critical | /popup/* endpoints without authentication |
| Shop Isolation | Critical | Shop A accessing Shop B's data |
PII Protection
Classification
| Data Type | Classification | Public Endpoint? |
|---|---|---|
| Email, Phone, Address | PII | Never |
| Date of Birth | PII | Never |
| Payment Info | Sensitive PII | Never |
| First Name | Low Risk | With signature |
| Points, Tier | Non-PII | With signature |
Secure Response
javascript
// Only return non-sensitive data
ctx.body = {
firstName: customer.firstName,
points: customer.points,
tier: customer.tier
// Never: email, phone, address
};
Input Validation
javascript
async function updateCustomer(ctx) {
const shopId = getCurrentShop(ctx);
const {customerId} = ctx.params;
const {firstName, lastName} = ctx.request.body; // Whitelist fields
const customer = await customerRepo.getById(customerId);
if (customer.shopId !== shopId) {
ctx.status = 403;
return;
}
await customerRepo.update(customerId, {
firstName: firstName?.trim().slice(0, 50),
lastName: lastName?.trim().slice(0, 50)
});
}
Best Practices
| Do | Don't |
|---|---|
Get shopId from getCurrentShop(ctx) | Use ctx.params.shopId |
| Scope all queries by shopId | Query without shop filter |
| Whitelist response fields | Return full objects |
| Verify HMAC on webhooks | Trust headers blindly |
| Validate and sanitize inputs | Use ctx.request.body directly |
Use crypto.timingSafeEqual | Compare strings with === |
Security Checklist
code
Authentication: - Sensitive endpoints require auth - Shop ID from session, not params - Customer ID verified against token Authorization: - Users access only their data - Shop isolation verified - No IDOR vulnerabilities Data Protection: - No PII in unauthenticated responses - Response fields whitelisted - Inputs validated and sanitized Webhooks: - HMAC verification on all webhooks - Timestamp validation - No bypass headers