Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问clear审计提醒

audit-expert审计专家

Agent Skill

用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查。它适合让 Agent 梳理敏感配置、检查依赖风险、分析鉴权逻辑或生成安全复核清单。使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。

总安装

2,210

周安装

93

GitHub Stars

19

下载量

774
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:audit-expert(审计专家)
来源仓库:https://github.com/personamanagmentlayer/pcl
仓库路径:skills/audit-expert
安装命令:
npx skills add https://github.com/personamanagmentlayer/pcl --skill audit-expert
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/personamanagmentlayer/pcl --skill audit-expert

简介

提供安全审计、合规评估、代码审查和漏洞检测的专业指导,覆盖 SOC 2、GDPR、HIPAA 等标准。

  • 基于 OWASP ASVS 和 NIST 框架构建审计流程,支持应用安全、基础设施和 SDLC 全过程检查。
  • 适用于渗透测试、静态分析和监管合规场景,输出可操作的改进建议和缺陷分类。
  • 安装方式:通过 npx skills add 命令从指定 GitHub 仓库添加,支持 Codex、Claude、Cursor 等宿主环境。
  • 不替代专业审计意见,所有工作底稿需经持证财务或安全人员复核方可作为正式依据。

SKILL.md

Audit Expert

Expert guidance for security auditing, compliance assessments, code reviews, vulnerability assessments, and regulatory compliance (SOC 2, GDPR, HIPAA, PCI-DSS).

Core Concepts

Audit Types

  • Security Audit: Vulnerability assessment, penetration testing
  • Code Audit: Code review, static analysis, security patterns
  • Compliance Audit: SOC 2, GDPR, HIPAA, PCI-DSS, ISO 27001
  • Infrastructure Audit: Configuration review, access control
  • Process Audit: SDLC, change management, incident response

Audit Frameworks

  • OWASP ASVS (Application Security Verification Standard)
  • NIST Cybersecurity Framework
  • CIS Controls
  • ISO 27001/27002
  • SOC 2 Trust Service Criteria

Audit Process

  1. Planning and scoping
  2. Information gathering
  3. Vulnerability identification
  4. Risk assessment
  5. Reporting
  6. Remediation tracking
  7. Follow-up verification

Security Code Review

Authentication Review

// ❌ Issues to flag
class AuthService {
  // Issue 1: Weak password requirements
  validatePassword(password) {
    return password.length >= 6; // Too short!
  }

  // Issue 2: Password stored in plaintext
  async createUser(email, password) {
    await db.users.create({ email, password }); // No hashing!
  }

  // Issue 3: Timing attack vulnerability
  async login(email, password) {
    const user = await db.users.findOne({ email });
    if (!user) return null;

    // Direct comparison reveals timing
    if (user.password === password) {
      return user;
    }
    return null;
  }

  // Issue 4: No rate limiting
  // Issue 5: No MFA support
  // Issue 6: Predictable session tokens
  generateSessionToken() {
    return Math.random().toString(36); // Not cryptographically secure!
  }
}

// ✅ Secure implementation
const bcrypt = require('bcrypt');
const crypto = require('crypto');

class SecureAuthService {
  // Strong password validation
  validatePassword(password) {
    const minLength = 12;
    const hasUppercase = /[A-Z]/.test(password);
    const hasLowercase = /[a-z]/.test(password);
    const hasNumber = /[0-9]/.test(password);
    const hasSpecial = /[^A-Za-z0-9]/.test(password);

    return password.length >= minLength &&
           hasUppercase && hasLowercase &&
           hasNumber && hasSpecial;
  }

  // Secure password hashing
  async hashPassword(password) {
    const saltRounds = 12;
    return await bcrypt.hash(password, saltRounds);
  }

  async createUser(email, password) {
    if (!this.validatePassword(password)) {
      throw new Error('Password does not meet requirements');
    }

    const passwordHash = await this.hashPassword(password);
    await db.users.create({
      email: email.toLowerCase(),
      passwordHash
    });
  }

  // Constant-time comparison with rate limiting
  async login(email, password) {
    // Check rate limit
    const attempts = await this.getLoginAttempts(email);
    if (attempts > 5) {
      throw new Error('Too many login attempts. Try again later.');
    }

    const user = await db.users.findOne({
      email: email.toLowerCase()
    });

    // Always hash password even if user not found (timing attack prevention)
    const isValid = user ?
      await bcrypt.compare(password, user.passwordHash) :
      await bcrypt.compare(password, '$2b$12$dummyhash');

    if (!user || !isValid) {
      await this.recordFailedAttempt(email);
      throw new Error('Invalid credentials');
    }

    await this.clearLoginAttempts(email);
    return user;
  }

