目录
简介
题目
单选题
题解
A选项的Content-Security-Policy
http-equiv属性
content属性
B选项的CSRF
使用CSRF Token
验证Referer和Origin头
C选项的HTTP Only
D选项的防止SQL注入
输入验证和转义
简介
这个是一个长系列,我会以题目为导向,通过题目来针对性的学习前端的方方面面,每篇文章涉及到的题目并不多,但是每道题我都会尽量细致,面向初学者友好的去讲解,喜欢的可以一直关注,我会持续更新这个系列的文章。
题目
单选题
1.关于前端安全,以下说法正确的是()
A. XSS(跨站脚本攻击)可以通过设置HTTP响应头的Content-Security-Policy为none来防止。
B. CSRF(跨站请求伪造)攻击可以通过移除所有的cookie来防止。
C. HTTP Only属性可以防止通过JavaScript访问cookie,从而减少XSS攻击的风险。
D. 输入验证和转义是防止SQL注入的无效方式。
题解
答案选C,我们逐个解释,我们尽量讲解的细致一些,面向初学者友好一些,而且我们尽量有代码示例就用代码来解释。
A选项的Content-Security-Policy
设置HTTP的响应头的Content-Security-Policy为none,并不是防止XSS攻击的有效正确方式。相反,Content-Security-Policy反而是可以有效防止XSS的攻击。XSS,是一种网站应用程序的安全漏洞攻击,是代码注入的一种。 HTTP概括来讲,就是万维网的数据通信的基础。而Content-Security-Policy,以后我简称为CSP,CSP是HTTP的一个响应头,它不是对象,属性或者方法,而是一种服务器发送的指令。 我们在HTML文件中,<head>标签下会有一个<meta>标签,在这个标签下,我们可以对于http-equiv设置一个配置性的命令,即CSP,它可以告诉浏览器如何处理一个网页的内容。
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';"> <meta charset="UTF-8"> <title>Title</title> </head> <body> </body> </html>
http-equiv属性
http-equiv属性的作用是模拟HTTP响应头部的效果,这里我们设置为CSP,就是它指令的一种,而CSP的作用就是有效防止XSS的攻击
content属性
content属性用于定义与name属性和http-equiv属性相关的值,它可以设置很多相关的命令,这个例子就是一个典型的样式default-src 'self指令设置了所有类型资源的默认策略,我们一般都是这样设置的,这里的资源就是比如脚本、样式、图片和字体等等。img-src https://指令用于指定哪些来源的图片可以被加载,我们设置为这个命令,意味着我们可以在任何使用HTTPS协议的来源,来去加载图片child-src 'none',也是一个属性,我们设置为none,表示不允许从任何源加载这类内容,这里的内容我们说的是要嵌入的内容,比如iframe/embed/object这些元素回到题目本身,其实那么我们到底如何做到A选项说的,如何防止XSS呢?完整的代码是这样的,但是,概括来讲,正确配置Content-Security-Policy(如限制资源的加载和执行来源)可以有效防止XSS攻击,A说法说反了。
<meta http-equiv="Content-Security-Policy" content=" default-src 'none'; script-src 'self' https://trustedscript.com; connect-src 'self'; img-src 'self' https://trustedimagehost.com; style-src 'self' 'unsafe-inline'; font-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'self';">
B选项的CSRF
移除所有的cookie并不是防止CSRF攻击的有效方法,Cross-Site Request Forgery,全称为这个,为跨站请求伪造,简单来说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站,并执行一些操作。
什么是cookie呢?全称为HTTP cookie,我们在浏览一些国外网站的时候,可能会遇到这个选项,是我们在浏览网站时,网络服务器创建的,并通过网页浏览器存放在用户计算机的小文本文件,即cookie就是一些小文件。移除所有的cookie并不能防止CSRF攻击。要通过CSRF攻击的常见方式,来阻止,比如使用CSRF Token,或者验证Referer和Origin头,下面逐一介绍。
B选项说的,移除所有的cookie,这个操作本身和有效防止CSRF并没有直接关系,CSRF攻击的是什么?它攻击的是用户当前的登录状态,cookie这些小文件更多的是比如购物车信息,会话标识符,跟踪和分析信息等。
使用CSRF Token
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>CSRF的阻止方式一</title></head><body><form action="/submit-form" method="post"> <input type="hidden" name="csrf_token" value="your_csrf_token_here"> <!-- 其他表单字段 --> <input type="submit" value="Submit"></form></body></html>
这是一份使用CSRF Token方式的一份代码,这里的value,我们要根据实际情况来定,是服务器生成的唯一随机,并且不可预测的CSRF令牌(token)。
验证Referer和Origin头
const express = require('express');const app = express();app.use((req, res, next) => { const referer = req.headers.referer; const origin = req.headers.origin; // 检查Referer或Origin是否合法 if (referer !== 'https://expected-referer.com' && origin !== 'https://expected-origin.com') { return res.status(403).send('CSRF check failed'); } next();});app.post('/submit-form', (req, res) => { // 处理表单提交 res.send('Form data received');});app.listen(3000);
这是通过验证referer和origin头的方式,我们可以在node.js环境下写这样的JavaScript代码,同时满足这两个条件,我们就把参数res的状态设置为403,再send一下信息:CSRF check failed。
C选项的HTTP Only
HTTP Only属性确实可以防止通过JavaScript访问, 减少XSS攻击的风险,前面已经说了cookie是什么?下面来看看完整代码,来看看我们是如何做的。首先确保你的计算机已经安装了node.js和express,如果没有express,我们可以通过npm install express指令来安装。
const express = require('express');const app = express();app.use((req, res, next) => { const referer = req.headers.referer; const origin = req.headers.origin; // 检查Referer或Origin是否合法 if (referer !== 'https://expected-referer.com' && origin !== 'https://expected-origin.com') { return res.status(403).send('CSRF check failed'); } next();});app.post('/submit-form', (req, res) => { // 处理表单提交 res.send('Form data received');});app.listen(3000);
当我们访问服务器的根目录'/'的时候,它会设置一个名为secureCookie的Cookie,我们把httpOnly属性设置为true,即使用HTTP Only属性,增强了cookie的安全性。
D选项的防止SQL注入
D说法也是,说反了,我们确实是可以通过输入验证和转义,来防止SQL注入的。什么是SQL注入?SQL注入也是一种常见的网络攻击技术,攻击者通过恶意SQL代码注入到应用程序的输入字段中,试图破坏或者操纵后台数据库。比如攻击者可以写一些这样的语句。
SELECT * FROM users WHERE username = '[用户输入的用户名]' AND password = '[用户输入的密码]';
输入验证和转义
输入验证和转义是两种基本的安全措施,它可以防止很多不同形式的注入攻击,包括SQL注入。比如我们可以写这样的代码。转义,说的是什么事呢?就是指输入数据可能会被错误的解释为代码的特殊字符进行处理的过程,我们通过转义来确保输入字符串中特殊字符,比如单引号,不会结束字符串文本,并且开始新的SQL命令。
app.post('/submit-form', (req, res) => { const email = req.body.email; const age = req.body.age; // 验证电子邮件地址 if (!email.match(/^[^@]+@[^@]+\.[^@]+$/)) { return res.status(400).send('无效的电子邮件地址'); } // 验证年龄 if (isNaN(age) || age < 18 || age > 100) { return res.status(400).send('无效的年龄'); } // 处理有效输入 // ...});
这里的if当中的部分即是这种方式的体现。当然,还有很多,比如类型检查,格式验证,长度验证,内容检查等等。