ISVforce 指南:构建和分发 AppExchange 解决 方案

作为独立软件供应商 (ISV) 建立蓬勃发展的 Salesforce 业务。开始者 加入 Salesforce 合作伙伴计划并熟悉对您有用的资源 AppExchange ISV 或咨询之旅。然后,学习计划、构建、分发、销售和支持 AppExchange 市场的解决方案。

  • 发行说明
    使用 Salesforce 发行说明了解 AppExchange 合作伙伴的最新更新和技术更改,包括打包、分析和安全编码工具。
  • 准备在 AppExchange 上分发 在 AppExchange
    上列出解决方案或咨询服务之前,请完成先决条件任务。首先,注册 Salesforce 合作伙伴计划。接下来,确认您有合作伙伴业务组织。然后,熟悉可帮助您高效导航合作伙伴旅程的资源和文档。
  • 使用托管软件包开发 AppExchange 解决方案
    托管软件包是 Salesforce 合作伙伴用来创建业务应用程序并通过 AppExchange 将其应用程序分发给客户的工具。托管软件包提供的功能套件可帮助您分发、许可、试用功能、排除故障并从产品中获利。
  • 设计您的 AppExchange 解决方案 了解影响 AppExchange 解决方案
    设计的体系结构概念和安全要求。
  • 通过 AppExchange 安全审核
    [生效日期:2023 年 8 月 9 日] 在 Salesforce,没有什么比客户的信任更重要。信任需要安全。要在 AppExchange 上分发托管软件包、Salesforce Platform API 解决方案或 Marketing Cloud API 解决方案,它必须通过我们的安全审查。了解如何准备并通过安全审查。
  • 在 AppExchange 上发布解决方案 使用 AppExchange
    合作伙伴控制台创建解决方案列表、启动安全审查、管理许可证设置以及查看列表的 Marketplace Analytics。
  • 使用 Checkout 在 AppExchange 上销售 使用 AppExchange Checkout
    直接从您的列表接受信用卡付款和银行转账。使用结账管理应用程序将您的销售和收入数据转化为见解和操作。
  • 使用 Analytics for AppExchange 合作伙伴
    监控性能 了解客户如何在 Marketplace Analytics 仪表板中找到您的 AppExchange 列表并与之交互。通过浏览 App Analytics 数据,了解订阅者如何使用您的套餐。
  • 使用 Channel Order App 向 Salesforce 报告订单 使用 Channel Order App
    (COA) 创建、管理订单并将其提交到 Salesforce。如果您是 OEM 合作伙伴,则可以使用 COA 来预配 Salesforce 许可证和收入分成。如果你是 ISV 合作伙伴,则可以使用 COA 进行收入分成。如果您使用 AppExchange Checkout 管理客户付款,请不要使用 COA。当客户购买您的 AppExchange 解决方案时,使用 Checkout 的合作伙伴的收入会自动报告给 Salesforce。
  • 提供 AppExchange 解决方案的免费试用 通过提供 AppExchange 解决方案
    的免费试用,提高客户转化率。探索试用选项,并确定解决方案的最佳类型。
  • OEM 用户许可证指南
    了解 OEM 合作伙伴可用的许可证类型。

准备好在 AppExchange 上分发

在 AppExchange 上列出解决方案或咨询服务之前,请完成 先决条件任务。首先,注册 Salesforce 合作伙伴计划。接下来,验证您是否 拥有合作伙伴业务组织。然后,熟悉可以 帮助您高效地驾驭合作伙伴之旅。

  • 加入 Salesforce 合作伙伴社区
    AppExchange 解决方案和咨询服务由 Salesforce 官方合作伙伴构建。要开始您的合作之旅,请加入 Salesforce 合作伙伴社区。
  • 验证对 Salesforce 合作伙伴业务组织的
    访问权限 作为 Salesforce 合作伙伴,您有资格加入合作伙伴业务组织 (PBO)。您的 PBO 包含用于设置和管理 AppExchange ISV 业务或咨询实践的工具。在开始构建解决方案或实践之前,请验证是否可以访问 PBO。
  • 申请 Salesforce 合作伙伴业务组织 如果您在加入 Salesforce 合作伙伴社区时未收到合作伙伴业务组织
    (PBO),请记录案例以请求。如果您在加入合作伙伴社区时创建了单独的用户名,请跳过此步骤。加入时,已自动预配 PBO。
  • 浏览面向 Salesforce 合作伙伴的学习资源 借助来自 Trailhead、合作伙伴社区等的精选资源,更快地实现 Salesforce 合作伙伴
    旅程中的里程碑并实现目标。

加入 Salesforce 合作伙伴社区

AppExchange 解决方案和咨询服务由 Salesforce 官方合作伙伴构建。 要开始您的合作之旅,请加入 Salesforce 合作伙伴社区。

您的业务目标决定了我们与您合作的方式。加入 Salesforce 合作伙伴之前 社区,了解 AppExchange ISV 和咨询合作伙伴关系。

提示

我们建议您为合作伙伴社区创建一个单独的用户名,甚至 如果您有现有的 Salesforce 用户名。通过这种方法,您可以立即访问您的 合作伙伴业务组织 (PBO),其中包含用于设置和管理 商。

  1. 转到 Salesforce 合作伙伴社区。
  2. 单击“成为合作伙伴”。
  3. 单击“继续”进行注册
  4. 单击加入合作伙伴社区
  5. 单击“获取 Salesforce 用户名”,然后填写所需的 领域。
  6. 单击创建用户名。我们会发送一封确认电子邮件,要求您验证您的帐户并设置 密码。
  7. 为您的帐户设置密码,然后单击“我有我的 Salesforce 用户名 – 加入合作伙伴社区。
  8. 登录到合作伙伴社区,然后完成剩余的设置任务。

验证对 Salesforce 合作伙伴业务组织的访问权限

作为 Salesforce 合作伙伴,您有资格加入合作伙伴业务组织 (PBO)。您的 PBO 包含用于设置和管理 AppExchange ISV 业务或咨询实践的工具。 在开始构建解决方案或实践之前,请验证是否可以访问 PBO。

  1. 登录 Salesforce,使用您在加入合作伙伴时创建的用户名和密码 社区。
  2. 单击应用程序启动器。
  3. 在“快速查找”框中,输入“Environment Hub”,然后单击“Environment Hub”。
  4. 如果重定向到 Environment Hub 应用,则表示你验证了 PBO 访问权限。如果 Environment Hub 应用程序在“快速查找”框中不可用,请在 Salesforce 帮助上记录案例以请求 PBO。

若要了解有关 PBO 的详细信息,请注册“了解合作伙伴业务组织” (PBO)Salesforce 合作伙伴学习营中的工具(需要登录)。

申请 Salesforce 合作伙伴业务组织

