一个网站的最基本功能,通常会是会员系统,而会员系统也算是一项重要的功能,因为这里面包含的个人隐私与帐号、密码,一旦会员系统被骇客入侵,User 对网站的信任度也就会大幅下降,接著这篇文章将会介绍一些「登入程式逻辑」上的错误,造成系统的漏洞。
登入验证顺序错误
登入验证一定要在程式的最开端进行,而不能放在程式的中段,或是后段,曾经看过有工程师,将修改会员资料的逻辑处理,写在登入验证的前面。
- <?php
- updateMember($_POST['name']);
- if(!login()){
- echo '<script>alert("您尚未登入")</script>';
- exit(1);
- }
- ?>
上述的程式中,会先更新会员资料,然后再去验证会员是否有登入,而骇客只要将 data post updateMember.php , Php 程式就会先更新会员资料,接著弹出错误讯息给 User,因为顺序上的错误,造成骇客可以修改会员资料,甚至修改管理员的密码,而入侵整个网站。
登入验证失败后,未中断程式
当会员登入验证失败后,必需重导页面到登入画面,并且中断程式的运行,否则程式会继续执行,直到结束。
- <?php
- if(!login($account, $passwd)){
- echo '<script>confirm("你并非管理员,不可修改会员资料")</script>';
- }
- updateMember($_POST['name']);
- ?>
在范例 2-1 中,当验证登入失败后,会回传一段 javascript ,告知 user 并非登入中。
- <?php
- if(!login($account, $passwd)){
- header("location:login.php");
- }
- updateMember($_POST['name']);
- ?>
在范例 2-2 中,当验证登入失败后,会直接回传 http header ,告知 Browser重导到登入页。
这两个范例,虽然都有回传讯息给 user,告知无法修改会员资料,但是却漏掉 「exit(1)」中断程式的运行,骇客就可以不需要登入,而修改会员 or 管理员资料,入侵系统。
未对所有功能进行登入验证
「所有需要会员登入才能运作的功能,都要加上登入验证」,这句话看起没有大不了,大家也都知道,但是没有网路安全观念的工程师们,还是常常会写出漏掉验证的程式码。
- <?php
- if(!login($account, $passwd)){
- header("location:login.php");
- exit(1);
- }
- if($_POST['action'] == "updateMember") {
- require "updateMember3-2.php"; //更新会员资料
- }
- ?>
- <?php
- updateMember($_POST['name']);
- ?>
有些工程师会将网站功能的入口都作在同一个 url 上,例如透过 index3-1.php 这一个页面,当传入的参数 action = updateMember ,就自动载入 updateMember3-2.php 并且完成会员更新的行为,因为 index3-1.php 这个档案的开头就已经先验证会员登入状态,所以工程师就会以为这个程式非常安全。
其实骇客只要直接将参数传给 updateMember3-2.php 这个 url ,跳过 index3-1.php ,就能轻易的再一次修改会员资料。
会员登入使用的 cookie 需加密
一般在会员登入之后,网站会建立一个代表这位会员已经登入过的 cookie 记录,有了这个记录,网站才知道这位会员不用再登入第二次,他可以执行会员应有的功能。
因为 cookie 是直接存在 Browser 里面,骇客可以轻易的看到 cookie 的格式是什么,所以我们还必需对 cookie 加密。
- <?php
- if(login($_POST['account'], $_POST['password']){
- setcookie("member", base64_encode($_POST['account']));
- }
- ?>
有不少工程师只会简单的对 cookie 做 base64 encode,这个加密出来的格式,很容易被骇客看出来,解密也相对简单,例如 「password」 base64 encode 过后的代码是 「cGFzc3dvcmQ=」,只要使用 base64_decode ,就能马上破解出来。
另外登入的 cookie 最好要加上后端程式能够判定的使用期限,再经过一段时间后,cookie 就不能再被使用,就算有骇客故意使用过期的 cookie,程式也要能过泸掉,为了这个功能,通常会在 cookie 的内容加入登入时间。
一个最基本的登入 cookie ,至少要会员密码,加上一个网站专用的固定 key,组合这二个数值,并且使用 md5 加密储存,而 key 也要三不五时的变换一下。
- <?php
- if(login($_POST['account'], $_POST['password']){
- $val = mcrypt_encrypt($cipher, $key, $_POST['account'].$expiredTime, $mode);
- $val .= md5($_POST['password'].$key);
- setcookie("member", $val);
- }
- ?>
目前回應 Comments(2 comments)
版大超棒 2017/10/30
最近工作上有需要涉略相關知識,這個網站對於剛起頭的人來說很棒呢
Reply如果對於相關議題能夠多寫一些就更好了
比方對於SQL injection事實上還有許多觀念和原則也很值得探討
就是讀完很有收穫但感覺有點不太過癮呢
Admin
謝謝支持。
版大你好 2013/11/07
說明簡單又清晰 雖然
Reply不是說完全懂 但是 卻有將重要的概念描述
期待 版大繼續 分享這類文章
Admin