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

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>
相关推荐
YBN娜8 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=8 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
minDuck13 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!33 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。39 分钟前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
EricWang13581 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
September_ning1 小时前
React.lazy() 懒加载
前端·react.js·前端框架
web行路人1 小时前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架