如果您在加入 Salesforce 时未收到合作伙伴业务组织 (PBO) 合作伙伴社区,记录案例以请求案例。如果您在加入时创建了单独的用户名 合作伙伴社区,请跳过此步骤。PBO 是自动预配的,当你 加入。

  1. 使用您注册 Salesforce 合作伙伴时所用的用户名登录 Salesforce 帮助 社区。
  2. 单击帐户切换器,并验证是否已选择您的合作伙伴帐户。
  3. 单击“联系支持人员”。
  4. 单击“创建案例”,然后填写必填字段。
    1. 对于主题,输入请求合作伙伴业务组织 (PBO)。
    2. 对于描述,请注意您是 Salesforce 合作伙伴,并且您正在请求 PBO。
    3. 当系统提示您选择产品时,单击“选择其他产品/” 主题
    4. 对于“产品”,选择“合作伙伴计划和权益”。
    5. 对于“主题”,选择“演示和合作伙伴业务组织”。
    6. 选择实例类型和严重性级别。
  5. 单击“创建案例”。

我们会审核案例,并与您联系以告知后续步骤。

浏览面向 Salesforce 合作伙伴的学习资源

借助 Salesforce 合作伙伴之旅,更快地达到里程碑并实现目标 来自 Trailhead、合作伙伴社区等的精选资源。

我想:推荐的资源
了解构建 AppExchange ISV 的基础知识 商。Trailhead:将您的业务发展为 AppExchange 合作伙伴
了解构建 Salesforce 咨询的基础知识 实践。Trailhead:将您的实践构建为 咨询合作伙伴
使用 AppExchange ISV 工具进行动手实践,并 技术,例如第二代托管包。Trailhead:将应用程序构建为 AppExchange 伙伴
了解构建安全的工具和最佳实践 解决 方案。Salesforce 开发人员:安全开发人员 中心
当我遇到困难时提出问题并获得帮助Salesforce 合作伙伴社区:问答社区 群
随时了解 Salesforce 合作伙伴的更改和更新 程序Salesforce 合作伙伴社区:官方:AppExchange 合作伙伴计划 社区组

使用托管包开发 AppExchange 解决方案

托管软件包是 Salesforce 合作伙伴用于创建业务应用程序的工具,以及 通过 AppExchange 将其应用程序分发给客户。托管提供的功能套件 软件包可帮助你分发、许可、试用功能、对产品进行故障排除以及从中获利。

程序包是您计划销售并分发给 Salesforce 的应用程序的容器 客户。创建一个包,然后添加包含的功能、自定义项和架构 你的应用。可以打包的元数据组件示例包括:

  • Apex 类和触发器
  • 标准对象上的自定义字段
  • 自定义元数据类型
  • 自定义对象
  • 闪电页面
  • 页面布局

您的包可以包含许多不同的元数据组件,也可以打包单个 组件,例如流。

Salesforce 提供第二代托管打包(托管 2GP)和第一代 托管打包(托管 1GP)。展望未来,我们建议每个人都使用托管 2GP 来 创建新应用。有关使用第二代托管打包的优势的详细信息,请参阅为什么要切换到第二代托管打包 包装?

设计您的 AppExchange 解决方案

了解影响 AppExchange 的架构概念和安全要求 解决方案设计。

注意

构建新应用?您是否考虑过使用第二代 托管软件包?灵活的版本控制和跨包共享命名空间的能力是 开发人员喜欢创建第二代托管包的两个原因。我们认为你会 也喜欢它。若要了解详细信息,请参阅:为什么要切换到第二代托管 封装以及第一代和第二代的比较 托管包。

  • AppExchange 合作伙伴和解决方案
    的安全要求 [生效日期:2023 年 8 月 9 日] 作为 Salesforce 合作伙伴,您负责实施和维护全面的安全计划,并维护您在 AppExchange 上列出或根据 AppExchange 合作伙伴计划分发的所有应用程序的安全性。
  • 组版和专业版的体系结构注意事项

AppExchange 合作伙伴和解决方案的安全要求

【生效日期:2023年8月9日】作为 Salesforce 合作伙伴,您负责 实施和维护全面的安全计划,并维护 您在 AppExchange 上列出或在 AppExchange 合作伙伴下分发的所有应用程序 程序。

注意

AppExchange 合作伙伴和解决方案的这些安全要求(以下简称“要求”)是 截至所列生效日期为止,并一直有效,直到或除非它们 在此相同或重定向的 URL 上被生效日期较晚的版本取代。SFDC可以 不时自行决定更新或修改这些要求,无论是否 通知。这些要求受 AppExchange 合作伙伴计划的约束,并成为 AppExchange 合作伙伴计划的一部分 政策和 Salesforce 合作伙伴计划协议 (“SPPA”),见 https://www.salesforce.com/company/legal/agreements/。本要求中未定义的大写术语具有以下含义 在SPPA中给予他们。

重要