  // Cryptographically secure tokens
  generateSessionToken() {
    return crypto.randomBytes(32).toString('hex');
  }

  // MFA support
  async verifyMFA(user, token) {
    const speakeasy = require('speakeasy');
    return speakeasy.totp.verify({
      secret: user.mfaSecret,
      encoding: 'base32',
      token,
      window: 2
    });
  }
}

SQL Injection Review

// Audit checklist for SQL injection:
// 1. Are all queries parameterized?
// 2. Is user input sanitized?
// 3. Are ORM features used correctly?
// 4. Are stored procedures parameterized?

// ❌ Vulnerable patterns to flag
async function searchUsers(name) {
  // Issue: String concatenation
  const query = `SELECT * FROM users WHERE name = '${name}'`;
  return await db.query(query);
}

async function updateUser(id, data) {
  // Issue: Dynamic column names not validated
  const columns = Object.keys(data).join(', ');
  const query = `UPDATE users SET ${columns} WHERE id = ${id}`;
  return await db.query(query);
}

// ❌ ORM misuse
async function findUsers(filters) {
  // Issue: Raw WHERE clause from user input
  return await User.findAll({
    where: db.literal(filters.where)
  });
}

// ✅ Secure patterns
async function searchUsers(name) {
  // Parameterized query
  return await db.query(
    'SELECT * FROM users WHERE name = ?',
    [name]
  );
}

async function updateUser(id, data) {
  // Whitelist allowed columns
  const allowedColumns = ['name', 'email', 'bio'];
  const updates = {};

  for (const [key, value] of Object.entries(data)) {
    if (allowedColumns.includes(key)) {
      updates[key] = value;
    }
  }

  return await User.update(updates, {
    where: { id }
  });
}

async function findUsers(filters) {
  // Use ORM query builder
  return await User.findAll({
    where: {
      name: { [Op.like]: `%${filters.name}%` },
      active: true
    }
  });
}

Authorization Review

// Audit checklist:
// 1. Is authentication checked before authorization?
// 2. Are resource ownership checks present?
// 3. Is role-based access control implemented?
// 4. Are there direct object reference vulnerabilities?

// ❌ Insecure patterns
app.delete('/api/posts/:id', authenticate, async (req, res) => {
  // Issue: No authorization check!
  await Post.delete(req.params.id);
  res.status(204).send();
});

app.get('/api/documents/:id', async (req, res) => {
  // Issue: No authentication at all!
  const doc = await Document.findById(req.params.id);
  res.json(doc);
});

// ✅ Secure patterns
const authorize = (resource) => async (req, res, next) => {
  const item = await db[resource].findById(req.params.id);

  if (!item) {
    return res.status(404).json({ error: 'Not found' });
  }

  // Check ownership or admin role
  if (item.userId !== req.user.id && !req.user.isAdmin) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  req.resource = item;
  next();
};

app.delete('/api/posts/:id',
  authenticate,
  authorize('posts'),
  async (req, res) => {
    await req.resource.delete();
    res.status(204).send();
  }
);

// Role-based access control
const requireRole = (...roles) => (req, res, next) => {
  if (!req.user || !roles.includes(req.user.role)) {
    return res.status(403).json({ error: 'Insufficient permissions' });
  }
  next();
};

app.post('/api/admin/users',
  authenticate,
  requireRole('admin'),
  async (req, res) => {
    // Admin-only endpoint
  }
);

XSS and Output Encoding Review

// Audit checklist:
// 1. Is user input escaped in HTML context?
// 2. Is Content-Security-Policy header set?
// 3. Are dangerous functions (eval, innerHTML) avoided?
// 4. Is templating engine auto-escaping enabled?

// ❌ Vulnerable patterns
app.get('/search', (req, res) => {
  // Issue: No escaping
  res.send(`<h1>Results for: ${req.query.q}</h1>`);
});

app.post('/comment', async (req, res) => {
  // Issue: Storing unsanitized HTML
  await Comment.create({
    text: req.body.comment,
    html: req.body.comment // Dangerous!
  });
});

