用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/fabioc-aloha/Alex_Skill_Mall --skill allowlist-over-blocklist命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Create or improve a Markdown instruction, skill, prompt, or agent from an explicitly selected file or user-identified text. Use when a user asks to optimize an existing brain artifact or create one for consistent future execution.
Clear documentation through visual excellence
Assess active Markdown brain files in a local AI agent project or plugin source without changing it. Use before modifying a brain or reviewing declared instructions, skills, prompts, agents, bundled Markdown resources, and research documentation.
基于 SOC 职业分类
正在显示 SKILL.md
| name | allowlist-over-blocklist |
| description | Validate input against an allowlist of permitted values — reject everything else |
| lastReviewed | 2026-04-30T00:00:00.000Z |
Category: Security Time Saved: Prevents security incidents Battle-tested: Yes — fundamental security principle
You need to validate user input — URLs, file paths, commands, or any constrained values. You think "I'll block the dangerous ones" and create a blocklist. Later, an attacker finds a format you didn't think of.
Blocklists are incomplete by definition. They only block what you anticipated. Attackers find edge cases, encodings, and variants you didn't consider.
Example: URL validation blocklist
// ❌ BLOCKLIST APPROACH
const blocked = ['javascript:', 'data:', 'vbscript:'];
if (blocked.some(b => url.toLowerCase().startsWith(b))) {
reject();
}
// Bypassed by: JAVASCRIPT:, java\nscript:, data\x00:text/html
Enumerate what's permitted. Reject everything else.
// ✅ ALLOWLIST APPROACH
const allowed = ['https:', 'http:'];
const protocol = new URL(url).protocol;
if (!allowed.includes(protocol)) {
reject();
}
// Only https: and http: pass. Everything else fails.
| Domain | Allowlist | Not Blocklist |
|---|---|---|
| URL schemes | ['https:', 'http:'] | Not ['javascript:', 'data:'] |
| File extensions | ['.jpg', '.png', '.pdf'] | Not ['.exe', '.sh'] |
| Commands | ['git', 'npm', 'node'] | Not ['rm', 'curl'] |
| API methods | ['GET', 'POST'] | Not ['DELETE', 'PATCH'] |
| User roles | ['admin', 'editor', 'viewer'] | Not ['banned', 'suspended'] |
const ALLOWED_PROTOCOLS = new Set(['https:', 'http:']);
function isValidUrl(input) {
try {
const url = new URL(input);
return ALLOWED_PROTOCOLS.has(url.protocol);
} catch {
return false;
}
}
const ALLOWED_EXTENSIONS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.pdf']);
function isAllowedFile(filename) {
const ext = path.extname(filename).toLowerCase();
return ALLOWED_EXTENSIONS.has(ext);
}
const ALLOWED_COMMANDS = new Set(['git', 'npm', 'node', 'tsc']);
function safeExec(command, args) {
if (!ALLOWED_COMMANDS.has(command)) {
throw new Error(`Command not allowed: ${command}`);
}
return execFileSync(command, args);
}
const ALLOWED_METHODS = new Set(['GET', 'POST', 'PUT']);
function validateMethod(method) {
if (!ALLOWED_METHODS.has(method.toUpperCase())) {
throw new Error(`Method not allowed: ${method}`);
}
}
Allowlists are your first gate, not your only gate:
function validateUpload(file) {
// Gate 1: Allowlist extension
if (!ALLOWED_EXTENSIONS.has(path.extname(file.name).toLowerCase())) {
throw new Error('File type not allowed');
}
// Gate 2: Check MIME type
if (!ALLOWED_MIMES.has(file.mimetype)) {
throw new Error('MIME type not allowed');
}
// Gate 3: Check magic bytes
if (!verifyMagicBytes(file.buffer)) {
throw new Error('File content mismatch');
}
}
| Mistake | Problem |
|---|---|
| Case-sensitive allowlist | HTTPS: bypasses ['https:'] |
| Partial matching | https://evil.com matches http |
| Mutable allowlist | Attackers modify at runtime |
| Empty string in allowlist | Matches falsy inputs |
const or frozenshell-injection-prevention — Command validationpath-traversal-prevention — File path validation