作者dio833 (Dio)
看板PHP
标题Re: [请益] 让网页只能让透过ajax取资料 不能直接连
时间Tue Apr 17 13:34:20 2012
因为字数稍多,我用回文的
先这样假设,你要传的资料有ID,Name两个资料
像下面这样
ID=3&Name=dio
你先定一个privateKey的字串,例如"lala",用来md5加密时的混淆
下列Server端我会使用PHP的语法概述
Server用md5透过参数加上privateKey产生Code如下:
$privateKey="lala";
$code=md5("ID=3&Name=dio" . $privateKey);
// 此时$code=3db79513ff3d039d9a48b1df689015be
Client端的发送方式会变为:
ID=3&Name=dio&code=3db79513ff3d039d9a48b1df689015be
当Sever端接收到这个请求时,将传过来的ID跟Name透过一样的方式产生code
当code不相等时,代表Client的请求不合法,就拒绝服务
当然你也可以再稍微严谨一点,code多加入个时间time来混淆
Client的传送方式会变成如下:
ID=3&Name=dio&time=1334640221&code=.....
Server端的产生$code的方式就变成:
$code=md5("ID=3&Name=dio&time=1334640221" . $privateKey);
而此时Server端除了可以比对code是否符合之外
还可以多检查time的有效时间,例如你限定time如果超过3600秒,就拒绝服务
这样可保证连接的时效性
上述的产生code以及检查code的行为可稍微用点心在Server端写成函式
方便不同地方重复呼叫
这样做的好处就是对方知道你主要的参数,也无法用穷举法硬抓
只要参数有所变化,code必须要相应改变
※ 引述《s861175 (s861175)》之铭言:
: 标题: [请益] 让网页只能让透过ajax取资料 不能直接连
: 时间: Tue Apr 17 11:27:08 2012
:
: 让网页只能让透过ajax取资料 不能直接连
:
: 想做一个网站,user只需要访问index.php这一页,不需换页就可查到所有资料,
:
: 而index.php上所有的动态资料都由ajax去跟其他php网页要(例如 1.php、2.php...等),
:
: 请问,像1.php、2.php这些只负责喂资料给index.php的网页,可否不让user直接连,
:
: 我知道可以利用$_SERVER['HTTP_REFERER']来绑定上一页的来源,但是这可以被伪造,
:
: 请问还有其他更安全的避免他人直接连结网页的作法吗?
:
: 谢谢
:
: --
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.66.243.96
1F:推 kerash:依照原发问的要求,单一个网页(index) ajax 抓资料的话 04/17 14:50
2F:→ kerash:如果你这个方法用到 md5,在设定 code 得动态跑 md5 04/17 14:50
3F:→ kerash:那用 js 跑 md5 时就会知道丢什麽参数进去了说.. 04/17 14:51
4F:→ kerash:除非是跑两层,第一层先抛第一次参数後多跑一个加密页 04/17 14:51
5F:→ kerash:等把code加上去後再curl到第二页回传(当然这样会很麻烦...) 04/17 14:52
md5不会放在js这边产生,因为这样privateKey就失去意义了
以ID=3,Name=Dio为例,程式码应该如下:
################
<?php
$data["ID"]=$ID;
$data["Name"]=$Name;
$code=getSign($data,$privateKey);
?>
aaa.php?ID=<?php echo $data["ID"]?>&Name=<?php echo $data["Name"]?>&code=<?echo $code?>
################
我是觉得大部分的状况下ID,Name的值是由Server带进Client端的
所以Code也由Server端带出来的很合理。
而getSign($ary,$key)是产生code的function
6F:推 LPH66:其实重点只在说有心人还是能够模仿 browser 所送出的 req 04/17 15:44
7F:→ LPH66:所以很多东西其实都是防君子不防小人... 04/17 15:45
你说的对,很多东西是防不胜防,端看我们开发者能尽多少心力
不可能直接敞开大门任人存取
※ 编辑: dio833 来自: 61.66.243.96 (04/17 16:04)
8F:推 kerash:当然如果复杂度高的话还是勉强可以防 ...... 一下QQ 04/17 15:56
9F:推 kerash:这部分要考虑看原发问是否考虑到连接的网页要不要加参数 04/17 16:12
10F:→ kerash:以及在使用时会经过一段浏览器处理的换页 04/17 16:13
11F:→ kuAIpAI:我相信没有人会发现 md5('我很帅')加密法 ya~ 选我选我~ 04/17 16:17
我推测其他网友说的md5('我很帅')会replay attack的意思是,因为md5中使用固定的值。
会导致验证的参数永远固定,这样一下就被看穿
假设md5("我很帅")的值是"帅到爆"
以本篇文章的例子来说的话,Client的结果如下
ID=3&Name=Dio&code=帅到爆
ID=4&Name=Neo&code=帅到爆
Code不因其他参数的变化有所变化
这样就失去传Code的意义了
反正对方只要多传个"帅到爆",其他参数任填,都可以用力的try Server的Response
※ 编辑: dio833 来自: 61.66.243.96 (04/17 16:35)
12F:→ kuAIpAI:我当然不会这样写 我只是要跟他说可以传参数去防而已..... 04/17 16:36
13F:→ kuAIpAI:你也认真了...跟乡民认真就....恩阿(奔) 04/17 16:36
14F:→ dio833:privateKey用"我很帅"我倒是蛮赞同的 04/17 16:38
15F:→ MOONRAKER:我何必知道md5('我很帅')的plaintext... 04/17 18:48
16F:→ MOONRAKER:我只要用一只眼睛看一眼get的参数,或者累一点多用一只 04/17 18:48
17F:→ MOONRAKER:眼睛看http传送的header,就会看到有一个参数永远都是 04/17 18:50
18F:→ MOONRAKER:5beda80a8feb2b877702463d961eac1f不会变,我就把他存起 04/17 18:50
19F:→ MOONRAKER:来replay就好了,谁管你plaintext是什麽鬼… 04/17 18:50
20F:→ MOONRAKER:Ku老兄你也真是够了,胡扯被戳破就说你不是要这样说 04/17 18:51
21F:→ MOONRAKER:还继续扯「认真就输」,你最好祈祷不要有人被你误导 04/17 18:52
22F:→ MOONRAKER:写个烂code,一辈子都记得你 04/17 18:53
23F:→ chrisQQ:不就是 name id code pair 记下来就可以连了嘛… 04/17 18:53
你说的对,这个目的只能避免穷举法
当前的参数配对的code是一样的,但可避免的被人改换参数值,用spider抓光
另外前文有提到,可以加个time参数纳入md5混淆,Server端接到参数後
可以比对时间差,这样可以确保时效性,例如设定时间差600
这样的话同一组参数,只有10分钟有效,十分钟过後,参数就失效了
※ 编辑: dio833 来自: 59.120.148.186 (04/17 19:29)
24F:→ kuAIpAI:我只能说 我只是给方向 剩下的我也不想多说了~~ (菸) 04/17 23:42