合作伙伴应用程序,包括托管软件包、Salesforce Platform API 解决方案、Marketing Cloud API 解决方案以及本文提及的其他解决方案, 是 Salesforce 主要服务协议中定义的非 SFDC 应用程序(可在 https://www.salesforce.com/company/legal/agreements 或后续 URL)。尽管有 对合作伙伴应用程序进行安全审查时,Salesforce 不保证其质量 或任何合作伙伴应用程序的安全性,客户有责任评估 合作伙伴应用程序的质量、安全性和功能。

作为参与 AppExchange 合作伙伴计划的条件,您必须遵守 本文档中概述的安全要求。这些要求包括一般 适用于所有 AppExchange 合作伙伴和合作伙伴应用程序的要求,以及其他要求 特定于使用特定 或与特定 技术或旨在用于特定行业。在这些要求中,合作伙伴 应用程序也称为“解决方案”。创建或编辑 AppExchange 时 发布时,您需要确认自己符合这些要求。

本文档中的安全要求并不详尽。我们鼓励合作伙伴 遵循所有适用的行业安全标准。

一般 AppExchange 要求

  1. 所有合作伙伴都必须遵守安全策略中所述的要求 要求。
  2. 所有合作伙伴应用程序都必须符合防止安全编码冲突中所述的要求。
  3. 所有合作伙伴应用程序都必须通过 Salesforce 安全审查和评估,其中 根据 AppExchange 合作伙伴计划政策的要求。

B2C 商务解决方案安全要求

如果您的合作伙伴应用程序是 B2C Commerce Cartridge 或 Headless Integration,则必须 此外,请遵循保护您的 B2C 商务解决方案中所述的要求。这些 B2C Commerce 特定要求是另外的 到一般 AppExchange 要求。

Tableau Accelerator 安全要求

如果您的合作伙伴应用程序是 Tableau 加速器,您还必须遵循这些要求 在保护您的 Tableau 加速器中进行了介绍。这些 Tableau 特定要求 是对一般 AppExchange 要求的补充。

  • 安全策略要求 要求
    :在 AppExchange 上列出解决方案之前,您必须有一个安全计划来证明贵公司对安全的承诺。此外,为了帮助客户评估解决方案的质量,必须与他们共享计划信息。
  • 防止安全编码违规
    AppExchange 上列出的所有解决方案都必须遵守这些 AppExchange 安全要求。了解哪些违规行为最有可能出现在 AppExchange 解决方案中,它们为什么会带来安全风险,以及如何创建有助于避免这些风险的解决方案。
  • 保护您的 B2C 商务解决方案
    AppExchange 上列出的所有 B2C Commerce Cartridge 和 Headless 集成都必须遵守这些要求。
  • 保护您的 Tableau 加速器 AppExchange 上列出的
    所有 Tableau 加速器都必须遵守这些要求。

安全策略要求

要求:在 AppExchange 上列出解决方案之前,必须具有安全性 证明贵公司对安全的承诺的计划。另外,为了帮助客户 评估解决方案的质量,您必须与他们共享您的计划信息。

建议:我们建议在程序中包含这些元素。

指定安全专家

集成安全性后,可以更轻松地保护解决方案免受安全威胁 考虑进入开发的各个阶段。确保您的 解决方案遵循安全准则,即为您的开发指定一名安全专家 团队。让您的整个开发团队与安全专家协作完成所有工作 开发阶段:设计、实现和测试。推迟安检 在开发的最后阶段之前的注意事项会增加您的团队的可能性 在不知不觉中传播安全违规行为。定期协作可防止 不必要地积累安全违规行为,并有助于避免准备 成功提交 AppExchange 安全审查。

实施安全策略

制定企业安全策略,详细说明贵公司如何保护客户资产, 例如用户数据。告知客户他们可以采取哪些活动来帮助确保 从头到尾的解决方案。

列出服务和项目

列出解决方案中包含的服务和项目,例如 Web 和移动解决方案。 Web 服务、API 和 SDK。

清点第三方库

保留第三方库和 正确操作的解决方案。

创建架构图

提供显示数据接触点、信息流、 身份验证、授权和其他安全控制。

列出认证

共享所有适用的认证报告,例如:

  • HIPAA:健康保险流通与责任法案
  • PCI DSS:支付卡行业数据安全标准
  • SOC 2:系统和组织控制 管理客户数据的 2 个标准
  • ISO27001:信息安全管理

获取第三方审核

让独立的第三方进行安全审计。与您的分享摘要 客户。

文档安全保证活动

记录公司级别的安全保障活动,包括:

  • 软件开发生命周期 (SDLC) 方法
  • 漏洞管理
  • 修正服务级别协议 (SLA)
  • 供应商和依赖安全计划
  • 安全意识培训
  • 安全漏洞响应程序

列出敏感数据

列出解决方案处理或存储的所有敏感数据,例如付款方式 数据、个人数据和健康数据。

披露数据存储位置和提供商

如果解决方案存储或处理受管制的数据,例如个人身份数据 和健康数据,披露数据存储位置列表。确定国家/地区和提供商 例如 Amazon Web Services (AWS)、Azure 和 Google Cloud Platform (GCP)。

识别第三方数据共享

提供您与之共享客户数据的第三方供应商列表。

分享联系方式

发布联系信息,以便客户轻松获得支持和报告 安全事件。

防止安全编码违规

AppExchange 上列出的所有解决方案都必须遵守这些 AppExchange 安全性 要求。了解哪些违规行为最有可能出现在 AppExchange 解决方案中,以及为什么会出现这些违规行为 构成安全风险,以及如何创建有助于避免这些风险的解决方案。

  • 从第三方终结点
    加载 JavaScript 文件 避免从内容分发网络 (CDN) 动态加载第三方 JavaScript 文件。相反,请从包的静态资源文件夹中加载代码。
  • 在 Lightning 组件
    中加载第三方 CSS 包括级联样式表 (CSS) 和其他静态资源中的资源,而不是从第三方加载。
  • 使用 CSS 外部组件
    Salesforce Platform 试图确保每个命名空间都是一个隔离的沙盒,但不能始终保证隔离。如果发生命名空间隔离漏洞,一个组件可能会窃取另一个组件的点击,或以其他方式干扰另一个组件的预期用途。为了防止这种类型的滥用,请不要使用已知与组件中的样式隔离不兼容的 CSS 指令。
  • 在 Salesforce 域
    中运行 JavaScript 来自多个供应商的 JavaScript 代码可以在同一源中运行。为了防止代码干扰,供应商的 JavaScript 代码被沙盒化。不要尝试跳出沙盒或在源之外运行代码。使用 Visualforce、Aura 或 Lightning Web 组件,它们在正确的源中运行。
  • 调试
    时暴露机密数据 在生产环境中,使用 debug 语句记录机密数据是一个安全漏洞。不要在生产环境中记录机密数据、敏感信息、密码、密钥或堆栈跟踪。编辑数据或从日志中省略数据。
  • 不安全地存储敏感数据 当您从 Salesforce Platform 导出数据以及在平台中存储机密数据时,
    请遵循企业安全标准。
  • 使用具有已知漏洞的软件
    使用记录了与您的用例相关的常见漏洞和暴露 (CVE) 的软件是一个安全漏洞。如果您的解决方案存在已知漏洞,请在安全补丁可用时立即对其进行测试和部署。如果您的解决方案使用的软件具有与您的用例无关的 CVE 记录的漏洞,请准备误报文档。
  • 在生产环境中
    使用示例代码 仅将示例代码用作准备开发自己的应用程序的教育工具。构建生产代码时,请始终自己编写代码。避免从不直接控制的源复制代码。
  • 绕过对象级和字段级访问设置 设计解决方案以在标准和自定义对象上强制执行组织的创建、读取、更新和删除 (CRUD) 和字段级安全性 (FLS) 设置
  • 绕过 Apex 中的共享规则 在 Apex
    代码中尊重基于配置文件的权限、字段级安全性、共享规则和组织范围的默认值。
  • 由于数据库查询构造不安全导致的 SOQL 注入 要防止 Salesforce 对象查询语言 (SOQL) 注入,请使用绑定变量和输入卫生。
  • 跨站点请求伪造 跨站点请求伪造
    (CSRF) 是一种攻击,它迫使最终用户在其经过身份验证的 Web 应用程序会话期间执行不需要的操作。要防止 CSRF,请使用 或通过用户操作触发状态更改。confirmationTokenRequired
  • 打开重定向 当应用程序在未经任何验证的情况下动态重定向
    到用户控制的参数值时,就会发生打开重定向。使用硬编码重定向来防止打开重定向。
  • Lightning LockerService 已禁用
    Lightning LockerService 是 Lightning 代码的一项关键安全功能。它提供组件隔离,允许来自多个来源的代码使用安全、标准的 API 和事件机制执行和交互。为包含 Lightning 组件或应用程序的 AppExchange 软件包启用 Lightning Locker。
  • Lightning 组件中的转义不足 捆绑包中的每个组件都负责清理父组件
    、应用程序或 URL 参数提供给它的输入。
  • 组件
    中的异步代码 黑客可以操纵异步代码的时序来产生恶意结果。若要保留当前执行上下文,请将异步函数调用或批处理操作包装到单个请求中。
  • 安全通信
    确保只能通过安全连接(如 SFTP 和 HTTPS)访问解决方案。避免使用 HTTP 和 FTP,因为这些协议不会加密通过 Internet 传输的信息。

从第三方端点加载 JavaScript 文件

避免从内容分发网络动态加载第三方 JavaScript 文件 (CDN)。相反,请从包的静态资源文件夹中加载代码。从 CDN 或其他第三方动态加载第三方 JavaScript 文件不是 允许有两个原因。

  • 必须使用包版本 ID 对整个解决方案进行版本控制,以便有一个 定义明确的产品以供审查和跟踪。如果解决方案从 第三方终结点,外部托管代码可以在没有包的情况下进行更改 版本 ID 更改。管理员和 Salesforce 安全审查团队不是 意识到了这一变化。Salesforce 无法确保第三方代码继续 防范最新的安全漏洞。确保代码是 受制于包版本控制,从静态动态加载代码 resources 文件夹。如果不更改 软件包版本 ID。另外,版本 ID 更改会向管理员发出信号,并且 AppExchange 安全团队认为代码已更改。
  • 从第三方终结点动态加载代码可授予该终结点功能 将代码注入到安装软件包的任何 Salesforce 组织中。只 从 Salesforce 批准的 CDN 动态加载代码,由 Salesforce 管理代码, 而不是合作伙伴。

概括地说,解决方案是:

  1. 将第三方 JavaScript 文件保存在静态资源中。
  2. 将资源添加到解决方案包中。
  3. 从 URL 加载每个 JavaScript 文件。$Resource

Visualforce 示例

这些代码片段描述了安全违规以及如何在 Apex 和 for 中修复它 Aura 中的闪电组件。此 Visualforce 代码不安全,因为加载了 jQuery 来自第三方来源。

<apex:includescript value="https://code.jquery.com/jquery-3.2.1.min.js"/>

此 Visualforce 代码是安全的,因为它从静态加载 jQuery 的一个版本 resources 文件夹。

$Resource

<apex:includeScript value="{! $Resource.jQuery }"/>

光环示例

此 Aura 组件代码不安全,因为 jQuery 直接从第三方加载 源。

<aura:component>
   <ltng:require afterScriptsLoaded="{!c.initializeUI}"
   scripts="https://code.jquery.com/jquery-2.2.0.min.js”/>
<aura:component>

此 Aura 组件代码是安全的,因为 jQuery 是从解决方案包加载的,并且 使用 URL 作为静态资源引用。$Resource

<aura:component>
   <ltng:require afterScriptsLoaded="{!c.initializeUI}"
   scripts="{!$Resource.jsLibraries + '/jsLibOne.js'}"/>
<aura:component>

在 Lightning 组件中加载第三方 CSS

将级联样式表 (CSS) 和其他资源包含在静态资源中 而不是从第三方加载。

强制执行此要求的原因与从第三方终结点加载 JavaScript 文件中概述的原因相同。整个 解决方案必须受版本控制,并且组织管理员和 Salesforce 安全性 审核团队必须了解这一变化。

使用标签加载外部 CSS 资源违反了此安全策略。<link>概括地说,解决方案是:

  1. 将第三方 CSS 文件保存在静态资源中。
  2. 将资源添加到解决方案包中。
  3. 使用标签引用 CSS 在 .cmp 或 .app 标记中。<ltng:require>

有关更多信息,请参阅在 Lightning Aura 组件开发人员指南。

光环示例

这些代码片段描述了安全违规以及如何在 Lightning 中修复它 Aura 中的组件。此 Aura 组件代码不安全,因为它使用标签来加载外部 CSS 资源。

<link>

<aura:component>
     <link rel="stylesheet" href="https://example.com/styles.css" type="text/css">
<aura:component>

此 Aura 组件代码使用 ,其中 是引用作为静态上传的外部 CSS 资源的更安全方法 资源。

<ltng:require>

<aura:component>
    <ltng:require styles="{!$Resource.SLDSv1 + '/assets/styles/lightning-design-system-ltng.css'}" />
</aura:component>

使用 CSS 外部组件

Salesforce Platform 尝试确保每个命名空间都是一个隔离的沙盒,但 隔离并不总是得到保证。在发生命名空间隔离漏洞时,一个组件 可以从另一个组件窃取点击,或以其他方式干扰另一个组件的 有可能的用途。为了防止这种类型的滥用,不要使用已知不兼容的CSS指令 在组件中实现样式隔离。

CSS 示例

此 CSS 代码容易受到攻击,因为它使用不兼容的绝对定位 有风格 隔离。

#some_element {
   position: absolute;
   right: 80px;
   top: 160px;
}