// Client-side issues
function displayComment(comment) {
  // Issue: Using innerHTML
  document.getElementById('comment').innerHTML = comment;

  // Issue: Using eval
  eval(comment);
}

// ✅ Secure patterns
const escape = require('escape-html');

app.get('/search', (req, res) => {
  res.send(`<h1>Results for: ${escape(req.query.q)}</h1>`);
});

// Or use templating with auto-escape
app.get('/search', (req, res) => {
  res.render('search', { query: req.query.q }); // Auto-escaped
});

// Content Security Policy
app.use((req, res, next) => {
  res.setHeader('Content-Security-Policy',
    "default-src 'self'; " +
    "script-src 'self'; " +
    "style-src 'self' 'unsafe-inline'; " +
    "img-src 'self' data: https:;"
  );
  next();
});

// Client-side: Use textContent
function displayComment(comment) {
  document.getElementById('comment').textContent = comment;
}

Compliance Auditing

GDPR Compliance Checklist

// GDPR Requirements Audit

// 1. Lawful Basis for Processing
// ✓ Explicit consent obtained
// ✓ Purpose clearly stated
// ✓ Option to withdraw consent

// 2. Data Minimization
// Review: Are we collecting only necessary data?
async function createUser(data) {
  // ❌ Collecting too much
  const user = {
    email: data.email,
    password: data.password,
    ssn: data.ssn,              // Unnecessary!
    medicalHistory: data.medical, // Unnecessary!
    location: data.location      // May be unnecessary
  };

  // ✅ Only essential data
  const user = {
    email: data.email,
    passwordHash: await hashPassword(data.password)
  };
}

// 3. Right to Access (Subject Access Request)
app.get('/api/gdpr/data', authenticate, async (req, res) => {
  const userData = {
    personalInfo: await User.findById(req.user.id),
    posts: await Post.findByUserId(req.user.id),
    comments: await Comment.findByUserId(req.user.id),
    loginHistory: await LoginHistory.findByUserId(req.user.id)
  };

  res.json(userData);
});

// 4. Right to Erasure (Right to be Forgotten)
app.delete('/api/gdpr/delete-account', authenticate, async (req, res) => {
  const userId = req.user.id;

  await db.transaction(async (tx) => {
    // Anonymize or delete personal data
    await User.anonymize(userId, tx);
    await Post.anonymizeByUser(userId, tx);
    await Comment.anonymizeByUser(userId, tx);

    // Keep audit logs (legal requirement)
    await AuditLog.create({
      action: 'account_deletion',
      userId,
      timestamp: new Date()
    }, tx);
  });

  res.status(204).send();
});

// 5. Right to Data Portability
app.get('/api/gdpr/export', authenticate, async (req, res) => {
  const data = await exportUserData(req.user.id);

  res.setHeader('Content-Type', 'application/json');
  res.setHeader('Content-Disposition', 'attachment; filename="my-data.json"');
  res.json(data);
});

// 6. Breach Notification (72 hours)
async function handleDataBreach(breach) {
  // Log breach
  await SecurityIncident.create({
    type: 'data_breach',
    severity: breach.severity,
    affectedUsers: breach.userIds.length,
    detectedAt: new Date()
  });

  // Notify authorities within 72 hours if high risk
  if (breach.severity === 'high') {
    await notifyDataProtectionAuthority(breach);
  }

  // Notify affected users
  for (const userId of breach.userIds) {
    await notifyUserOfBreach(userId, breach);
  }
}

// 7. Privacy by Design
// - Encryption at rest and in transit
// - Access controls
// - Audit logging
// - Data retention policies

// 8. Data Processing Agreement
// - Document third-party processors
// - Ensure processor compliance
// - Review contracts

SOC 2 Compliance Audit

// SOC 2 Trust Service Criteria

// 1. Security - Access Control
class AccessControlAudit {
  async auditUserAccess() {
    // Review user permissions
    const users = await User.findAll();
    const issues = [];

    for (const user of users) {
      // Check for overprivileged users
      if (user.role === 'admin' && !user.adminJustification) {
        issues.push({
          type: 'excessive_privilege',
          user: user.email,
          message: 'Admin access without justification'
        });
      }

      // Check for inactive users with access
      const daysSinceLogin = daysBetween(user.lastLoginAt, new Date());
      if (daysSinceLogin > 90) {
        issues.push({
          type: 'stale_access',
          user: user.email,
          message: `No login for ${daysSinceLogin} days`
        });
      }
    }

    return issues;
  }

