mcpField
S
secure-checkout

secure-checkout

github.com/finsilabs安全6091 次安装5 天前更新
代码仓库

关于 secure-checkout

secure-checkout 面向构建或审计支付结账流程的开发者和店铺运营者,提供平台相关的安全指导,涵盖 TLS、CSP、支付令牌化及第三方脚本管理。

主要功能

  1. 01按平台提供结账安全指导
  2. 02TLS 与 HTTPS 配置
  3. 03CSP 与安全响应头实践
  4. 04支付令牌化指导
  5. 05第三方脚本审查

适用场景

  1. 01发现 XSS 后审计结账页面
  2. 02检查可接触支付表单的脚本
  3. 03准备 PCI DSS 合规评估
  4. 04迁移至自定义结账界面时加强安全

安装

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

$npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill secure-checkout

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

tile.json
evals/payment-tokenization-and-input-validatio/
criteria.json
task.md
evals/security-headers-and-csp-configuration/
criteria.json
task.md
evals/third-party-script-isolation-and-csp-vio/
criteria.json
task.md

详细介绍

安全结账

概述

支付页面是攻击者最觊觎的目标——单个 XSS 漏洞就可能引发类似 Magecart 的银行卡窃取攻击,导致数千个银行卡号失窃。保护结账安全需要在所有位置强制使用 TLS、实施严格的内容安全策略(CSP)以防止脚本注入、使用支付令牌化来尽量缩小 PCI 范围,并从支付页面移除非必要的第三方脚本。好消息是:Shopify 和 BigCommerce 会自动处理大部分基础设施。WooCommerce 商家需要配置托管服务并安装安全插件。自定义店面则需要从头实现所有这些控制措施。

何时使用此技能

  • 构建或审计接收支付信息的结账流程时
  • 渗透测试或安全扫描发现支付页面存在 XSS、CSP 或标头漏洞时
  • 审查能够访问支付表单上下文的页面上加载的第三方脚本时
  • 准备进行 PCI DSS SAQ A-EP 或 SAQ D 合规性评估时
  • 从托管支付页面迁移到自定义 UI 时(这会扩大 PCI 范围)

核心说明

步骤 1:了解不同平台下你承担的结账安全责任
平台HTTPS / TLSCSP 标头支付令牌化第三方脚本控制
Shopify自动处理 — Shopify 会签发并续订 SSL 证书Shopify 管理结账 CSP;需要审查你的主题页面Shopify Payments 和所有网关集成均使用令牌化使用 Shopify 的 Script Manager 和 Customer Events 控制结账时加载的内容
WooCommerce由你的托管服务负责 — 从 Let's Encrypt 或你的托管服务商处安装 SSL由你的服务器负责 — 通过托管服务或插件配置取决于你选择的网关(Stripe Elements = SAQ A-EP)WordPress 插件和主题脚本会全局加载;使用条件加载将其排除在结账页面之外
BigCommerce自动处理 — BigCommerce 会签发 SSL 并强制使用 HTTPSBigCommerce 管理托管结账的 CSP由你通过 BigCommerce 结账选择的支付网关处理BigCommerce Script Manager 控制第三方脚本的放置位置
自定义 / 无头由你的基础设施负责由你的应用负责 — 实施包含随机数的逐请求 CSP使用 Stripe Elements 或 Braintree Drop-in UI 实施拥有完全控制权,也承担全部责任 — 必须明确实施
步骤 2:按平台设置结账安全

Shopify

Shopify 托管的结账页面是最安全的方案之一——它运行在 Shopify 自有域名(checkout.shopify.com 或启用了 SSL 的自定义域名)上,使用 Shopify Payments 令牌化,并受 Shopify 的 CDN 和 WAF 保护。

强制使用 HTTPS:

  • Shopify 会自动为所有商店和自定义域名配置免费的 SSL 证书
  • 前往 Online Store → Domains,确认自定义域名上的 SSL 已启用
  • 在 Online Store → Preferences → Checkout and accounts 下启用 Redirect all traffic to HTTPS

