前端开发面试宝典-安全防范部分

XSS

什么是 XSS 攻击?如何防范 XSS 攻击?什么是 CSP?

XSS 简单点来说,就是攻击者想尽一切办法将可以执行的代码注入到网页中。 总体上我认为分为两类:持久型和非持久型

持久型

举个例子,对于评论功能来说,就得防范持久型 XSS 攻击。评论区输入以下js代码

javascript 复制代码
<script>alert('xss攻击');</script>

非持久型

一般通过修改URL参数的方式加入攻击代码,诱导用户访问链接从而进行攻击。 举个例子,如果页面需要从 URL 中获取某些参数作为内容的话,不经过过滤就会导致攻击代码被执行。

javascript 复制代码
<!-- http://www.domain.com?name=<script>alert(1)</script> --> 
<div>{{name}}</div>

注意:Chrome 这类浏览器能自动帮助用户防御攻击。其他浏览器未知

如何防御XSS攻击

转义字符

针对普通输入框

javascript 复制代码
function escape(str) { 
    str = str.replace(/&/g, '&amp;') 
    str = str.replace(/</g, '&lt;') 
    str = str.replace(/>/g, '&gt;') 
    str = str.replace(/"/g, '&quto;') 
    str = str.replace(/'/g, '&#39;') 
    str = str.replace(/`/g, '&#96;') 
    str = str.replace(/\//g, '&#x2F;') 
    return str 
}
escape('<script>alert(1)</script>') // -> &lt;script&gt;alert(1)&lt;&#x2F;script&gt;

针对富文本 转义字符的方式会把需要的格式也过滤掉,所以推荐使用白名单的方式。

javascript 复制代码
const xss = require('xss') 
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>') 
// -> <h1>XSS Demo</h1>&lt;script&gt;alert("xss");&lt;/script&gt; 
console.log(html)

CSP

两种方式来开启 CSP

后端设置 HTTP Header 中的 Content-Security-Policy
php 复制代码
/*
    default-src:设置默认加载资源的策略(例如,自身的源、任何地方的源、或者不加载任何外部资源)。
    script-src:定义哪些脚本可以执行, 例如script标签, a标签的JavaScript:location.href="" 等.
    style-src:定义哪些样式表可以加载。
    img-src:定义哪些图片资源可以加载。
    connect-src:限制可以通过脚本接口进行连接的URL(例如,AJAX 请求、WebSocket)。
    font-src:定义哪些字体资源可以加载。
    object-src:限制可以加载哪些插件。
    media-src:定义哪些媒体资源(音频和视频)可以加载。
    frame-src:定义哪些iframe可以加载。
*/
<?php
// 只允许加载来自同源的所有资源
header("Content-Security-Policy: script-src 'self'"); 
// 允许执行来自同源以及http://192.168.112.183的脚本。
header("Content-Security-Policy: script-src 'self' http://192.168.112.183"); 
// 允许执行来自同源以及http://http://192.168.112.183的行内脚本
// 比如 <a javascript:location.href="http://192.168.112.183/hack.php"></a>
header("Content-Security-Policy: script-src 'self' http://192.168.112.183 'unsafe-inline'");
前端设置 meta 标签的方式 <meta http-equiv="Content-Security-Policy">
html 复制代码
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://apis.example.com; img-src 'self' https://images.example.com; style-src 'self' 'unsafe-inline';">
    <title>My Secure Page</title>
</head>
<body>
    <!-- 页面内容 -->
</body>
</html>
运维全局配置CSP 修改服务器配置文件

举例

html 复制代码
// Apache
<IfModule mod_headers.c>
    Header set Content-Security-Policy "default-src 'self';"
</IfModule>
// Nginx
server {
    add_header Content-Security-Policy "default-src 'self';";
    ...
}

CSRF

什么是 CSRF 攻击?如何防范 CSRF 攻击?

跨站请求伪造。原理就是攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。

举个例子,假设网站中有一个通过 GET 请求提交用户评论的接口,那么攻击者就可以在钓鱼网站中加入一个图片,图片的地址就是评论接口

html 复制代码
<img src="http://www.domain.com/xxx?comment='attack'"/>

防御 CSRF的方法包括:

CSRF令牌:

  • 为每个用户会话生成唯一的 CSRF 令牌,并将其添加到每个可能引发状态更改的请求(例如表单提交)中。
  • 服务器在接收到请求时检查令牌的有效性,确保请求是来自合法用户。

验证 HTTP Referer头部

  • 检查 HTTP 请求中的 Referer 头部,确保请求来自预期的来源。

Get 请求不对数据进行修改

合理设置用户会话过期时间

设置 Cookie 的 SameSite 属性 该属性表示 Cookie 不随着跨域请求发送

注意:该属性目前并不是所有浏览器都兼容

点击劫持

什么是点击劫持?如何防范点击劫持?

点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中,并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击。

X-FRAME-OPTIONS

html 复制代码
/*
    该响应头有三个值可选,分别是
    -   `DENY`,表示页面不允许通过 `iframe` 的方式展示
    -   `SAMEORIGIN`,表示页面可以在相同域名下通过 `iframe` 的方式展示
    -   `ALLOW-FROM`,表示页面可以在指定来源的 `iframe` 中展示
*/
<meta http-equiv="X-Frame-Options" content="SAMEORIGIN">

JS 防御

html 复制代码
<head> 
    <style id="click-jack"> html { display: none !important; } </style> 
</head> 
<body> 
<script> 
    if (self == top) { 
        var style = document.getElementById('click-jack') 
        document.body.removeChild(style) 
    } else { 
        top.location = self.location 
    } 
</script> 
</body>
相关推荐
excel5 分钟前
前端必备:从能力检测到 UA-CH,浏览器客户端检测的完整指南
前端
前端小巷子12 分钟前
Vue 3全面提速剖析
前端·vue.js·面试
悟空聊架构18 分钟前
我的网站被攻击了,被干掉了 120G 流量,还在持续攻击中...
java·前端·架构
CodeSheep20 分钟前
国内 IT 公司时薪排行榜。
前端·后端·程序员
尖椒土豆sss24 分钟前
踩坑vue项目中使用 iframe 嵌套子系统无法登录,不报错问题!
前端·vue.js
遗悲风24 分钟前
html二次作业
前端·html
江城开朗的豌豆28 分钟前
React输入框优化:如何精准获取用户输入完成后的最终值?
前端·javascript·全栈
CF14年老兵28 分钟前
从卡顿到飞驰:我是如何用WebAssembly引爆React性能的
前端·react.js·trae
画月的亮31 分钟前
前端处理导出PDF。Vue导出pdf
前端·vue.js·pdf
江城开朗的豌豆37 分钟前
拆解Redux:从零手写一个状态管理器,彻底搞懂它的魔法!
前端·javascript·react.js