安全
清理用户输入
对于诸如 ion-alert
之类的组件,开发人员可以允许使用自定义或用户提供的內容。此内容可以是纯文本或 HTML,应被视为不可信。与任何不可信输入一样,在对其进行任何其他操作之前,务必对其进行清理。特别是,在没有进行清理的情况下使用诸如 innerHTML
之类的东西会为恶意用户提供一个攻击载体,让他们输入恶意内容并可能发起 跨站点脚本攻击 (XSS)。
Ionic 内置了其提供的组件的基本清理实现。但是,它不是一个全面的解决方案。开发人员有责任确保所有传递的数据都经过清理。不同的框架对清理用户输入有不同的解决方案,因此开发人员应该熟悉他们的特定框架提供的功能。
对于没有使用框架或框架没有提供其所需清理方法的开发人员,我们建议使用 sanitize-html。该包提供了一个简单的 HTML 清理器,允许开发人员指定他们希望在应用程序中允许的确切标签和属性。
Angular
Angular 内置了 DomSanitizer
类。这有助于通过确保值可以安全地用于 DOM 来防止 XSS 问题。默认情况下,Angular 将标记任何它认为不安全的价值。例如,以下链接将被 Angular 标记为不安全,因为它会尝试执行一些 JavaScript。
public myUrl: string = 'javascript:alert("oh no!")';
...
<a [href]="myUrl">Click Me!</a>
要了解有关 Angular 提供的内置保护的更多信息,请参阅 Angular 安全指南。
React
React DOM 在通过将它们转换为字符串来渲染它们之前,会转义嵌入在 JSX 中的值。例如,以下操作将是安全的,因为 name
在渲染之前被转换为字符串
const name = values.name;
const element = <h1>Hello, {name}!</h1>;
但是,这并不能阻止有人将 JavaScript 注入诸如锚元素的 href
属性之类的位置。以下是不安全的,并可能允许 XSS 攻击发生
const userInput = 'javascript:alert("Oh no!")';
const element = <a href={userInput}>Click Me!</a>;
如果开发人员需要实现更全面的清理,他们可以使用 sanitize-html 包。
Vue
Vue 没有提供任何内置的清理方法。建议开发人员使用诸如 sanitize-html 之类的包。
要了解有关绑定到诸如 v-html
之类的指令的安全建议的更多信息,请参阅 Vue 语法指南。
通过 innerHTML
启用自定义 HTML 解析
ion-alert
、ion-infinite-scroll-content
、ion-loading
、ion-refresher-content
和 ion-toast
可以接受用于某些属性的自定义 HTML 作为字符串。这些字符串使用 innerHTML
添加到 DOM,并且必须由开发人员进行适当的清理。此行为默认情况下处于禁用状态,这意味着传递给受影响组件的值将始终被解释为纯文本。开发人员可以通过在 IonicConfig 中设置 innerHTMLTemplatesEnabled: true
来启用此自定义 HTML 行为。
从内置清理器中弹出
对于希望向诸如 ion-toast
之类的组件添加复杂 HTML 的开发人员,他们需要从 Ionic 框架内置的清理器中弹出。开发人员可以全局禁用整个应用程序的清理器,也可以在特定情况下绕过它。
绕过清理功能会使您的应用程序容易受到 XSS 攻击。在禁用清理器时,请格外小心。
通过配置禁用清理器
Ionic 框架提供了一个名为 sanitizerEnabled
的应用程序配置选项,默认情况下设置为 true
。将此值设置为 false
以全局禁用 Ionic 框架内置的清理器。请注意,这不会禁用其他框架(如 Angular)提供的任何清理功能。
在特定情况下绕过清理器
开发人员还可以选择在某些情况下从清理器中弹出。Ionic 框架提供了 IonicSafeString
类,允许开发人员做到这一点。
为了绕过清理器并在相关的 Ionic 组件中使用未清理的自定义 HTML,innerHTMLTemplatesEnabled
必须在 Ionic 配置中设置为 true
。
如果 innerHTMLTemplatesEnabled
设置为 false
,则不应使用 IonicSafeString
。
有关更多信息,请参阅 启用自定义 HTML 解析。
用法
- Angular
- Angular (独立)
- JavaScript
- React
import { IonicSafeString, ToastController } from '@ionic/angular';
...
constructor(private toastController: ToastController) {}
async presentToast() {
const toast = await this.toastController.create({
message: new IonicSafeString('<ion-button>Hello!</ion-button>'),
duration: 2000
});
toast.present();
}
import { IonicSafeString, ToastController } from '@ionic/angular/standalone';
...
constructor(private toastController: ToastController) {}
async presentToast() {
const toast = await this.toastController.create({
message: new IonicSafeString('<ion-button>Hello!</ion-button>'),
duration: 2000
});
toast.present();
}
import { IonicSafeString } from '@ionic/core';
...
const async presentToast = () => {
const toast = document.createElement('ion-toast');
toast.message = new IonicSafeString('<ion-button>Hello!</ion-button>');
toast.duration = 2000;
document.body.appendChild(toast);
return toast.present();
}
import React, { useState } from 'react';
import { Animation, IonButton, IonContent, IonicSafeString, IonToast } from '@ionic/react';
export const ToastExample: React.FC = () => {
const [showToast, setShowToast] = useState(false);
return (
<IonContent>
<IonButton onClick={() => setShowToast(true)} expand="block">Show Toast</IonButton>
<IonToast
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
message={new IonicSafeString('<ion-button>Hello!</ion-button>')}
duration={2000}
/>
</IonContent>
)
};
内容安全策略 (CSP)
内容安全策略 (CSP) 是一种安全机制,有助于保护 Web 应用程序免受某些类型的攻击,例如跨站点脚本 (XSS) 和数据注入。它是通过 HTTP 标头实现的,该标头指示浏览器允许哪些内容来源(例如脚本、样式表和图像)在网页上加载和执行。
CSP 的主要目的是减轻与代码注入攻击相关的风险。通过定义策略,Web 开发人员可以指定浏览器应该允许从哪些域或来源加载和执行各种类型的内容。这有效地限制了恶意脚本或未经授权的内容可能造成的潜在损害。
启用 CSP
开发人员可以通过设置一个带有策略详细信息和脚本和样式标签上预期 nonce 值的元标记来将其应用程序分配给 CSP。
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' 'nonce-randomNonceGoesHere'; style-src 'self' 'nonce-randomNonceGoesHere';"
/>
Ionic 和 CSP
Ionic 框架提供了一个函数来帮助开发人员设置在构造 Web 组件样式表时使用的 nonce 值。此函数应在加载任何 Ionic 组件之前调用。这是将 nonce 值传递给 Web 组件以便它们可以在 CSP 环境中使用的必要条件。
import { setNonce } from '@ionic/core/loader';
setNonce('randomNonceGoesHere');
在 Angular 中,可以在应用程序启动之前,在 main.ts
文件中调用此方法。
有关如何在 Stencil Web 组件中使用 CSP 的更多信息,请参见 Stencil 文档。
Angular
从 Angular 16 开始,Angular 提供了两种设置 nonce 值的方法。
- 在根应用程序元素上设置
ngCspNonce
属性,例如<app ngCspNonce="randomNonceGoesHere"></app>
。如果您有权访问服务器端模板,可以使用此方法在构建响应时将 nonce 添加到标头和index.html
中。 - 使用
CSP_NONCE
注入令牌提供 nonce。如果您在运行时有权访问 nonce 并且希望能够缓存index.html
,可以使用此方法。
如果提供 CSP_NONCE
注入令牌,请在模块项目的 AppModule
或独立项目的 bootstrapApplication
中设置提供程序。
有关如何在 Angular 中使用 CSP 的更多信息,请参见 Angular 文档。