技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
pci-dss-compliance【数据与研究】Achieve PCI DSS compliance for handling payment card data — scoping, controls, and SAQ selection. Use when storing, processing, or transmitting payment card data, building e-commerce security, or achieving payment processing compliance.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
PCI DSS (Payment Card Industry Data Security Standard) v4.0 applies to any organization that stores, processes, or transmits cardholder data (CHD). Maintained by the PCI Security Standards Council, it has 12 requirements across 6 goals. Non-compliance can result in fines of $5,000–$100,000/month and loss of card processing privileges.
The most effective compliance strategy is reducing scope — minimize the number of systems in the CDE.
// ✅ PCI DSS scope: SAQ A (minimal)
// Card data never touches your server — handled by Stripe.js
import { loadStripe } from '@stripe/stripe-js';
import { Elements, CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
const stripePromise = loadStripe('pk_live_...');
function PaymentForm() {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (event) => {
event.preventDefault();
// Card data goes directly to Stripe — never to your server
const { paymentMethod, error } = await stripe.createPaymentMethod({
type: 'card',
card: elements.getElement(CardElement),
});
if (!error) {
// Send only paymentMethod.id to your server
await fetch('/api/payments', {
method: 'POST',
body: JSON.stringify({ paymentMethodId: paymentMethod.id, amount: 2999 })
});
}
};
}
# ✅ Server-side: receives only token/payment method ID — not card data
import stripe
stripe.api_key = "sk_live_..."
def charge_customer(payment_method_id: str, amount_cents: int, currency: str = "usd"):
"""Process payment using token. CDE never touches card data."""
intent = stripe.PaymentIntent.create(
amount=amount_cents,
currency=currency,
payment_method=payment_method_id,
confirm=True,
automatic_payment_methods={"enabled": True, "allow_redirects": "never"}
)
return intent
| SAQ Type | Who Uses It | Scope |
|---|---|---|
| SAQ A | Card-not-present merchants using fully outsourced payment pages (Stripe Checkout, PayPal hosted) | Minimal — ~22 requirements |
| SAQ A-EP | E-commerce with JS-based payment forms (Stripe Elements, Braintree.js) | Medium — ~191 requirements |
| SAQ B | Merchants using standalone terminals, no electronic storage | Hardware terminals |
| SAQ B-IP | Merchants using IP-connected terminals | IP terminals |
| SAQ C | Merchants with payment app connected to internet | ~139 requirements |
| SAQ D | All other merchants and service providers | All 12 requirements |
Rule of thumb: If you use Stripe Checkout (hosted page), you qualify for SAQ A. If you use Stripe Elements (custom form with Stripe.js), you qualify for SAQ A-EP.
# Firewall rules — only allow necessary traffic to CDE
# Block all traffic by default, allow only what's needed
location /api/payments {
allow 10.0.0.0/8; # Internal services
deny all;
}
# ❌ NEVER store SAD (CVV, full magnetic stripe, PIN)
# ❌ NEVER store unencrypted PANs
# ✅ Store only masked PAN if needed
def mask_pan(pan: str) -> str:
"""Mask PAN per PCI DSS — show first 6 and last 4 only."""
if len(pan) < 13:
raise ValueError("Invalid PAN length")
return pan[:6] + "*" * (len(pan) - 10) + pan[-4:]
# Example: 4111111111111111 → 411111******1111
# ✅ Or store token from payment processor instead
# token = "tok_1234567890" — maps to real card in Stripe's vault
import ssl
import requests
# Always use TLS 1.2+ for any connection involving CHD
session = requests.Session()
session.mount('https://', requests.adapters.HTTPAdapter())
# Verify SSL certificates — never disable in production
response = session.get(
'https://api.stripe.com/v1/charges',
verify=True, # Never set to False in production
headers={'Authorization': f'Bearer {stripe_key}'}
)
# Secure coding — prevent injection in payment contexts
# ❌ Never log card data
import logging
def process_payment(card_number: str, amount: int):
# WRONG: logging.info(f"Processing card {card_number}")
logging.info(f"Processing payment for amount {amount}") # ✅ No CHD in logs
# Validate PAN format (Luhn algorithm)
def luhn_check(pan: str) -> bool:
"""Validate PAN with Luhn algorithm — use for format validation only."""
digits = [int(d) for d in pan.replace(" ", "").replace("-", "")]
odd_digits = digits[-1::-2]
even_digits = digits[-2::-2]
total = sum(odd_digits)
for d in even_digits:
total += sum(divmod(d * 2, 10))
return total % 10 == 0
# Role-based access — only billing/finance roles access payment records
PAYMENT_ACCESS_ROLES = {"billing_admin", "finance_manager", "cfo"}
def require_payment_access(func):
def wrapper(request, *args, **kwargs):
if request.user.role not in PAYMENT_ACCESS_ROLES:
raise PermissionError("Payment data access denied")
return func(request, *args, **kwargs)
return wrapper
# Log all access to cardholder data
def log_chd_access(user_id, action, last4, amount=None):
"""Compliance log for Req 10 — never log full PAN."""
entry = {
"timestamp": datetime.utcnow().isoformat(),
"user_id": user_id,
"action": action, # "view" | "charge" | "refund"
"card_last4": last4, # ✅ Only last 4 digits
"amount": amount,
"event_type": "chd_access"
}
audit_logger.info(json.dumps(entry))
Log retention: Minimum 12 months, with 3 months immediately available for analysis.
# Quarterly vulnerability scanning (approved scanning vendor required)
# Annual penetration testing
# Internal scan with nmap
nmap -sV --script vuln -oX vuln-scan-$(date +%Y%m%d).xml 10.0.1.0/24
# Run OWASP ZAP against payment pages
docker run -t owasp/zap2docker-stable zap-baseline.py \
-t https://yoursite.com/checkout \
-r zap-report-$(date +%Y%m%d).html
Customer → Stripe.js → Stripe Servers → Token returned to your app
↓
Card data never
touches your server
↓
Your Server → Receives token only → Stores token in DB
↓
Payment needed → Send token to Stripe API → Stripe processes → Result