Agent Skill
2/7/2026security-audit
Use this skill when the user asks to "audit security", "check for vulnerabilities", "review authentication", "prevent IDOR", "protect customer data", "verify webhooks", "check HMAC", or any security-related review work. Provides security patterns for authentication, authorization, IDOR prevention, PII protection, and webhook verification.
T
trantuananh
0GitHub Stars
1Views
npx skills add trantuananh-17/product-reviews
SKILL.md
| Name | security-audit |
| Description | Use this skill when the user asks to "audit security", "check for vulnerabilities", "review authentication", "prevent IDOR", "protect customer data", "verify webhooks", "check HMAC", or any security-related review work. Provides security patterns for authentication, authorization, IDOR prevention, PII protection, and webhook verification. |
name: security-audit description: Use this skill when the user asks to "audit security", "check for vulnerabilities", "review authentication", "prevent IDOR", "protect customer data", "verify webhooks", "check HMAC", or any security-related review work. Provides security patterns for authentication, authorization, IDOR prevention, PII protection, and webhook verification.
Security Patterns (packages/functions)
For API design patterns, see
api-designskill
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 |
Authentication
Endpoint Types
| Endpoint Type | Auth Required | Example |
|---|---|---|
| Admin API | Shop session + JWT | /api/admin/* |
| Storefront API | Customer token OR signature | /api/storefront/* |
| Popup/Widget | HMAC signature | /popup/* |
| Webhook | Shopify HMAC | /webhooks/* |
| Public | None (no sensitive data) | /health, /status |
Admin Controller
import {getCurrentShop} from '@functions/helpers/auth';
async function getCustomers(ctx) {
const shopId = getCurrentShop(ctx); // From authenticated session
const customers = await customerRepo.getByShopId(shopId);
ctx.body = {success: true, data: customers};
}
IDOR Prevention
Audit Checklist
| Check | Secure | Vulnerable |
|---|---|---|
| Shop ID source | getCurrentShop(ctx), ctx.state.shop.id | ctx.params, ctx.query |
| Query scoping | .where('shopId', '==', shopId) | .doc(id).get() alone |
| Ownership check | if (resource.shopId !== shopId) | Return data directly |
| Update/Delete | Verify ownership first | repo.update(id, data) |
Grep Commands for Audit
grep -rn "ctx.params.shopId" controllers/
grep -rn "ctx.params.customerId" controllers/
grep -rn "getById(" repositories/
grep -rn ".doc(.*).get()" repositories/
Secure Pattern
async function getOrder(ctx) {
const shopId = getCurrentShop(ctx);
const {orderId} = ctx.params;
const order = await orderRepo.getById(orderId);
if (order.shopId !== shopId) {
ctx.status = 403;
return;
}
ctx.body = {success: true, data: order};
}
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
// Only return non-sensitive data
ctx.body = {
firstName: customer.firstName,
points: customer.points,
tier: customer.tier
// Never: email, phone, address
};
HMAC Verification
Popup Signature
import crypto from 'crypto';
function verifyPopupSignature(ctx) {
const {shopId, customerId, timestamp, signature} = ctx.query;
// Reject old requests
if (Date.now() - parseInt(timestamp) > 5 * 60 * 1000) return false;
const expected = crypto
.createHmac('sha256', process.env.POPUP_SECRET)
.update(`${shopId}:${customerId}:${timestamp}`)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
Shopify Webhook
function verifyShopifyWebhook(ctx) {
const hmac = ctx.get('X-Shopify-Hmac-Sha256');
const calculated = crypto
.createHmac('sha256', process.env.SHOPIFY_API_SECRET)
.update(ctx.request.rawBody, 'utf8')
.digest('base64');
return crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(calculated));
}
Webhook Vulnerabilities
| Pattern | Risk |
|---|---|
| HMAC bypass headers | CRITICAL |
| No HMAC verification | HIGH |
| Missing timestamp validation | MEDIUM |
Input Validation
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)
});
}
Database Security
Firestore Rules
match /customers/{customerId} {
allow read, write: if request.auth != null
&& request.auth.token.shopId == resource.data.shopId;
}
Storage Rules
match /shops/{shopId}/{allPaths=**} {
allow read, write: if request.auth != null
&& request.auth.token.shopId == shopId
&& request.resource.size < 5 * 1024 * 1024;
}
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
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
Skills Info
Original Name:security-auditAuthor:trantuananh
Download