mcpField
P
pci-compliance

pci-compliance

github.com/wshobson安全41.9k10.7k 次安装2 周前更新
代码仓库

关于 pci-compliance

此技能为构建支付系统或处理持卡人数据的团队提供 PCI DSS 指南,涵盖标准要求、合规级别、数据最小化、令牌化及加密模式。

主要功能

  1. 01PCI DSS 要求概览
  2. 02合规级别参考
  3. 03持卡人数据最小化
  4. 04支付令牌化模式
  5. 05静态与传输中数据加密

适用场景

  1. 01设计安全支付流程
  2. 02准备 PCI DSS 评估
  3. 03减少卡数据暴露

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/wshobson/agents --skill pci-compliance

安装后在 Claude Code 中输入/pci-compliance确认已加载。

附带文件references/details.md

详细介绍

PCI 合规

掌握 PCI DSS(支付卡行业数据安全标准)合规,实现安全的支付处理和持卡人数据处理。

何时使用本技能

  • 构建支付处理系统
  • 处理信用卡信息
  • 实现安全支付流程
  • 开展 PCI 合规审计
  • 缩小 PCI 合规范围
  • 实现令牌化和加密
  • 为 PCI DSS 评估做准备

PCI DSS 要求(12 项核心要求)

构建并维护安全的网络
  1. 安装并维护防火墙配置
  2. 不要使用供应商提供的默认密码
保护持卡人数据
  1. 保护存储的持卡人数据
  2. 加密持卡人数据在公共网络上的传输
维护漏洞管理
  1. 保护系统免受恶意软件侵害
  2. 开发和维护安全的系统和应用程序
实施严格的访问控制
  1. 按业务需知原则限制对持卡人数据的访问
  2. 识别并验证对系统组件的访问
  3. 限制对持卡人数据的物理访问
监控并测试网络
  1. 跟踪并监控对网络资源和持卡人数据的所有访问
  2. 定期测试安全系统和流程
维护信息安全政策
  1. 维护一项涵盖信息安全的政策

合规级别

级别 1:每年 > 600 万笔交易(需要年度 ROC) 级别 2:每年 100 万 - 600 万笔交易(年度 SAQ) 级别 3:每年 20,000 - 100 万笔电子商务交易 级别 4:每年 < 20,000 笔电子商务交易或 < 100 万笔总交易

数据最小化(绝不存储)

# NEVER STORE THESE
PROHIBITED_DATA = {
    'full_track_data': 'Magnetic stripe data',
    'cvv': 'Card verification code/value',
    'pin': 'PIN or PIN block'
}

# CAN STORE (if encrypted)
ALLOWED_DATA = {
    'pan': 'Primary Account Number (card number)',
    'cardholder_name': 'Name on card',
    'expiration_date': 'Card expiration',
    'service_code': 'Service code'
}

class PaymentData:
    """Safe payment data handling."""

    def __init__(self):
        self.prohibited_fields = ['cvv', 'cvv2', 'cvc', 'pin']

    def sanitize_log(self, data):
        """Remove sensitive data from logs."""
        sanitized = data.copy()

        # Mask PAN
        if 'card_number' in sanitized:
            card = sanitized['card_number']
            sanitized['card_number'] = f"{card[:6]}{'*' * (len(card) - 10)}{card[-4:]}"

        # Remove prohibited data
        for field in self.prohibited_fields:
            sanitized.pop(field, None)

        return sanitized

    def validate_no_prohibited_storage(self, data):
        """Ensure no prohibited data is being stored."""
        for field in self.prohibited_fields:
            if field in data:
                raise SecurityError(f"Attempting to store prohibited field: {field}")

令牌化

使用支付处理商令牌
import stripe

class TokenizedPayment:
    """Handle payments using tokens (no card data on server)."""

    @staticmethod
    def create_payment_method_token(card_details):
        """Create token from card details (client-side only)."""
        # THIS SHOULD ONLY BE DONE CLIENT-SIDE WITH STRIPE.JS
        # NEVER send card details to your server

        """
        // Frontend JavaScript
        const stripe = Stripe('pk_...');

        const {token, error} = await stripe.createToken({
            card: {
                number: '4242424242424242',
                exp_month: 12,
                exp_year: 2024,
                cvc: '123'
            }
        });

        // Send token.id to server (NOT card details)
        """
        pass

    @staticmethod
    def charge_with_token(token_id, amount):
        """Charge using token (server-side)."""
        # Your server only sees the token, never the card number
        stripe.api_key = "sk_..."

        charge = stripe.Charge.create(
            amount=amount,
            currency="usd",
            source=token_id,  # Token instead of card details
            description="Payment"
        )

        return charge

    @staticmethod
    def store_payment_method(customer_id, payment_method_token):
        """Store payment method as token for future use."""
        stripe.Customer.modify(
            customer_id,
            source=payment_method_token
        )

        # Store only customer_id and payment_method_id in your database
        # NEVER store actual card details
        return {
            'customer_id': customer_id,
            'has_payment_method': True
            # DO NOT store: card number, CVV, etc.
        }
自定义令牌化(高级)
import secrets
from cryptography.fernet import Fernet

class TokenVault:
    """Secure token vault for card data (if you must store it)."""

    def __init__(self, encryption_key):
        self.cipher = Fernet(encryption_key)
        self.vault = {}  # In production: use encrypted database

    def tokenize(self, card_data):
        """Convert card data to token."""
        # Generate secure random token
        token = secrets.token_urlsafe(32)

        # Encrypt card data
        encrypted = self.cipher.encrypt(json.dumps(card_data).encode())

        # Store token -> encrypted data mapping
        self.vault[token] = encrypted

        return token

    def detokenize(self, token):
        """Retrieve card data from token."""
        encrypted = self.vault.get(token)
        if not encrypted:
            raise ValueError("Token not found")

        # Decrypt
        decrypted = self.cipher.decrypt(encrypted)
        return json.loads(decrypted.decode())

    def delete_token(self, token):
        """Remove token from vault."""
        self.vault.pop(token, None)

加密

静态数据
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

class EncryptedStorage:
    """Encrypt data at rest using AES-256-GCM."""

    def __init__(self, encryption_key):
        """Initialize with 256-bit key."""
        self.key = encryption_key  # Must be 32 bytes

    def encrypt(self, plaintext):
        """Encrypt data."""
        # Generate random nonce
        nonce = os.urandom(12)

        # Encrypt
        aesgcm = AESGCM(self.key)
        ciphertext = aesgcm.encrypt(nonce, plaintext.encode(), None)

        # Return nonce + ciphertext
        return nonce + ciphertext

    def decrypt(self, encrypted_data):
        """Decrypt data."""
        # Extract nonce and ciphertext
        nonce = encrypted_data[:12]
        ciphertext = encrypted_data[12:]

        # Decrypt
        aesgcm = AESGCM(self.key)
        plaintext = aesgcm.decrypt(nonce, ciphertext, None)

        return plaintext.decode()

# Usage
storage = EncryptedStorage(os.urandom(32))
encrypted_pan = storage.encrypt("4242424242424242")
# Store encrypted_pan in database
传输中的数据
# Always use TLS 1.2 or higher
# Flask/Django example
app.config['SESSION_COOKIE_SECURE'] = True  # HTTPS only
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Strict'

# Enforce HTTPS
from flask_talisman import Talisman
Talisman(app, force_https=True)

其他模式和模板

更详细的模板和完整示例位于 references/details.md。阅读该文件以获取完整的模式库。

评论

支持 Markdown