  async auditAPIKeys() {
    const apiKeys = await APIKey.findAll();
    const issues = [];

    for (const key of apiKeys) {
      // Check for keys without expiration
      if (!key.expiresAt) {
        issues.push({
          type: 'no_expiration',
          keyId: key.id,
          message: 'API key has no expiration'
        });
      }

      // Check for unused keys
      if (!key.lastUsedAt ||
          daysBetween(key.lastUsedAt, new Date()) > 90) {
        issues.push({
          type: 'unused_key',
          keyId: key.id,
          message: 'API key not used in 90 days'
        });
      }
    }

    return issues;
  }
}

// 2. Availability - Monitoring
class AvailabilityAudit {
  async auditMonitoring() {
    const checks = [
      { name: 'Health checks configured', check: this.hasHealthChecks },
      { name: 'Uptime monitoring active', check: this.hasUptimeMonitoring },
      { name: 'Alert policies defined', check: this.hasAlertPolicies },
      { name: 'On-call rotation configured', check: this.hasOnCallRotation },
      { name: 'Backup systems tested', check: this.hasBackupTesting }
    ];

    const results = await Promise.all(
      checks.map(async (check) => ({
        name: check.name,
        passed: await check.check()
      }))
    );

    return results;
  }
}

// 3. Processing Integrity - Data Validation
class ProcessingIntegrityAudit {
  async auditDataValidation() {
    // Review all API endpoints for input validation
    const endpoints = [
      { path: '/api/users', method: 'POST' },
      { path: '/api/posts', method: 'POST' },
      // ... all endpoints
    ];

    const issues = [];

    for (const endpoint of endpoints) {
      const hasValidation = await this.checkValidation(endpoint);
      if (!hasValidation) {
        issues.push({
          endpoint: `${endpoint.method} ${endpoint.path}`,
          message: 'Missing input validation'
        });
      }
    }

    return issues;
  }
}

// 4. Confidentiality - Encryption Audit
class ConfidentialityAudit {
  async auditEncryption() {
    const issues = [];

    // Check encryption at rest
    const tables = await this.getDatabaseTables();
    for (const table of tables) {
      if (table.containsSensitiveData && !table.encrypted) {
        issues.push({
          type: 'encryption_at_rest',
          table: table.name,
          message: 'Sensitive data not encrypted'
        });
      }
    }

    // Check TLS configuration
    const tlsConfig = await this.getTLSConfig();
    if (tlsConfig.version < '1.2') {
      issues.push({
        type: 'weak_tls',
        message: 'TLS version below 1.2'
      });
    }

    // Check for hardcoded secrets
    const secrets = await this.scanForHardcodedSecrets();
    if (secrets.length > 0) {
      issues.push({
        type: 'hardcoded_secrets',
        count: secrets.length,
        message: 'Found hardcoded secrets in code'
      });
    }

    return issues;
  }
}

// 5. Privacy - Data Retention
class PrivacyAudit {
  async auditDataRetention() {
    // Check for data retention policies
    const policies = await DataRetentionPolicy.findAll();
    const issues = [];

    if (policies.length === 0) {
      issues.push({
        type: 'no_retention_policy',
        message: 'No data retention policies defined'
      });
    }

    // Check for old data
    const oldRecords = await this.findOldRecords();
    for (const record of oldRecords) {
      issues.push({
        type: 'old_data',
        table: record.table,
        count: record.count,
        message: `${record.count} records older than retention period`
      });
    }

    return issues;
  }
}

PCI-DSS Compliance

// PCI-DSS Requirements for Payment Card Data

// 1. Never store sensitive authentication data after authorization
// ❌ Don't store:
// - Full magnetic stripe data
// - CVV2/CVC2/CID
// - PIN/PIN blocks

// ✅ Can store (encrypted):
// - Primary Account Number (PAN)
// - Cardholder name
// - Expiration date
// - Service code

