前端面试题集每日一练Day5
问题先导
-
什么是XSS攻击(概念、攻击方式、危害)?如何预防XSS攻击?【
浏览器
】 -
两数之和【
算法
】求给定数组中和为指定数字的两个下标。 输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
知识梳理
什么是XSS攻击?如何预防XSS攻击?
概念
XSS是Cross Site Scripting的缩写,由于CSS在网页设计领域已经被广泛指层叠样式表(Cascading Style Sheets),而Cross又有“交叉”的含义,所以将Cross改以交叉形的X做为缩写。因此XSS就是我们常说的跨站脚本攻击。
跨站脚本攻击是一种安全漏洞,攻击者可以利用这种漏洞向网站注入具有攻击性的脚本代码,当被攻击者登录网站时就会自动执行这些恶意代码,攻击者甚至可以突破网站访问权,冒充受害者,并进行更多攻击性操作。
根据开放式 Web 应用安全项目(OWASP),XSS 在 2017 年被认为 7 种最常见的 Web 应用程序漏洞之一。
攻击方式
XSS根据攻击脚本的来源不同,一般分为三种类型:
- 存储型XSS:恶意脚本存储到了目标服务器上。当浏览器请求到数据时,脚本从服务器上传并执行。
- 反射型XSS:当用户点击一个恶意链接,或者提交一个表单,或者进入一个恶意网站时,注入脚本进入被攻击者的网站。Web服务器将注入脚本,比如一个错误信息,搜索结果等 返回到用户的浏览器上。由于浏览器认为这个响应来自"可信任"的服务器,所以会执行这段脚本。
- 基于DOM的XSS:通过修改原始的客户端代码,受害者浏览器的 DOM 环境改变,导致有效载荷的执行。也就是说,页面本身并没有变化,但由于DOM环境被恶意修改,有客户端代码被包含进了页面,并且意外执行。
简答来说,存储型XSS脚本被存储到了服务器中,并由服务器上传至页面并执行,存储型XSS也称为持久性XSS,由于攻击脚本被存储到了服务器,可见其危害之广、影响之大。
比如较为经典的留言板持久型XSS攻击,如某网站对用户输入没有做特殊处理,而用户直接输入类似下面的内容:
<script>alert(“you see me!”)</script>
由于留言板会缓存到服务器,让每个人都能看到,当用户打开这个留言页面时,就会触发这段脚本代码。
而非持久性也就是反射型XSS,一般是用户经过某些恶意链接后重定向回某个可信任网站,但由于这些恶意链接携带了一些攻击性的表单信息,并被重定向的网站携带回来,然后在用户界面执行。由于脚本由用户触发,服务器只是中转站,然后又带回给页面,所以称之为反射型XSS。经过了可信任服务器的”转载“,这些来自恶意网站的脚本就变成了可信任数据,然后被执行。
比如某个恶意链接中携带了脚本代码:
<a
href="http://192.168.1.102/xss/example.php?name=<script>alert("hey!")</script>">
点我就送大惊喜</a>
而某些攻击者利用http://192.168.1.102/xss/example.php
这个页面的打开逻辑,知道name
参数会被插入页面进而编写了具有攻击性的诱导链接,当用户点击之后就触发了设计好的脚本代码。
最后一种,基于DOM的XSS不常见,这往往是浏览器环境被恶意篡改导致了恶意代码在某些页面上的执行。
危害
如果脚本在页面执行,最坏的情况就是页面上的所有信息都被获取,甚至伪造成用户与服务器进行交互,进行更大的破坏。一般来说,有以下几方面的危害:
- 获取隐私数据:客户cookie、session等网站信息
- DOS攻击:向服务器发送请求,占用服务器资源,让用户无法正常访问服务器
- 修改页面信息
- 流量劫持。将链接指向其他网站,进一步进行恶意控制或其他操作。
如何预防XSS攻击
从XSS的攻击方式来看,造成脚本执行的原因有两方面,一是服务器接收了脚本,但没有识别,让客户端保持了信任条件,二是浏览器本身没有对脚本进行甄别,我们发现,恶意脚本执行基本都是要操作DOM才能出发的,而DOM的操作是客户端能够控制的。所以,XSS的预防要从服务器端和客户端两头抓。
针对不同的脚本攻击有不同的处理办法,可能有的攻击方式还未出现,但层层把关是我们能做到的:
-
对上传的用户数据进行转译处理:客户端转译或进行输入限制;服务器端也要进行转译,避免漏网之鱼。
-
对DOM操作慎之又慎:很多时候DOM操作不规范才使得脚本语言有机可乘,要对DOM来源有明确的把控。
-
设置CSP安全策略。严格的CSP设置可以
-
禁止加载外域代码,防止复杂的攻击逻辑。
-
禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
-
禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。
-
禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。
-
合理使用上报可以及时发现 XSS,利于尽快修复问题。
更多细节可参考内容安全策略( CSP ) - MDN。
-
-
增强对敏感数据的保护,提交攻击门槛:比如cookie中使用
http-only
,让脚本无法获取隐私信息,设置验证操作等提高脚本攻击门槛。 -
主动检测:利用XSS攻击检测工具扫描网站数据是否存在XSS漏洞。
扩展:XSS攻击小游戏
以下是几个 XSS 攻击小游戏,开发者在网站上故意留下了一些常见的 XSS 漏洞。玩家在网页上提交相应的输入,完成 XSS 攻击即可通关。
参考:
关键字:浏览器安全、XSS
两数之和
求给定数组中和为指定数字的两个下标。
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
暴力解法很容易想到,遍历数组两两相加来判断是否等于目标值即可。
我们发现关键语句为nums[i] + nums[j] == target
,这样我们需要知道同时知道i
和j
才行,这样就不得不遍历两次数组。
实际上,这个关键式子可以转换为求差:nums[i] == target - nums[j]
。看似没有区别,但我们可以理解为判断目标值与下标j
的差是否为出现过的num[i]
的值,我们一般遍历一遍记录nums[i]
的值即可,这样,当遇到适合的nums[j]
就能匹配上,也就只需要遍历一遍数组。
参考代码:
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
const map = new Map(); // 存储遍历过的数据
for(let i = 0; i < nums.length; i++) {
const diff = target - nums[i];
if(map.has(diff)) {
return [map.get(diff), i];
}
map.set(nums[i], i);
}
}
关键字:转变求解思路,异曲同工