此 CSS 代码通过使用相对 定位。

#some_element_revised {
   position: relative;
   right: 80px;
   top: 160px;
}

有关详细信息,请参阅组件中的 CSS 提示 Lightning Aura 组件开发人员指南。

在 Salesforce 域中运行 JavaScript

来自多个供应商的 JavaScript 代码可以在同一源中运行。防止代码 干扰,供应商 JavaScript 代码是沙盒的。不要试图冲出沙盒或 在源外部运行代码。使用 Visualforce、Aura 或 Lightning Web 组件,它们在 正确的来源。

许多不同类型的 JavaScript 代码在 Salesforce 组织中运行,包括未打包的 客户代码、Salesforce 代码和打包代码。通常,代码来自多个 无法相互协作的供应商。如果他们的代码运行在同一个 来源,来自一个供应商的代码可能会干扰其他供应商的代码。

为了防止代码干扰,供应商的 JavaScript 代码被沙盒化。使用 Visualforce 解决方案中,JavaScript 代码在特定于供应商的唯一来源中进行沙盒化。使用闪电 解决方案和 Lightning Web 组件 (LWC),JavaScript 被沙盒化为独特的, 特定于供应商的储物柜。

任何试图突破沙盒并在源之外运行代码的尝试都是一种安全编码 违反。安全编码冲突包括尝试运行供应商编写的 JavaScript 代码 在 Salesforce 源中通过主页组件、Web 链接或自定义按钮。

在大多数情况下,您可以使用 Visualforce、Aura 或 Lightning Web 组件,在正确的源中运行。

元数据示例

此示例中的元数据表示自定义对象。此自定义中的 Web 链接 对象是使用语句定义的。在一个 托管包,使用是一种安全性 漏洞,因为供应商正在将其代码注入 Salesforce 源。管理 包必须保留在其命名空间沙箱中,并且不能在此沙箱之外执行脚本 沙盒。

REQUIRESCRIPTREQUIRESCRIPT

<?xml version=”1.0”encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<actionOverrides>
<actionName>Accept</actionName>
      <type>Default</type>
</actionOverrides>
<webLinks>
     <fullName>Add_to_List</fullName>
     <openType>onClickJavaScript</openType>
     <url>{!REQUIRESCRIPT(&quot;/soap/ajax/30.0/connection.js&quot;)}</url>
