第三方 CSS 并不安全
最近一段时间,关于 通过 CSS 创建 “keylogger”(键盘记录器) 的讨论很多。
有些人呼吁浏览器厂商去“修复”它。有些人则深入研究,表示它仅能影响通过类 React 框架建立的网站,并指责 React。而真正的问题却在于认为第三方内容是“安全”的。
第三方图片
<img src="https://example.com/kitten.jpg">
如果我将上述代码引入我的文件中,即表示信任 example.com。对方可能会删除资源,给我一个 404,导致网站不完整,从而破坏这种信任关系。或者,他们可能会用其他非预期的数据来替代小猫图片的数据。
但是,图片的影响仅限于元素本身的内容区域。我可以向用户解释并希望用户相信,“此处的内容来自 example.com,如果它有误,则是原站点的问题,并不是本站造成的”。但这个问题肯定不会影响到密码输入框等内容。
熊猫办公https://www.wode007.com/sites/73654.html
第三方脚本
<script src="https://example.com/script.js"></script>
与图片相比,第三方脚本则有更多的控制权。如果我将上述代码引入我的文件中,则表示我赋予了 example.com 完全控制我的网站的权限。该脚本能:
- 读取/修改页面内容。
- 监听用户的所有交互。
- 运行耗费大量计算资源的代码(如 cryptocoin 挖矿程序)。
- 通过向本站发请求,这样能附带用户的 cookie,转发响应。(译注:盗取用户的 cookie 及其他数据)
- 读取/修改本地存储。
- ......可以做任何对方想做的事情。
“本地存储”非常重要。如果脚本通过 IndexedDB 或缓存 API 发起攻击,则即使在删除脚本后,攻击仍可能在整个站点内继续存在。
如果你引入了其他站点的脚本,则必须绝对相信对方及对方的防护能力。
如果你遭到恶意脚本的攻击,则可设置 Clear-Site-Data header(清空站点数据响应头) 清除站点所有数据。
第三方CSS
<link rel="stylesheet" href="https://example.com/style.css">
相比图片,CSS 在能力上更接近脚本。像脚本一样,它适用于整个页面。它可以:
- 删除/添加/修改页面内容。
- 根据页面内容发起请求。
- 可响应多种用户交互。
虽然 CSS 不能修改本地存储,也不能通过 CSS 运行 cryptocoin 挖矿程序(也许是可能的,只是我不知道而已),但恶意 CSS 代码仍然能造成很大的损失。
键盘记录器
从引起广泛关注的代码开始讲起:
input[type="password"][value$="p"] {
background: url('/password?p');
}
如果输入框的 value 属性值以 p 结尾,上述代码将会向 /password?p 发起请求。每个字符都可触发这个操作,通过它能获取到很多数据。
默认情况下,浏览器不会将用户输入的值存储在 value 属性中,因此这种攻击需要依赖某些能同步这些值的东西,如 React。
要应对这个问题,React 可用另一种同步密码字段的方式,或浏览器可限制那些能匹配密码字段属性的选择器。但是,这仅仅是一种虚假的安全。你只解决了在特殊情况下的该问题,而其他情况依旧。
如果 React 改为使用 data-value 属性,则该应对方法无效。如果网站将输入框更改为 type="text",以便用户可以看到他们正在输入的内容,则该应对方法无效。如果网站创建了一个 <better-password-input> 组件并暴露 value 作为属性,则该应对方法无效。
此外,还有很多其他的基于 CSS 的攻击方式:
消失的内容
body {
display: none;
}
html::after {
content: 'HTTP 500 Server Error';
}
以上是一个极端的例子,但想象一下,如果第三方仅对某一小部分用户这样做。不但你很难调试,还会失去用户的信任。
更狡猾的方式如偶尔删除“购买”按钮,或重排内容段落。
添加内容
.price-value::before {
content: '1';
}
哦,价格被标高了。
移动内容
.delete-everything-button {
opacity: 0;
position: absolute;
top: 500px;
left: 300px;
}
上面的按钮能做一些重要的操作,设置其为不可见,然后放在用户可能点击的地方。
值得庆幸的是,如果按钮的操作确实非常重要,网站可能会先显示确认对话框。但也不是不可绕过,只需使用更多的 CSS 来欺骗用户点击 “确定” 按钮而不是“取消”按钮即可。
假设浏览器确实采用上面的应对方法解决“键盘记录器”的问题。攻击者只需在页面上找到一个非密码文本输入框(可能是搜索输入框)并将其盖在密码输入框上即可。然后他们的攻击就又可用了。
读取属性
其实,你需要担心的不仅仅是密码输入框。你可能在属性中保存着其他的隐藏内容:
<input type="hidden" name="csrf" value="1687594325">
<img src="/avatars/samanthasmith83.jpg">
<iframe src="//cool-maps-service/show?st-pancras-london"></iframe>
<img src="/gender-icons/female.png">
<div></div>
所有这些都可以通过 CSS 选择器获取,且能发出请求。
监听交互
.login-button:hover {
background: url('/login-button-hover');
}
.login-button:active {
background: url('/login-button-active');
}
可将 hover 和 active 状态发送到服务器。通过适当的 CSS,你就能获取到用户意图。
读取文本
@font-face {
font-family: blah;
src: url('/page-contains-q') format('woff');
unicode-range: U+85;
}
html {
font-family: blah, sans-serif;
}
在这种情况下,如果页面内有 q 字符,则会发送请求。你可以为不同的字符,并针对特定的元素,创建大量不同的字体。字体也可以包含 ligature(连字),所以你可以在开始检测字符序列。你甚至可以通过将字体技巧与滚动条检测结合起来 来推断内容。
译注:关于 ligature(连字), 可查看 Wikipedia Typographic Ligature
第三方内容不安全
这些只是我所知道的一些技巧,我相信还有更多。
第三方内容在其沙箱区域内具有强大的能力。一张图片或沙盒化的 iframe 仅在一个小范围内的沙箱中,但脚本和样式的范围却是你的页面,甚至是整个站点。
如果你担心恶意用户诱使你的网站加载第三方资源,可以通过 CSP 用作防护手段,其可以限制加载图片,脚本和样式的来源。
你还可以使用 Subresource Integrity(子资源完整性 ) 来确保脚本/样式的内容匹配特定的 hash,否则将不加载。感谢 Hacker News上的Piskvorrr 提醒我!
如果你想了解更多如上述的 hack 技巧,包括滚动条技巧,更多信息请参阅 Mathias Bynens' talk from 2014,Mike West's talk from 2013,或 Mario Heiderich et al.'s paper from 2012(PDF)。是的,这不是什么新东西。
第三方 CSS 并不安全的更多相关文章
- 第三方CSS安全吗?
原文:https://jakearchibald.com/201...翻译:疯狂的技术宅 本文首发微信公众号:jingchengyideng欢迎关注,每天都给你推送新鲜的前端技术文章 前一段时间,有很 ...
- Vue学习笔记【19】——Vue中的动画(使用第三方 CSS 动画库)
导入动画类库: <link rel="stylesheet" type="text/css" href="./lib/animate.css& ...
- Vue - @import css 加载第三方css
@import '~@/assets/css/style.css' CSS loader 会把把非根路径的url解释为相对路径, 加~前缀才会解释成模块路径.
- vue.js之过渡效果-css
概述 vuejs的过渡效果可以让我们的页面元素在出现和消失时实现过渡.官方文档这样描述过渡效果的方式: 在 CSS 过渡和动画中自动应用 class 可以配合使用第三方 CSS 动画库,如 Anima ...
- CSS布局概述
1.HTML5文档类型 由于Bootstrap使用了HTML5特定的HTML元素和CSS属性,所以使用Bootstrap的时候,所有的HTML文件都需要在其顶部引用HTML5的DOCTYPE属性,如下 ...
- DotNetNuke-DNN Module模块引用自定义CSS或者JS文件
当新增一个module时,有时会引用自定义的或者第三方CSS.JS文件. 1.添加自定义的CSS时,可以直接在module的根目录下添加module.css,然后框架会自动加载此CSS: 2.这个比较 ...
- Vue过渡效果之CSS过渡
前面的话 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果.本文将从CSS过渡transition.CSS动画animation及配合使用第三方CSS动画库(如animate. ...
- SharePoint Framework 在web部件中使用第三方样式 - 将第三方样式打到包中
博客地址:http://blog.csdn.net/FoxDave 有许多第三方库可以帮助我们构建丰富的SharePoint Framework客户端web部件.并且这些JavaScript脚本常常包 ...
- 前端读者 | 别人写的css,你敢用吗?
本文来自@yeaseonzhang:链接:http://yeaseonzhang.github.io/2018/04/10/%E5%88%AB%E4%BA%BA%E5%86%99%E7%9A%84cs ...
随机推荐
- PAT 有几个PAT
字符串 APPAPT 中包含了两个单词 PAT,其中第一个 PAT 是第 2 位(P),第 4 位(A),第 6 位(T):第二个 PAT 是第 3 位(P),第 4 位(A),第 6 位(T). 现 ...
- python自学Day06(自学书籍python编程从入门到实践)
第7章 用户输入和while循环 我们设计的程序大多是为了解决用户最终的问题,所以我们大多需要在用户那里获取一些信息. 学习用户输入的获取与处理,学习while循环让程序不断运行直到达到指定的条件不满 ...
- How to delete a directory recursively in Java
在java8或更高版本中,使用NIO API递归删除一个非空目录: try { // 创建stream流 Stream<Path> file = Files.walk(Paths.get( ...
- pip常出问题的操作
pip 是一个 Python 包安装与管理工具. 以pip安装yaml为主: 1.更新pip 打开cmd命令,安装yaml包,输入pip install pyyaml,提示pip已过期 更新pip版本 ...
- 02 . Zabbix配置监控项及聚合图形
安装Zabbix Agent监控本机 安装agent软件 与server端不同,Agent只需安装zabbix-agent包 cat /etc/yum.repos.d/zabbix.repo [zab ...
- @atcoder - AGC029F@ Construction of a tree
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定 N - 1 个 {1, 2, ..., N} 的子集,第 ...
- @codeforces - 575E@ Spectator Riots
目录 @description@ @solution@ @accepted code@ @details@ @description@ 一个以 (0, 0) 为左下角,(10^5, 10^5) 为右上 ...
- Nginx 的变量究竟是怎么一回事?
之前说了很多关于 Nginx 模块的内容,还有一部分非常重要的内容,那就是 Nginx 的变量.变量在 Nginx 中可以说无处不在,认识了解这些变量的作用和原理同样是必要的,下面几乎囊括了关于 Ng ...
- controller场景设计
场景设计模型-手动场景快增长慢增长指定运行次数组模式 快增长模型:就是压力瞬间启动并且达到最大,通常用于秒杀的场景 loadrunner设置:瞬间启动,瞬间停止 慢增长:压力按照设定的规则慢慢的添加, ...
- 关于Ubuntu系统忘记密码的解决方法合集
昨天有台机器的Ubuntu系统密码出了问题,一直提示错误.由于里面的数据比较重要,不建议重装系统,所以百度了一会,最终解决了忘记密码问题.整理了一个大合集分享出来. 第一种:参考教程如下 ...