Instrucciones de origen · Vista previa de solo lectura
name
pci-compliance
description
Master PCI DSS (Payment Card Industry Data Security Standard) compliance for secure payment processing and handling of cardholder data.
type
skill
created
2026-02-27T00:00:00.000Z
domain
security
category
compliance
risk
unknown
source
community
tags
["skill","security","compliance","pci"]
PCI Compliance
Master PCI DSS (Payment Card Industry Data Security Standard) compliance for secure payment processing and handling of cardholder data.
Do not use this skill when
The task is unrelated to pci compliance
You need a different domain or tool outside this scope
Instructions
Clarify goals, constraints, and required inputs.
Apply relevant best practices and validate outcomes.
Provide actionable steps and verification.
If detailed examples are required, open resources/implementation-playbook.md.
Use this skill when
Building payment processing systems
Handling credit card information
Implementing secure payment flows
Conducting PCI compliance audits
Reducing PCI compliance scope
Implementing tokenization and encryption
Preparing for PCI DSS assessments
PCI DSS Requirements (12 Core Requirements)
Build and Maintain Secure Network
Install and maintain firewall configuration
Don't use vendor-supplied defaults for passwords
Protect Cardholder Data
Protect stored cardholder data
Encrypt transmission of cardholder data across public networks
Maintain Vulnerability Management
Protect systems against malware
Develop and maintain secure systems and applications
Implement Strong Access Control
Restrict access to cardholder data by business need-to-know
Identify and authenticate access to system components
Restrict physical access to cardholder data
Monitor and Test Networks
Track and monitor all access to network resources and cardholder data
Regularly test security systems and processes
Maintain Information Security Policy
Maintain a policy that addresses information security
Compliance Levels
Level 1: > 6 million transactions/year (annual ROC required)
Level 2: 1-6 million transactions/year (annual SAQ)
Level 3: 20,000-1 million e-commerce transactions/year
Level 4: < 20,000 e-commerce or < 1 million total transactions
Data Minimization (Never Store)
# NEVER STORE THESE
PROHIBITED_DATA = {
: ,
: ,
:
}
ALLOWED_DATA = {
: ,
: ,
: ,
:
}
:
():
.prohibited_fields = [, , , ]
():
sanitized = data.copy()
sanitized:
card = sanitized[]
sanitized[] =
field .prohibited_fields:
sanitized.pop(field, )
sanitized
():
field .prohibited_fields:
field data:
SecurityError()
'full_track_data'
'Magnetic stripe data'
'cvv'
'Card verification code/value'
'pin'
'PIN or PIN block'
# CAN STORE (if encrypted)
'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
'cvv'
'cvv2'
'cvc'
'pin'
def
sanitize_log
self, data
"""Remove sensitive data from logs."""
# Mask PAN
if
'card_number'
in
'card_number'
'card_number'
f"{card[:6]}{'*' * (len(card) - 10)}{card[-4:]}"
# Remove prohibited data
for
in
self
None
return
def
validate_no_prohibited_storage
self, data
"""Ensure no prohibited data is being stored."""
for
in
self
if
in
raise
f"Attempting to store prohibited field: {field}"
Tokenization
Using Payment Processor Tokens
import stripe
classTokenizedPayment:
"""Handle payments using tokens (no card data on server).""" @staticmethoddefcreate_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 @staticmethoddefcharge_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
@staticmethoddefstore_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 detailsreturn {
'customer_id': customer_id,
'has_payment_method': True# DO NOT store: card number, CVV, etc.
}
Custom Tokenization (Advanced)
import secrets
from cryptography.fernet import Fernet
classTokenVault:
"""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 databasedeftokenize(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 mappingself.vault[token] = encrypted
return token
defdetokenize(self, token):
"""Retrieve card data from token."""
encrypted = self.vault.get(token)
ifnot encrypted:
raise ValueError("Token not found")
# Decrypt
decrypted = self.cipher.decrypt(encrypted)
return json.loads(decrypted.decode())
defdelete_token(self, token):
"""Remove token from vault."""self.vault.pop(token, None)
Encryption
Data at Rest
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
classEncryptedStorage:
"""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 bytesdefencrypt(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 + ciphertextreturn nonce + ciphertext
defdecrypt(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
Data in Transit
# 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 HTTPSfrom flask_talisman import Talisman
Talisman(app, force_https=True)
Access Control
from functools import wraps
from flask import session
defrequire_pci_access(f):
"""Decorator to restrict access to cardholder data.""" @wraps(f)defdecorated_function(*args, **kwargs):
user = session.get('user')
# Check if user has PCI access roleifnot user or'pci_access'notin user.get('roles', []):
return {'error': 'Unauthorized access to cardholder data'}, 403# Log access attempt
audit_log(
user=user['id'],
action='access_cardholder_data',
resource=f.__name__
)
return f(*args, **kwargs)
return decorated_function
@app.route('/api/payment-methods')@require_pci_accessdefget_payment_methods():
"""Retrieve payment methods (restricted access)."""# Only accessible to users with pci_access rolepass
import re
defvalidate_card_number(card_number):
"""Validate card number format (Luhn algorithm)."""# Remove spaces and dashes
card_number = re.sub(r'[\s-]', '', card_number)
# Check if all digitsifnot card_number.isdigit():
returnFalse# Luhn algorithmdefluhn_checksum(card_num):
defdigits_of(n):
return [int(d) for d instr(n)]
digits = digits_of(card_num)
odd_digits = digits[-1::-2]
even_digits = digits[-2::-2]
checksum = sum(odd_digits)
for d in even_digits:
checksum += sum(digits_of(d * 2))
return checksum % 10return luhn_checksum(card_number) == 0defsanitize_input(user_input):
"""Sanitize user input to prevent injection."""# Remove special characters# Validate against expected format# Escape for database queriespass