</webLinks>
...
</CustomObject>

与其将代码直接嵌入到对象中,不如在 Visualforce Aura 组件,或使用 Lightning Web 组件。

调试时公开机密数据

在生产环境中,使用 debug 语句记录机密数据是一种安全性 脆弱性。不要在 生产环境。编辑数据或从日志中省略数据。

使用 debug 语句泄露机密数据会使 Salesforce 组织管理员感到困难 来控制对数据的访问。通常,允许查看日志的配置文件不是 允许查看机密的相同配置文件。

Apex 示例

在此 Apex 代码中,是一个 写入调试日志的加密密钥。若要避免此漏洞,请从生产中删除该语句 法典。

authenticationTokensystem.debug

if (varCount > 0){
   sensitiveUserData = JSON.serialize(AssignUsrs);
   ReqSignature = RequestWrapper.generateHmacSHA256Signature(sensitiveUserData, authenticationToken);
   system.debug('Token--->'+authenticationToken);
}

不安全地存储敏感数据

从 Salesforce Platform 导出数据时遵循企业安全标准 以及当您在平台中存储机密数据时。

不安全的敏感数据存储为黑客提供了许多构成威胁的途径。为 例如,组织管理员是唯一应该知道 API 密钥的人。 黑客可以使用公开的密钥通过管理通道将数据传送到远程 端点。

Salesforce 会认真对待源自解决方案的数据威胁。数据泄露 或因解决方案中的漏洞而造成的损失危及您与 Salesforce的。在以下情况下,请遵循存储敏感数据中的企业标准:

  • 从 Salesforce 平台导出客户数据。
  • 将加密密钥、会话 ID 或密码等密钥存储在 Salesforce平台。

元数据示例

此示例中的元数据表示自定义对象。此自定义对象定义 不安全,因为 API 的标记 key 字段设置为 。该字段可以在 平原 发短信。

<visibility>Public

<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
   <fields>
        <fullName>apiKey__c</fullName>
        <externalId>false</externalId>
        <fieldManageability>DeveloperControlled</fieldManageability>
        <label>apiKey</label>
        <length>50</length>
        <required>false</required>
        <type>Text</type>
        <unique>false</unique>
   </fields>
   <label>Phone Verify Setting</label>
   <pluralLabel>Phone Verify Settings</pluralLabel>
   <visibility>Public</visibility>
</CustomObject>

将密钥存储在自定义对象(如 API 密钥)中时,请对其进行加密。存储 加密密钥分别在受保护的自定义设置或受保护的自定义元数据 API 中 田。

使用具有已知漏洞的软件

使用记录了常见漏洞和暴露 (CVE) 相关漏洞的软件 您的用例是一个安全漏洞。如果解决方案存在已知漏洞,请进行测试 并在安全补丁可用时立即部署它们。如果您的解决方案使用以下软件: 具有 CVE 记录的与您的用例无关的漏洞,请准备误报 文档。

黑客可以快速攻击已披露的软件漏洞。大多数供应商提供 针对其软件中发现的漏洞进行修补或更新。要了解您的 解决方案使用具有已知漏洞的软件,请检查常见漏洞和披露 (CVE) 数据库。

应用与解决方案用例相关的所有修补程序或更新。如果漏洞 与您的使用案例无关,并且您正在为 AppExchange 准备解决方案 安全审查,将其记录为误报。解释为什么它对你的解决方案是安全的 以使用易受攻击的软件。我们的安全审查团队在做出决定时会使用此信息 是否批准在解决方案中使用该软件。有关详细信息,请参阅误报。

在生产环境中使用示例代码

仅使用示例代码作为教育工具,为开发自己的代码做准备 应用。构建生产代码时,请始终自己编写代码。避免复制 来自您不直接控制的来源的代码。

互联网上的开发人员可以使用很棒的示例代码。虽然在 学习最佳实践或新技术,不要直接在 生产包。直接重用可能会在许多包中传播漏洞, 无论示例代码作者是否有意为之。

绕过对象级和字段级访问设置

设计解决方案以强制执行组织的创建、读取、更新和删除 (CRUD) 和 标准对象和自定义对象上的字段级安全性 (FLS) 设置。

在 Salesforce Platform 上,您可以在配置文件和 权限集。CRUD 设置确定用户可以访问哪些对象。FLS 确定 用户可以访问哪些对象字段。使用 CRUD 和 FLS 限制对标准和 自定义对象和单个字段。

客户希望你的解决方案不会违反他们在 组织。设计解决方案,以在标准和 自定义对象。此外,请确保您的解决方案能够正常处理用户 访问受到限制。在某些用例中,绕过 CRUD 和 FLS 是可以接受的,例如在以下情况下:

  • 创建不直接公开数据的汇总摘要或聚合。
  • 修改自定义对象或字段,例如日志或系统元数据,以便它们 用户无法通过 CRUD 或 FLS 直接访问。
  • 从高特权方法访问对象,非管理员用户无法访问的方法 访问。
  • 当您的解决方案是社区或 网站。
  • 使用自定义安全策略访问属于命名空间的自定义对象。 在这种情况下,请将策略记录为 AppExchange 安全审查的一部分 提交。

若要了解有关 CRUD 和 FLS 强制执行的详细信息,请查看安全服务器端开发 模块。若要检测代码中的 CRUD/FLS 冲突,请考虑使用 代码扫描器,如 Salesforce Code Analyzer 的 Salesforce Graph Engine。

Apex 示例

在此 Apex 代码中,数据 操作语言 (DML) 语句在不检查用户是否具有创建访问权限的情况下运行 Account 对象的权限。该代码不会强制执行组织的访问权限 设置。

insert account

public static Account createIndividualModalData(String name, String email, String mobile) {
   RecordType recordType = [Select Id from RecordType where DeveloperName = 'IndustriesIndividual' and SobjectType = Account'];
   Account account = new Account();
   account.Name = name;

   if(recordType != null) account.RecordTypeId = recordType.id;
   insert account;
    ...
}

此 Apex 代码更安全,因为它强制执行组织的访问设置。它在执行 DML 语句之前调用该方法。如果返回 true,则用户具有创建访问权限 Account 对象的权限,并执行语句。否则,访问不足错误是 报道。

isCreatable()insert accountisCreatable()insert account

public static Account createIndividualModalData(String name, String email, String mobile) {
   RecordType recordType = [Select Id from RecordType where DeveloperName = 'IndustriesIndividual' and SobjectType = 'Account'];
   Account account = new Account();
   account.Name = name;

   if(recordType != null) account.RecordTypeId = recordType.id;

   if (Schema.sObjectType.Account.isCreateable()) {
      insert account;
   } else {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'Error: Insufficient Access'));
   }
   ...
}

绕过 Apex 中的共享规则

尊重基于配置文件的权限、字段级安全性、共享规则和组织范围 默认值。