结账页面上的第三方脚本: Shopify 的结账扩展模型(Checkout Extensibility)限制了结账页面上可运行的内容——这是为了符合 PCI 要求而设计的。

  1. 前往 Settings → Customer events,管理跟踪像素和脚本
  2. 通过 Customer Events 添加的脚本会在沙盒环境中运行,无法访问支付数据
  3. 不要通过主题代码或 ScriptTag API 向结账页面注入 JavaScript——这违反了 SAQ A 合规要求,并且可能会被 Shopify 拦截

主题安全审查:

  1. 前往 Online Store → Themes → Edit code
  2. 搜索主题中是否在购物车/结账页面引用了 document.cookie、localStorage 或 fetch——如果不是你有意添加的,这些都是危险信号
  3. 检查已安装的应用:前往 Settings → Apps and sales channels,移除不再使用的应用;每个已安装的应用都可能向你的店面注入脚本

管理员账户安全(减少攻击面):

  1. 前往 Settings → Users and permissions
  2. 要求所有员工账户启用双重身份验证(2FA)——攻击者修改结账行为最常见的方式是入侵管理员账户
  3. 将员工访问权限限制为其角色所需的权限

WooCommerce

WooCommerce 结账的安全性几乎完全取决于你的主机配置和支付网关。TLS 由主机提供商负责,而你选择的网关决定了卡数据是否会经过你的服务器。

步骤 1 — 强制商店使用 HTTPS:

  1. 在 WordPress 主机控制面板(cPanel、Kinsta、WP Engine)中,通过 Let's Encrypt 或主机内置证书启用免费 SSL
  2. 安装 Really Simple SSL(免费插件)——它会强制整个网站使用 HTTPS、更新内部链接,并一次性修复混合内容警告
  3. 激活后,在 Settings → SSL 中确认重定向已启用,且没有出现混合内容警告

步骤 2 — 选择不会让卡数据经过你服务器的支付网关:

  • Stripe (WooCommerce Stripe Payment Gateway) — 使用 Stripe Elements;在 Stripe iframe 中输入的卡数据不会经过你的服务器(SAQ A-EP)
  • Stripe Checkout (redirect) — 将客户重定向到 Stripe 托管页面;流程更简单(SAQ A)
  • PayPal Standard — 重定向到 PayPal;SAQ A
  • 避免使用任何要求你的服务器接收原始卡号的网关

步骤 3 — 安装安全插件:

  1. 安装 Wordfence Security(免费):前往 Wordfence → Firewall,将防护级别设为 "Extended Protection"——这会在 WordPress 应用层添加 WAF 规则
  2. 安装 WP Activity Log(约 $99/年)或 Simple History(免费):记录所有管理员操作,包括订单编辑、插件安装和设置更改
  3. 前往 Settings → Discussion——如果已启用,请在结账页和购物车页禁用评论(缩小 XSS 攻击面)

步骤 4 — 从结账页面移除脚本: 默认情况下,WooCommerce 会在每个页面加载所有已启用的插件。使用 Asset CleanUp Pro(一次性 $25)或添加条件 PHP 代码,以防止非必要脚本在结账时加载:

前往 WooCommerce → Settings → Advanced 并确认:

  • 调试日志记录已关闭(生产环境中,WP_DEBUG 在 wp-config.php 中必须为 false)
  • 没有自定义代码记录订单数据或支付详情

步骤 5 — 通过主机或插件配置 SSL 安全标头:

  1. 如果使用 Nginx 主机(Kinsta、WP Engine、Nexcess),请联系主机提供商添加 HSTS 和 X-Frame-Options 标头——这些标头通常已在托管式 WordPress 主机上预先配置
  2. 或者,安装 HTTP Headers(免费插件),无需编辑服务器配置,即可通过 WordPress 添加安全标头

