在网页设计中,模板是一个类似于 HTML 的文件,其中散布着程序指令,这些指令将在运行时由 Web 服务器或浏览器中的 JavaScript 代码解释。
模板是一个静态文件,用于通过插入从数据库检索或从 HTTP 提取的动态内容来生成 HTML 。
当模板引擎将动态内容视为要执行的代码而不是要插入的数据时,就会发生模板注入漏洞。
这会允许攻击者在服务器或受害者的浏览器中执行恶意代码。
Angular 中的模板注入
Angular 应用由一组分层组件组成,这些组件封装了应用程序逻辑和状态信息。每组件在浏览器中使用模板呈现,该模板描述要输出的给定状态的 HTML元件。React模板将使用"{{"和"}}"分隔符安全的差值状态,并允许组件以侦听使用事件处理程序的用户交互。使用"@Component"装饰器将模板附加到组件。
可以使用"templateUrl"选项,提供相应模板文件的相对或绝对路径:
typescript
selector: ,
templateUrl: ,
styleUrls: [ ]
})
export class LoginComponent {}
模板也可以使用"模板"选项作为内联字符串提供:
typescript
@Component({
selector: 'app-login',
template: '<form (ngSubmit)="onSubmit()">' +
'<input type="text" placeholder="Username" [(ngModel)]="username" />' +
'<input type="password" placeholder="Password" [(ngModel)]="password" />' +
'<button type="submit">Login</button>' +
'</form>',
styleUrls: ['./login.component.css']
})
export class LoginComponent {}
当不受信任的输入传递到"模板"选项时,Angular中会发生模板注入漏洞,当模板字符串由字符串串联生成时:
typescript
@Component({
selector: 'app-header',
template: '<h1>' + (window.location.hash || 'Home') + '</h1>'
})
export class HeaderComponent {}
避免以这种方式动态生成的模板。
相反,将状态加载到组件中,并使用 Angular 的内置插值逻辑,可安全地转义任何不受信任的内容:
typescript
selector: ,
template:
})
export class HeaderComponent {
title = ''
ngOnInit() {
this.title = window.location.hash || 'Home';
}
}
React 中的模板注入大多数 React 开发人员使用 JSX 以 JavaScript 语法制作原生的 HTML 标签。
JSX 让动态渲染变得容易
对应于从服务器加载的数据的页面元素。在构建过程中将代码转译为 JavaScript 时,提供所有 React 组件在 JSX 中定义,通常可以免受模板注入攻击。
然而,React 组件可以直接从运行时使用
React.createElement(...)
函数的低级 API。
如果使用不受信任的方式调用此方法内容,很容易受到模板注入攻击:
jsx
const tagName = 'div'
const attributes = { class: 'page-contents' }
const textContent = 'Tag contents go here'
/**
* Dynamically create a React component, in this case:
*
* <div class="page-contents">Tag contents go here</div>
*
* If any of the arguments come from an untrusted source an attacker can inject malicious content.
*/
React.createElement(
tagName,
attributes,
textContent
)
如果调用
dangerouslySetInnerHTML
攻击者还可以控制 HTML 标签的属性和内容React 组件上的函数:
jsx
/**
* React allows you to write raw HTML from a string, but discourages it - hence the function name
* "dangerouslySetInnerHTML(...)"! If the inputs to this function are taken from an untrusted source
* you are vulnerable to template injection.
*/
const html = {
__html: '<div class="page-contents">Tag contents go here</div>'
}
<div dangerouslySetInnerHTML={html} />
React 中模板注入漏洞的最终来源是
href
属性,如果链接的href
属性或者import
语句是从不受信任的内容动态生成的,攻击者可以通过提供带有javascript:
前缀的 URL:jsx
/**
* Dynamically setting the `href` of a link can permit cross-site scripting attacks if the
* URL is taken from an untrusted source.
*/
const link = "javascript:alert('Oh no')"
// An user clicking on this this component will execute the attacker's JavaScript.
const button = <a href={link}>Click here</a>
原文始发于微信公众号(网安之道):模板注入
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论