security-review
Provides essential security guidance for securing web applications and API integrations.
Install
mkdir -p .claude/skills/security-review-augustsnow1127 && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/15607" && unzip -o skill.zip -d .claude/skills/security-review-augustsnow1127 && rm skill.zipInstalls to .claude/skills/security-review-augustsnow1127
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Security checklist and best practices for the personal blog projectKey capabilities
- →Check for hardcoded secrets in source code
- →Validate environment variables at runtime
- →Implement rate limiting for API calls
- →Sanitize user input to prevent XSS
- →Configure Content Security Policy (CSP) headers
- →Validate Notion API data before rendering
How it works
The skill provides a checklist and code examples to ensure secure handling of environment variables, API interactions, and user input. It covers prevention of common vulnerabilities like XSS and SQL injection, and guides on configuring security headers.
Inputs & outputs
When to use security-review
- →Audit env variable usage
- →Secure notion api integration
- →Validate input sanitization
- →Verify security checklist
About this skill
Security Review Checklist
This skill provides a comprehensive security review checklist for the Next.js + Notion blog.
Environment Variables Security
✅ Required Checks
- No hardcoded secrets in source code
- All API keys in
.env.localfile -
.env.localis in.gitignore - Environment variables validated at runtime
- No secrets in client-side code
Implementation
// lib/env.ts - Environment variable validation
export function validateEnv() {
const required = ['NOTION_API_KEY', 'NOTION_DATABASE_ID'];
for (const key of required) {
if (!process.env[key]) {
throw new Error(`Missing required environment variable: ${key}`);
}
}
}
// Call in server-side code only
validateEnv();
❌ Common Mistakes
// ❌ NEVER do this
const API_KEY = 'ntn_abc123...'; // Hardcoded secret
// ❌ NEVER expose in client components
'use client';
const key = process.env.NOTION_API_KEY; // Exposed to browser!
// ✅ CORRECT - Server-side only
// app/api/posts/route.ts
export async function GET() {
const key = process.env.NOTION_API_KEY; // Safe - server-side
// ...
}
API Security
Notion API Best Practices
- Rate limiting - Handle 429 responses
- Error handling - Don't expose internal errors
- Input validation - Validate all user inputs
- CORS configuration - Restrict origins if needed
// lib/notion.ts - Secure API wrapper
export async function getPosts(): Promise<NotionPost[]> {
try {
const response = await notion.databases.query({
database_id: process.env.NOTION_DATABASE_ID!,
filter: {
property: 'Published',
checkbox: { equals: true },
},
});
return response.results.map(mapNotionToPost);
} catch (error) {
// ✅ Log error server-side
console.error('Notion API error:', error);
// ❌ Don't expose internal error details
// throw error;
// ✅ Return safe fallback
return [];
}
}
Rate Limiting
// lib/rateLimit.ts
const RATE_LIMIT = 3; // requests per second
const cache = new Map<string, number[]>();
export function rateLimit(identifier: string): boolean {
const now = Date.now();
const timestamps = cache.get(identifier) || [];
// Remove timestamps older than 1 second
const recent = timestamps.filter(t => now - t < 1000);
if (recent.length >= RATE_LIMIT) {
return false; // Rate limit exceeded
}
recent.push(now);
cache.set(identifier, recent);
return true;
}
XSS Prevention
Content Sanitization
- Sanitize user input (if accepting comments/forms)
- Escape HTML in dynamic content
- Use React's built-in escaping (automatic)
- Validate Notion content before rendering
// components/NotionRenderer.tsx
export function NotionRenderer({ blocks }: { blocks: NotionBlock[] }) {
return blocks.map(block => {
switch (block.type) {
case 'paragraph':
// ✅ React automatically escapes text
return <p>{block.paragraph.rich_text[0]?.plain_text}</p>;
case 'code':
// ✅ Use proper code highlighting library
return <SyntaxHighlighter>{block.code.rich_text[0]?.plain_text}</SyntaxHighlighter>;
default:
return null;
}
});
}
❌ Dangerous Patterns
// ❌ NEVER use dangerouslySetInnerHTML with unsanitized content
<div dangerouslySetInnerHTML={{ __html: userInput }} />
// ✅ If you must use it, sanitize first
import DOMPurify from 'isomorphic-dompurify';
<div dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(content)
}} />
CSRF Protection
Next.js provides built-in CSRF protection for Server Actions.
// app/actions.ts
'use server';
export async function submitForm(formData: FormData) {
// ✅ Automatically protected by Next.js
const email = formData.get('email');
// Process form...
}
SQL Injection Prevention
Not applicable for this project (using Notion API), but if adding a database:
// ✅ Use parameterized queries
const result = await db.query(
'SELECT * FROM posts WHERE slug = $1',
[slug]
);
// ❌ NEVER concatenate user input
const result = await db.query(
`SELECT * FROM posts WHERE slug = '${slug}'` // VULNERABLE!
);
Authentication & Authorization
Currently not implemented, but if adding:
Checklist
- Use established auth library (NextAuth.js, Clerk, etc.)
- Implement HTTPS only
- Use secure session cookies
- Implement proper password hashing (bcrypt, Argon2)
- Add rate limiting to login endpoints
- Implement CSRF tokens
- Use secure password reset flow
Content Security Policy (CSP)
// next.config.ts
const nextConfig = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'Content-Security-Policy',
value: [
"default-src 'self'",
"script-src 'self' 'unsafe-eval' 'unsafe-inline'",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data: https:",
"font-src 'self' data:",
"connect-src 'self' https://api.notion.com",
].join('; '),
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
],
},
];
},
};
Dependency Security
Regular Audits
# Check for vulnerabilities
npm audit
# Fix automatically
npm audit fix
# Check for outdated packages
npm outdated
Dependabot Configuration
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
Vercel Deployment Security
Environment Variables
- Set environment variables in Vercel dashboard
- Use different keys for preview/production
- Enable "Encrypted" option for sensitive vars
Security Headers
- Enable HTTPS only
- Configure security headers in
next.config.ts - Set up custom domain with SSL
Notion Integration Security
API Key Management
- Use integration token (not personal token)
- Limit integration permissions to minimum required
- Rotate keys periodically
- Monitor API usage
Data Validation
// lib/notion.ts - Validate Notion data
function mapNotionToPost(page: any): NotionPost {
// ✅ Validate required fields
if (!page.properties.Title?.title?.[0]?.plain_text) {
throw new Error('Invalid post: missing title');
}
if (!page.properties.Slug?.rich_text?.[0]?.plain_text) {
throw new Error('Invalid post: missing slug');
}
return {
id: page.id,
title: page.properties.Title.title[0].plain_text,
slug: page.properties.Slug.rich_text[0].plain_text,
// ... other fields
};
}
Security Review Workflow
Before Every Deployment
- Run
npm audit - Check
.env.localnot committed - Review new dependencies
- Test error handling
- Verify environment variables in Vercel
- Check security headers
- Review Notion API permissions
Monthly Security Tasks
- Update dependencies
- Rotate API keys
- Review access logs
- Check for new vulnerabilities
- Update security policies
Incident Response Plan
If a security issue is discovered:
- Assess Impact - Determine scope and severity
- Contain - Rotate compromised keys immediately
- Investigate - Review logs and access patterns
- Fix - Deploy security patch
- Notify - Inform affected users if necessary
- Document - Record incident and response
Security Resources
How it compares
This skill offers a project-specific security checklist and implementation guidance for a Next.js + Notion blog, providing concrete code examples for common security practices rather than general security advice.
Compared to similar skills
security-review side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| security-review (this skill) | 0 | 6mo | Review | Intermediate |
| middleware-protection | 1 | 6mo | Review | Intermediate |
| vercel-data-handling | 1 | 1mo | No flags | Intermediate |
| Server Actions and Auth Guard Order | 0 | 1mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
middleware-protection
dadbodgeoff
Protect routes with Next.js middleware. Check authentication once, protect routes declaratively. Supports public routes, protected routes, and role-based access.
vercel-data-handling
jeremylongshore
Implement Vercel PII handling, data retention, and GDPR/CCPA compliance patterns. Use when handling sensitive data, implementing data redaction, configuring retention policies, or ensuring compliance with privacy regulations for Vercel integrations. Trigger with phrases like "vercel data", "vercel PII", "vercel GDPR", "vercel data retention", "vercel privacy", "vercel CCPA".
Server Actions and Auth Guard Order
bytetalent
Zod validation before data touch, auth guard sequence, authz inside the action, security headers.
reviewing-nextjs-16-patterns
djankies
Review code for Next.js 16 compliance - security patterns, caching, breaking changes. Use when reviewing Next.js code, preparing for migration, or auditing for violations.
firebase
davila7
Firebase gives you a complete backend in minutes - auth, database, storage, functions, hosting. But the ease of setup hides real complexity. Security rules are your last line of defense, and they're often wrong. Firestore queries are limited, and you learn this after you've designed your data model. This skill covers Firebase Authentication, Firestore, Realtime Database, Cloud Functions, Cloud Storage, and Firebase Hosting. Key insight: Firebase is optimized for read-heavy, denormalized data. I
auth-patterns
davepoon
This skill should be used when the user asks about "authentication in Next.js", "NextAuth", "Auth.js", "middleware auth", "protected routes", "session management", "JWT", "login flow", or needs guidance on implementing authentication and authorization in Next.js applications.