Web 开发常见安全问题

前端安全
XSS 漏洞
CSRF 漏洞

后端安全
SQL 注入漏洞
权限控制漏洞
SESSION 与 COOKIE
IP 地址
验证码

前言
水桶底部只要有一个洞,水就能全部流光。Web 安全同理。
前端安全
前端安全主要表现为通过浏览器间接影响到用户数据的安全问题。
XSS 漏洞
XSS (Cross-Site Scripting),是一个我觉得耳熟能详的前端安全问题。通过构造特殊数据,在用户浏览器上执行特定脚本,从而造成危害(如以用户身份发帖、转账等)。
由于页面内 JavaScript 几乎可以完成各种事情,因此一旦网站上有 XSS 漏洞,那些没有验证码等确认措施的操作大多都能不知情地完成,其危害甚大。
来看看几个存在 XSS 漏洞的例子吧:
Case A: HTML DOM
<a href="/user/1">{{ user_name }}</a>

Exploit:
<script>alert(1)</script>

Result:
<a href="/user/1"><script>alert(1)</script></a>

最基本的例子,如果此处不对 user_name
中的特殊符号进行 escape,就会造成 XSS。

Case B: HTML Attribute
![]({{ image_url }})

Exploit:
" onerror="alert(1)

Result:
<img src="" onerror="alert(1)">

这个例子表明,如果只对尖括号进行 escape 是不够的,很多时候引号也需要被 escape。简单来说,对不同输出场景,需要使用不同的 escape 规则。

Case C: JavaScript
<script>var user_data = {{ user_data|json_encode }};</script>

Exploit:
{"exploit": "</script><script>alert(1);//"}

Result:
<script>var user_data = {"exploit": "</script><script>alert(1);//"};</script>

这是一个特别的例子,大多数人觉得,对于输出在 <script>
中的内容,json_encode
一下就安全了,其实不然。在这个例子中,XSS 仍然发生了。
更可怕的是,不少编辑器的代码高亮方案中甚至无法看出上面的 Result 中存在 XSS 漏洞。如 Sublime Text 下,代码高亮结果是这样的,看上去没有任何问题:


Sublime-Text-Highlight

但是浏览器解析出来的结果是这样的:


Chrome-Inspector

解决方法:
在不同上下文中,使用合适的 escape 方式

不要相信 任何 来自用户的输入(不仅限于 POST Body,还包括 QueryString,甚至是 Headers)

CSRF 漏洞
CSRF (Cross-site request forgery),是一个知名度不如 XSS 但是却同样具有很大杀伤力的安全漏洞。它的杀伤力大正是因为很多开发者不知道这个漏洞。
举个栗子,如果你网站 A 上的「登出」功能是这样实现的:
<a href="http://a.com/logout.php">登出</a>

则存在 CSRF 漏洞。假设网站 B(当然也可以是网站 A 本身)中有这么一段代码:


那么当用户访问的时候,就会导致网站 A 上的会话被登出。
需要注意的是,不只是 GET 类请求,POST 类请求同样会存在 CSRF 漏洞,例如网站 B 中:
<form action="http://a.com/transaction" method="POST" id="hack"> <input type="hidden" name="to" value="hacker_account"> <input type="hidden" name="value" value="100000"></form><script>document.getElementById("hack").submit();</script>

那么用户访问网站 B 的时候,便会自动携带 A 的 SESSION 信息,成功 POST /transaction
到网站 A。
这个漏洞危害很大,例如以前某些 BTC 交易所就存在这个漏洞,一旦用户被诱骗访问了黑客精心布置的网站就会造成资金损失;又例如,以前某中国著名社交网站也存在这个漏洞,更糟糕的是该网站还允许用户递交自己的 <img>
显示在所有人的信息流中,且某些传播性操作可以用 GET

方式达成,这就导致黑客可以进行病毒式扩散,当然,仅仅是把

嵌入信息流也是有足够大杀伤力的 :)
解决方法:
给所有请求加上 token 检查。token 一般是随机字符串,只需确保其不可预测性即可。token 可以在 QueryString、POST body 甚至是 Custom Header 里,但千万不能在 Cookies 里。

检查 referer
(请注意,这往往不能防御来自网站自身的 CSRF 攻击,如用户评论中的 <img>
就是一个常见触发点)

后端安全
在这里,后端安全指的是对服务器数据等可能造成直接影响的安全问题。黑客一般会直接构造数据进行攻击。
SQL 注入漏洞
SQL 注入漏洞应该也是一个大多数开发者都知道的漏洞。
考察以下 PHP 代码:
<?php$user = mysql_query('SELECT * FROM USERS WHERE UserName="'.$_GET['user'].'"');

那么当请求中 user 参数为 ";DROP TABLE USERS;--
时,合成的 SQL 语句是:
SELECT * FROM USERS WHERE UserName="";DROP TABLE USERS;--"

这里产生什么结果就不需要解释了吧 :) 另外,通过 SQL 注入,往往还能拿到系统权限。
解决方法:
所有 SQL 语句都使用参数化查询(推荐)或对参数进行 escape(不推荐)

权限控制漏洞
这个就不仔细展开了,未经授权可以进行的操作都是权限控制漏洞。
例如,某些网站的后台操作就仗着「以为用户不知道入口地址」不进行任何权限检查,又例如,某些操作可能出现不允许更改的字段被用户递交更改(往往是那些网页上标记为 disabled
或者 hidden
的字段),再例如,允许通过 ../
访问到不应该被访问的文件等(一般存在于 include
中)。
解决方法:
所有地方都要进行权限检查(如是否已登录、当前用户是否有足够权限、该项是否可修改等),总之,不要相信任何来自用户的数据,URL 当然也是。

SESSION 与 COOKIE
Session 和 Cookie 是两种用于存储用户当前状态的工具。某些开发者不了解 Session 与 Cookie 的区别,误用或者混用,导致敏感信息泄露或者信息篡改。
Cookie 存储在浏览器上,用户可以查看和修改 Cookie。Session 是存储在服务端的数据,一般来说安全可靠;大多数 Session 都是基于 Cookie 实现的(在 Cookie 中存储一串 SESSION_ID,在服务器上存储该 SESSION_ID 对应的内容)。

IP 地址
首先,用户的 IP 地址一般存储在 REMOTE_ADDR
中,这是唯一的可信的 IP 地址数据(视不同语言而定)。然后某些代理服务器,会将用户的真实 IP 地址附加在 header 的 VIA
或 X_FORWARDED_FOR
中(因为REMOTE_ADDR
是代理服务器自身的 IP)。所以,要获取用户 IP 地址,一般做法是,判断是否存在 VIA
或者 X_FORWARDED_FOR
头,如果存在,则使用它们,如果不存在则使用 REMOTE_ADDR
。这也是网上大多数所谓教程提供的方法。
这就产生问题了,X_FORWARDED_FOR
或 VIA
是 HTTP Header,换句话说,它们是可以被伪造的。例如,在投票中,如果采信了 X_FORWARDED_FOR
,往往意味着被刷票。
解决方法:
只使用 REMOTE_ADDR
作为获取 IP 的手段。

验证码
验证码里常见的问题有:非一次性、容易被识别。
非一次性指的是,同一个验证码可以一直被用下去。一般来说,每进行一次验证码校对(无论正确与否),都应该强制更换或清除 Session 中的验证码。
关于识别问题,在当前科技水平下,不加噪点不加扭曲的验证码几乎是 100% 可识别的。所以大家自己看着办吧…

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容