class PCICompliantPayment {
  async processPayment(cardData) {
    // ❌ Never log card data
    // console.log('Processing card:', cardData); // VIOLATION!

    // ✅ Use payment processor (tokenization)
    const token = await stripe.tokens.create({
      card: {
        number: cardData.number,
        exp_month: cardData.expMonth,
        exp_year: cardData.expYear,
        cvc: cardData.cvc
      }
    });

    // Store only token, not actual card data
    await Payment.create({
      userId: cardData.userId,
      amount: cardData.amount,
      stripeToken: token.id,
      last4: cardData.number.slice(-4), // OK to store
      // ❌ Don't store: cardNumber, cvv, etc.
    });

    const charge = await stripe.charges.create({
      amount: cardData.amount,
      currency: 'usd',
      source: token.id
    });

    return charge;
  }

  async auditCardDataStorage() {
    // Scan database for potential card data
    const suspiciousColumns = [
      'card_number', 'cvv', 'pin', 'magnetic_stripe'
    ];

    const issues = [];
    const tables = await this.getDatabaseTables();

    for (const table of tables) {
      for (const column of table.columns) {
        if (suspiciousColumns.includes(column.name.toLowerCase())) {
          issues.push({
            type: 'potential_card_data_storage',
            table: table.name,
            column: column.name,
            message: 'Possible storage of prohibited card data'
          });
        }
      }
    }

    return issues;
  }
}

// 2. Mask PAN when displayed
function maskCardNumber(pan) {
  // Show only last 4 digits
  return `****-****-****-${pan.slice(-4)}`;
}

// 3. Encryption of cardholder data
// - Use strong cryptography (AES-256)
// - Secure key management
// - Keys separate from data

Audit Reporting

Security Audit Report Template

class SecurityAuditReport {
  constructor() {
    this.findings = [];
    this.summary = {
      critical: 0,
      high: 0,
      medium: 0,
      low: 0,
      info: 0
    };
  }

  addFinding(finding) {
    this.findings.push({
      id: this.findings.length + 1,
      severity: finding.severity,
      title: finding.title,
      description: finding.description,
      location: finding.location,
      recommendation: finding.recommendation,
      references: finding.references || [],
      cvssScore: finding.cvssScore,
      status: 'open',
      discoveredAt: new Date()
    });

    this.summary[finding.severity]++;
  }

  generateReport() {
    return {
      reportDate: new Date(),
      auditor: 'Security Team',
      scope: this.scope,
      summary: this.summary,
      findings: this.findings.sort((a, b) =>
        this.severityWeight(b.severity) - this.severityWeight(a.severity)
      ),
      recommendations: this.generateRecommendations()
    };
  }

  severityWeight(severity) {
    const weights = { critical: 5, high: 4, medium: 3, low: 2, info: 1 };
    return weights[severity] || 0;
  }

  generateRecommendations() {
    return [
      'Address all critical and high severity findings immediately',
      'Implement security code review process',
      'Conduct regular penetration testing',
      'Provide security training for developers',
      'Establish vulnerability disclosure program'
    ];
  }
}

// Usage
const audit = new SecurityAuditReport();

audit.addFinding({
  severity: 'critical',
  title: 'SQL Injection in User Search',
  description: 'User search endpoint concatenates user input into SQL query',
  location: 'src/controllers/users.js:45',
  recommendation: 'Use parameterized queries or ORM with proper escaping',
  references: ['CWE-89', 'OWASP A03:2021'],
  cvssScore: 9.8
});

const report = audit.generateReport();

Best Practices

Audit Preparation

  1. Define scope and objectives
  2. Gather documentation
  3. Review previous audit findings
  4. Prepare audit checklist
  5. Schedule with stakeholders

During Audit

  1. Follow systematic approach
  2. Document all findings
  3. Collect evidence
  4. Maintain objectivity
  5. Communicate preliminary findings

Post-Audit

  1. Prepare detailed report
  2. Present findings to stakeholders
  3. Develop remediation plan
  4. Track remediation progress
  5. Schedule follow-up audit

Anti-Patterns to Avoid

Auditing own code: Use independent reviewers ❌ Incomplete scope: Define clear boundaries ❌ No follow-up: Track remediation to completion ❌ Generic findings: Provide specific, actionable recommendations ❌ Ignoring context: Consider business requirements ❌ No prioritization: Rank findings by risk and impact

Resources

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude Code

29%
按下载量换算224

OpenCode

20.2%
按下载量换算156

Codex

17.27%
按下载量换算134

Antigravity

13.56%
按下载量换算105

Gemini CLI

7.12%
按下载量换算55

windsurf

3.12%
按下载量换算24

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。

来源信息

继续浏览同类 Skills