Salesforce Platform 广泛使用数据共享规则。每个对象可以有 指示哪些用户和配置文件可以读取、创建、编辑和删除的唯一权限 该对象类型的记录。当您的代码使用标准 控制器。

但是,自定义 Apex 类或 Visualforce 页面本质上并不遵循内置 配置文件权限、字段级安全限制或共享规则。默认情况下,一个 Apex 类可以读取和更新组织内的所有数据。

在 Apex 代码中,不要公开对用户隐藏的敏感数据。尊 基于配置文件的权限、字段级安全性、共享规则和组织范围的默认值。请遵循以下一般规则,以正确强制执行共享。

  • 在所有全局类上声明,或者 包含方法的类。 不要省略共享声明,也不要在解决方案的这些入口点上使用。with sharing@NamespaceAccessiblewithout sharing
  • 对于非全局或标记的控制器类,请将该类声明为 或 。不要省略共享声明,也不要在这些入口点上使用 溶液。@NamespaceAccessiblewith inherited sharingwith sharingwithout sharing
  • 将直接执行数据访问操作的所有类声明为 。如果解决方案中没有标记 的类,则也可以使用。with sharingwithout sharingwith inherited sharing

但是,也有一些值得注意的例外。在以下情况下,请勿遵循一般规则:

  • 你正在构建网站或社区,并希望拒绝来宾用户访问数据。
  • 您正在访问属于您的命名空间的自定义对象,并具有定制的安全性 政策。在这种情况下,请将策略记录为 AppExchange 安全审查的一部分 提交文件。此例外不适用于标准对象。组织管理员 独资拥有标准对象的安全策略。

Apex 示例

在此 Apex 代码中,关键字不是 添加到类头。默认情况下,共享规则不是 执行。

with sharing

public class maincontroller {
   @AuraEnabled public static String saveJobApplication(String vacId, String userId) {
      ...
   }
}

在此 Apex 代码中,关键字是 使用。强制执行共享规则。with sharing

public with sharing class maincontroller {
   @AuraEnabled public static String saveJobApplication(String vacId, String userId) {
       ...
   }
}

若要了解有关共享规则实施的详细信息,请查看安全服务器端开发 模块。

由于数据库查询构造不安全导致的 SOQL 注入

要防止 Salesforce 对象查询语言 (SOQL) 注入,请使用绑定变量和 输入卫生。

SOQL 注入是一种漏洞,用户直接控制 SOQL 的某些部分 数据库查询。在 Apex 中执行的 SOQL 查询不尊重用户权限。因此 SOQL 注入可用于提升用户的权限并允许他们访问数据 超出其用户权限。

两种类型的 SOQL 注入漏洞需要不同的保护 方法。

在第一种类型中,用户提供了不正确的表或字段名称进行查询。 当用户数据标识字段或表名称时,必须验证用户是否具有 访问命名表或字段的权限。请记住,此类型不是引用的 上下文。

在第二种类型中,用户提供带引号的 WHERE 子句的一部分。当用户数据 插入到带引号的字符串上下文中时,数据可以脱离带引号的上下文。这 首选的保护方法是使用绑定变量。或者,您可以使用 .这两种方法都会阻止用户 从引用的上下文中突破出来的数据。EscapeSingleQuotes()

永远不要允许用户提供除字段名称、表名称、 和 WHERE 子句输入。

避免在 Apex 中执行用户生成的查询,在 Apex 中,这些查询在系统模式下运行。如果必须 生成更复杂的客户端 SOQL,使用 REST 或 SOAP API,进行 SOQL 调用 牢牢。

要了解有关 SOQL 注入以及如何在代码中防止 SOQL 注入的更多信息,请查看安全服务器端开发 模块。

SOQL 示例

此 SOQL 语句是不安全的,因为它是通过将字符串与嵌入式连接起来构建的 用户输入。语句之前不进行输入审查 执行。

database.query

string objType = id.valueOf(deduped[0].recordId).getSObjectType().getDescribe().getName();
string soql = 'select id, ' + string.join(fields, ', ') + ' from ' +    objType +' where id in: lrIDs';
list<sobject> records = database.query(soql);

如果必须使用动态 SOQL,请使用该方法清理用户提供的输入。此方法添加 用户提供的字符串中所有单引号的转义字符 (\)。添加 转义字符可确保将所有单引号视为封闭式 字符串而不是数据库 命令。

EscapeSingleQuotes()

string objType = escapeSingleQuotes(id.valueOf(deduped[0].recordId).getSObjectType().getDescribe().getName());
string soql = 'select id, ' + string.join(fields, ', ') + ' from ' +    objType +' where id in: lrIDs';
list<sobject> records = database.query(soql);

跨站点请求伪造

跨站点请求伪造 (CSRF) 是一种强制最终用户执行 在经过身份验证的 Web 应用程序会话期间执行不需要的操作。为了防止 CSRF, 使用 或触发状态更改 与用户操作。

confirmationTokenRequired

在 Salesforce Platform 上发出的所有表单请求都受到保护。插入、删除、更新、 由用户操作(如按钮单击)触发的更新插入状态更改操作是 也受到保护。但是,页面上触发的状态更改或数据操作语言 (DML) 操作 实例化在页面的其余部分加载之前执行,它们绕过平台的 默认 CSRF 保护。类构造函数中的状态更改和 DML 操作是 如果它们由以下原因触发,则容易受到攻击:

  • Visualforce 页面
  • Lightning Web 组件 (LWC)
  • 光环
  • 从 Visualforce 页面的 action 参数调用的任何方法

Apex 示例

此 Visualforce 页面容易受到 CSRF 的攻击,因为该操作是在页面上触发的 初始化。

!init

<apex:page controller="maincontroller" action="{!init}">

public pageReference init(){

   UserSetting__c accountToUpdate;
   pageReference p = page.mainview;
   // Retrieve the password and redirect query string parameters from the current page URL
   String password = ApexPages.currentPage().getParameters().get('password');
   String redirect =   ApexPages.currentPage().getParameters().get('redirect');
   if(string.isBlank(redirect)){
       p.getParameters().put('redirect', '/home/home.jsp');
       p.setRedirect(true);
   } else {
       p.getParameters().put('redirect', redirect);
   }
   if(string.isBlank(password)){
       p.getParameters().put('password', 'blank');
       p.setRedirect(true);
   } else {
       p.getParameters().put('password', password);
       accountToUpdate = [SELECT password__c FROM UserSetting__c LIMIT 1];
       accountToUpdate.password__C = password;
       update accountToUpdate;
   }
   if(p.getRedirect()== true){
      return p; 
   }
   else {
       return null;
   }
}

黑客可以制作一个包含更改数据库语句的参数的 URL,从而允许 他们执行他们选择的恶意操作。当用户打开此类 URL 时 登录到您的应用程序,代码将使用黑客选择的 URL 参数执行。这 意外的数据库操作从受害者浏览器的上下文中执行。

Visualforce 页面保护