BigCommerce

BigCommerce 托管式结账已通过 PCI-DSS Level 1 认证;使用受支持的支付网关时,TLS、CSP 和支付令牌化均由系统自动处理。

强制使用 HTTPS:

  • BigCommerce 会自动为所有商店配置并续期 SSL
  • 前往 Store Setup → Store Settings → Security,确认已启用 Force secure checkout
  • 前往 Storefront → SSL Certificate,确认自定义域名已启用 SSL

控制第三方脚本:

  1. 前往 Storefront → Script Manager
  2. 检查所有已安装的脚本,并查看每个脚本的 Placement 设置
  3. 对于无需在结账页面运行的脚本(分析、广告、聊天),将 Placement 设置为排除结账页面
  4. Script Manager 中的脚本在店面上下文中运行;BigCommerce 结账本身受单独且限制更严格的 CSP 保护

结账支付安全:

  • BigCommerce Payments 和经过认证的支付网关(Stripe、Braintree、PayPal)使用令牌化,因此银行卡数据不会经过 BigCommerce 或应用服务器
  • 前往 Store Setup → Payments,检查当前使用的支付网关;确保没有使用会向服务器“直接提交”数据的网关

管理员账户安全:

  1. 前往 Account Settings → Users
  2. 检查所有用户账户,移除离职员工和承包商的账户
  3. 确保所有活动账户都已在各自的账户安全设置中启用 2FA
  4. 前往 Settings → Advanced Settings → API Accounts,检查 OAuth 凭据;撤销所有未使用的 API 令牌

自定义 / 无头架构

对于自定义店面,所有结账安全控制措施都需要自行实施。最关键的三项是:支付令牌化(确保服务器永远不会接触银行卡号)、在支付页面设置严格的 CSP(防止 Magecart 注入),以及使用带有安全标头的 HTTPS。

使用 Stripe Elements 进行支付令牌化(SAQ A-EP):

// Client-side: Stripe handles card data in an iframe — your code never sees card numbers
const stripe = await loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!);
const elements = stripe.elements({ clientSecret });
const paymentElement = elements.create('payment');
paymentElement.mount('#payment-element');

// On submit: Stripe handles card capture; your server receives only a paymentIntentId
const { error, paymentIntent } = await stripe.confirmPayment({
  elements,
  confirmParams: { return_url: `${window.location.origin}/order-confirmation` },
});
// Your server confirms via paymentIntentId — never a card number

HTTPS 和安全标头(Next.js 示例):

// next.config.ts
export default {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
          { key: 'X-Frame-Options', value: 'DENY' },
          { key: 'X-Content-Type-Options', value: 'nosniff' },
          { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
          { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=(), payment=()' },
        ],
      },
      {
        // No caching on checkout; no indexing by search engines
        source: '/checkout(.*)',
        headers: [
          { key: 'Cache-Control', value: 'no-store, no-cache, must-revalidate' },
          { key: 'X-Robots-Tag', value: 'noindex' },
        ],
      },
    ];
  },
};

使用每次请求的 nonce 设置内容安全策略(防止 Magecart):

// middleware.ts — generate a new nonce per request; static nonces can be bypassed
export function middleware(request: NextRequest) {
  const nonce = Buffer.from(crypto.randomUUID()).toString('base64');

  const csp = [
    `default-src 'self'`,
    `script-src 'self' 'nonce-${nonce}' https://js.stripe.com`,
    `style-src 'self' 'nonce-${nonce}'`,
    `frame-src https://js.stripe.com https://hooks.stripe.com`,
    `connect-src 'self' https://api.stripe.com`,
    `img-src 'self' data: https:`,
    `object-src 'none'`,
    `base-uri 'self'`,
    `form-action 'self'`,
    `upgrade-insecure-requests`,
    `report-uri /api/csp-report`,
  ].join('; ');

  const response = NextResponse.next();
  response.headers.set('Content-Security-Policy', csp);
  response.headers.set('x-nonce', nonce); // Pass to layout for script nonce attributes
  return response;
}