防止状态更改或 DML 时 Visualforce 页面中的 CSRF 漏洞 操作在页面初始化时执行,在 Visualforce 页面中启用布尔元数据字段。confirmationTokenRequired

如果设置为 true,则 GET 对页面的请求要求在 URL 中使用 CSRF 令牌。如果省略令牌,则页面为 无法。confirmationTokenRequired

默认设置为 false,这将删除 Apex 的内置 CSRF 令牌保护。您可以 通过转到组织设置中的相关 Visualforce 页面设置来配置此字段。

有关 , 请参阅元数据 API 中的 ApexPage 开发人员指南。confirmationTokenRequired

雷电和 LWC CSRF 保护

在实例化期间,请勿在 Apex 控制器中执行任何状态更改或 DML 操作 闪电或LWC。相反,使用用户操作(如按钮)触发状态更改 点击。要了解有关 CSRF 以及如何在代码中防止它的更多信息,请查看安全服务器端开发 模块。

打开重定向

当应用程序动态重定向到用户控制的 参数值,无需任何验证。使用硬编码防止打开重定向 重 定向。

开放重定向也称为任意重定向或未经验证的重定向。此漏洞是 用于网络钓鱼攻击,将用户重定向到任何 URL。

Apex 示例

在此函数定义中,该语句检索 URL 参数。该参数用于创建重定向 URL,然后 执行客户端重定向到构建的 网址。

String.redirect redirect

public PageReference changepassword(){
   PageReference savePage;
   String redirect = ApexPages.currentPage().getParameters().get('redirect');
   redirect = (redirect == NULL) ? '/home/home.jsp' : redirect;
   savePage = new PageReference(redirect);
   savePage.setRedirect(true);
   return savePage;
}

Visualforce 标记视图触发器 该操作,导致打开 重定向包中的漏洞。<apex:form>changepassword

<apex:form>
   Redirection action: <apex:inputText value="{!userInput}" />
   <br/><apex:commandButton value="Submit" action="{!changepassword}" />
</apex:form>

经修订的守则

开放重定向将您的重定向参数暴露给潜在的攻击者。您可以防止 使用多种策略打开重定向。一种策略是使用硬编码重定向。在一个 硬编码重定向时,您可以显式设置值,如下所示 例:

public PageReference changepassword(){
   PageReference savePage;
   savePage = new PageReference('/home/home.jsp');
   savePage.setRedirect(true);
   return savePage;
}

要了解有关开放重定向以及如何在代码中防止它们的更多信息,请查看登山口。

Lightning LockerService 已禁用

Lightning LockerService 是 Lightning 代码的一项关键安全功能。它提供 组件隔离,允许来自多个来源的代码使用 safe、 标准 API 和事件机制。为 AppExchange 软件包启用 Lightning Locker 包含 Lightning 组件或应用程序。

为所有自定义 Lightning Web 组件启用了 Lightning LockerService。服务是 在 17 年夏季版本中为客户激活。Lightning LockerService 未强制执行 适用于使用 API 版本 39.0 及更低版本的组件,该版本涵盖创建的任何组件 在 17 年夏季之前。当组件至少设置为 API 版本 40.0 时,将启用该组件。新增功能 AppExchange 安全审查和定期重新审查要求组件的版本为 40.0 或更高版本,以便启用 Locker。

元数据示例

在此组件的元数据中, 该字段将 API 版本设置为 39.0。 对于使用 API 版本 39.0 和 降低。

<AuraDefinitionBundle><apiVersion>

<?xml version="1.0" encoding="UTF-8"?>
<AuraDefinitionBundle xmlns="http://soap.sforce.com/2006/04/metadata">
     <apiVersion>39.0</apiVersion>
     <description>My Component</description>
</AuraDefinitionBundle>

在此组件的修订元数据中,该字段设置 API 版本 至 40.0。LockerService 对使用 API 版本 40.0 和 高等。

<AuraDefinitionBundle><apiVersion>

<?xml version="1.0" encoding="UTF-8"?>
<AuraDefinitionBundle xmlns="http://soap.sforce.com/2006/04/metadata">
     <apiVersion>40.0</apiVersion>
     <description>My Component</description>
</AuraDefinitionBundle>

有关更多信息,请阅读 2017 年夏季发行说明和 Lightning 安全性 Lightning Web 组件开发人员指南中的储物柜。

闪电组件中的转义不足

捆绑包中的每个组件都负责清理提供给它的输入 父组件、应用或 URL 参数。

单个组件的安全边界是组件捆绑包。中的每个组件 捆绑包负责清理父组件、应用程序、 或在 URL 参数中。假定公共或全局组件属性包含 攻击者控制的输入,除非被处理程序中的组件清理。onInit

未能清理输入可能会导致跨站点脚本 (XSS) 或 URL 重定向 攻击。

光环示例

在此 Aura 代码中,组件从全局属性中读取数据,然后将其呈现给 文档对象模型 (DOM) 没有充分转义。一个参数具有标签,该标签可被利用。黑客 或者恶意软件可以将 HTML 或 JavaScript 注入视图并触发跨站点脚本 (XSS) 攻击。

unescapedHTML

<aura:component controller="name_NewsController" access="global" extends="c:name_Name" implements="force:appHostable,flexipage:availableForAllPageTypes,forceCommunity:availableForAllPageTypes">
   <aura:handler name="baseReady" event="c:name_Name" action="{!c.doInit}"/>
   ...
   <aura:attribute name="newsDetails" type="String" default="" access="global"/>
   ...
   <div class="slds-col_padded slds-size_1-of-1 textDetail">
      <div class="slds-text-longform">
         <aura:unescapedHtml aura:Id="newsDetail" value="{!v.newsDetails}"/>
       </div>
   </div>
   ...
</aura:component>

此 Aura 组件代码是安全的,因为它不使用 .

unescapedHTML

<aura:component controller="name_NewsController" access="global" extends="c:name_Name" implements="force:appHostable,flexipage:availableForAllPageTypes,forceCommunity:availableForAllPageTypes">
   <aura:handler name="baseReady" event="c:name_Name" action="{!c.doInit}"/>
   ...
   <aura:attribute name="newsDetails" type="String" default="" access="global"/>
   ...
   <div class="slds-col_padded slds-size_1-of-1 textDetail">
      <div class="slds-text-longform">
         <aura:Id="newsDetail" value="{!v.newsDetails}"/>
       </div>
   </div>
   ...
</aura:component>

有关详细信息,请参阅“安全编码”中的“闪电安全” 指导。

组件中的异步代码

黑客可以操纵异步代码的时序来产生恶意结果。自 保留当前执行上下文,将异步函数调用或批处理操作包装到 单个请求。

当您使用异步函数(如 和)引用 组件,则退出框架的生命周期。如果在用户中的其他位置导航 接口 在执行异步代码时,框架会取消渲染并销毁 发出异步请求的组件。您仍然可以对此进行引用 组件,但它不再有效。黑客以有害的方式利用此漏洞,用于 例如,使应用崩溃。setTimeout()setInterval()