CSP 违规监控:

// app/api/csp-report/route.ts — log violations; alert on checkout page violations
export async function POST(req: NextRequest) {
  const body = await req.json();
  const violation = body['csp-report'];

  await logger.warn('CSP Violation', {
    documentUri: violation['document-uri'],
    violatedDirective: violation['violated-directive'],
    blockedUri: violation['blocked-uri'],
  });

  // A CSP violation on a payment page may indicate an active Magecart attack
  if (violation['document-uri']?.includes('/checkout')) {
    await alertSecurityTeam('CSP violation on checkout page', violation);
  }

  return new NextResponse(null, { status: 204 });
}

使用 Zod 进行服务器端输入验证:

import { z } from 'zod';

const checkoutSchema = z.object({
  email: z.string().email().max(255),
  name: z.string().min(1).max(200).regex(/^[\p{L}\p{M}\s\-'.]+$/u),
  address: z.string().min(1).max(500),
  city: z.string().min(1).max(100),
  postalCode: z.string().min(1).max(20),
  country: z.string().length(2), // ISO 3166-1 alpha-2
});

export async function POST(req: NextRequest) {
  const body = await req.json();
  const result = checkoutSchema.safeParse(body);
  if (!result.success) {
    return NextResponse.json({ errors: result.error.flatten() }, { status: 400 });
  }
  // Proceed with validated data only
}

最佳实践

  • 将结账视为独立的安全区域——采用限制最严格的 CSP,禁用所有非必要的第三方脚本,并将支付页面上的任何 CSP 违规视为潜在的 Magecart 事件
  • 切勿在支付页面内联 JavaScript——使用基于 nonce 的 CSP 和外部脚本;在 script-src 中添加 'unsafe-inline' 会完全破坏 CSP 的作用
  • 移除非必要的应用和插件——每个已安装的 Shopify 应用、WordPress 插件或 BigCommerce 脚本都可能成为攻击面;移除商店中不再主动使用的所有内容
  • 为 CDN 脚本添加子资源完整性(SRI)——即使 CDN 遭到入侵,SRI 也能确保脚本内容未被篡改;使用 openssl dgst -sha256 -binary script.js | openssl base64 生成
  • 在边缘启用 WAF 防护——Cloudflare WAF(免费套餐)或托管服务提供商的 WAF 可在 OWASP Top 10 攻击抵达应用之前将其拦截
  • 在 CI 中扫描依赖项漏洞——运行 npm audit 并使用 Snyk 或 Dependabot;结账捆绑包中的 npm 软件包遭到入侵,其危险程度不亚于 Magecart 注入

常见陷阱

问题解决方案
CSP 导致 Stripe Elements iframe 无法正常工作将 https://js.stripe.com 和 https://hooks.stripe.com 添加到 frame-src;查看 Stripe 的 CSP 文档,获取当前完整的允许列表
为解除样式限制而添加 'unsafe-inline'改用 nonce 处理内联样式;'unsafe-inline' 会完全使该指令的 CSP 保护失效
TLS 证书过期使用自动续订的 Let's Encrypt(Certbot),或使用 CDN 提供的托管证书;Shopify 和 BigCommerce 会自动续订,只有 WooCommerce/自定义商店需要手动续订
分析脚本在结账页面加载在分析初始化代码中添加条件检查,跳过 /checkout 路由;在 Shopify 上使用 Customer Events 放置设置
可访问支付字段的第三方聊天挂件从结账页面中彻底移除聊天挂件;没有任何合理的客服场景需要读取支付表单的值

相关技能

  • @fraud-detection
  • @account-security
  • @bot-protection
  • @pci-dss-compliance
  • @gdpr-ecommerce

评论

支持 Markdown