若要安全地重新进入框架,请将代码包装在函数中。然后,为了确保组件仍然有效, 在执行之前使用函数 回调中的任何内容。或者,使用 将多个操作批处理到一个请求中。$A.getCallback()component.isValid()enqueueAction()

注意

此漏洞不适用于针对 Summer ’17 版本创建的组件 (API v40.0) 或更高版本。

这些示例描述了安全违规以及如何解决它。

光环示例

该函数使您可以访问 文档对象模型 (DOM)。但是,访问 DOM 是在 Lightning 框架之外的上下文中发生的。有 无法保证父组件的状态 – 该函数可能没有 父组件。如果状态发生更改,回调函数可以对其数据执行操作 不拥有,或者它可以等待从未显示的数据。在这些情况下,应用会引发 一条错误消息,该消息将停止整个 Salesforce 页面,并且组件停止响应。

setInterval()setInterval()

vars.Timer = setInterval(function(){ helper.action(component); },1);

使用 getCallback() 示例修改的代码

若要安全地重新进入框架,请将代码包装在函数中。然后,为了确保组件仍然有效, 在执行之前使用函数 回调中的任何内容。$A.getCallback()component.isValid()

用于包装访问 正常重新渲染生命周期之外的组件,例如在 OR 调用中。 保留当前执行上下文,并授予对 异步代码。否则,框架将失去上下文,只允许访问全局 资源。$A.getCallback()setTimeout()setInterval()$A.getCallback()

window.setTimeout(
   $A.getCallback(function() {
      if(cmp.isValid()){ 
         cmp.set("v.visible", true); 
      }
   }), 5000
);

使用 enqueueAction() 示例修改后的代码

或者,使用 ,这会添加 服务器端控制器操作添加到要执行的操作队列中。而不是发送 对于每个单独的操作,框架分别请求处理事件链和 将队列中的操作批处理为一个请求。这些操作是异步的,并且具有 回调。enqueueAction()

var action = component.get(“c.usually_a_server_side_controller”);
action.setCallback(this, function()(response) {...});
$A.enqueueAction(action2);

要了解更多信息,请查看我们的安全客户端开发 模块。

安全通信

确保解决方案只能通过安全连接(如 SFTP)访问 和 HTTPS。避免使用 HTTP 和 FTP,因为这些协议不会对 通过 Internet 流动。

发送和接收文件传输时使用 SSH 文件传输协议 (SFTP)。SFTP 使用 加密算法可安全移动文件并提供比 FTP的。

使用安全超文本传输协议 (HTTPS) 在 Web 浏览器和 网站。在 HTTPS 中,通信使用传输层安全性 (TLS) 进行加密,该 保护传输中的数据。使用安全版本的 TLS,禁用弱密码,生成 长键,并将使用 HTTP 的传入请求重定向到 HTTPS。

要防止中间人降级攻击,请使用 HTTP 严格传输安全 (HSTS)。 在这些攻击中,黑客拦截通信并从 HTTPS 重定向访问者 将资源的版本复制到 HTTP 副本。

若要了解详细信息,请参阅安全编码 安全 通信。

保护您的 B2C 商务解决方案

AppExchange 上列出的所有 B2C Commerce Cartridge 和 Headless 集成都必须遵守 满足这些要求。

加密、加密和秘密存储

使用强大的加密方案保护静态数据,并保护加密密钥。

请参阅加密和 密码学和秘密 存储。

身份验证和授权

在处理带有特权操作的请求之前,请对 请求。此外,在读取或写入机密信息时强制执行身份验证和授权 Order、Customer 和 PaymentInstrument 等对象。

请参阅身份验证和 授权。

Open Commerce API (OCAPI) 和 Salesforce Commerce API (SCAPI) 设置

遵循 OCAPI 和 SCAPI 权限的最小特权原则。为用户提供 执行任务所需的最低权限集。记录权限,以及 与您的客户分享它们。

请参阅 SCAPI 的 OCAPI 设置和授权。

敏感数据存储和日志记录

敏感数据是必须防止未经授权的访问的任何信息。 不同的法规将信息归类为敏感数据,可能包括付款 仪器、受保护的健康信息、个人身份信息、访问 令牌和加密密钥。记录并向客户披露敏感数据列表 由解决方案存储或处理。编辑 B2C Commerce 日志文件中的敏感数据。

请参阅存储敏感数据。

密码学

使用受支持的加密 API,例如 dw.crypto。不实现 自定义加密。

客户端脚本

从 B2C Commerce 墨盒静态包含和提供所有客户端脚本。避免动态加载 来自内容分发网络 (CDN) 或其他第三方的第三方脚本。

代码注入

不要将任何输入数据解释为脚本。静态包含所有源代码。

用户输入验证

确保用户输入与解决方案所需的数据类型完全相同。全部验证 处理前的用户输入。

请参阅数据验证。

用户输入

在任何上下文中呈现所有用户提供的内容之前,请转义它,包括 HTML 和 JavaScript的。

请参阅模板最佳实践。

跨站点请求伪造 (CSRF)

在所有状态更改控制器中包括 CSRF 保护。

请参阅跨站点请求伪造。

打开重定向

开放重定向用于网络钓鱼攻击,将用户重定向到任何 URL。从不重定向用户 基于不受信任的数据。遵循开放重定向攻击中的做法。

内容安全政策

记录您的内容安全策略并与客户共享(如适用)。

补丁和升级

为了简化修补程序的安装和升级,请指导客户使用单独的磁带盒 尽可能进行自定义。

环境

在设置、管理、 并开发您的 Salesforce B2C Commerce 环境。

保护您的 Tableau Accelerator

AppExchange 上列出的所有 Tableau 加速器都必须遵守这些规定 要求。

允许的功能

在 Accelerator 中仅使用内置的 Tableau 功能。不要使用仪表板 扩展程序、来自 Tableau Exchange 的第三方连接器、外部第一方或第三方连接器 代码或与外部服务器的连接。

链接和 URL 操作

请勿在 Accelerator 中包含 URL 操作或外部链接。

示例数据来源

Tableau 加速器依靠示例数据在用户连接之前填充仪表板 他们自己的数据。您可以自行创建此示例数据,也可以获得使用权和 分发示例数据,以便可以在 Accelerator 中对源进行归因 清单。

去标识化数据

加速器的数据必须经过去标识化处理。它不能包含个人 可识别的信息,例如真实企业或商业实体的名称。你 不希望用户能够从 您的数据集。

数据打包

创建所有示例数据的平面提取,并将其打包为 TWBX 工作簿文件的一部分 为您的加速器。在打包数据之前,请隐藏未使用的字段。不包括直播 查询,甚至对平面文件。不要实现自定义加密。

数据源凭据

验证数据源与基于云的数据的连接,并删除 来自 Accelerator 的基于云的数据源连接。用户必须输入自己的 用于连接到数据的凭据。