首页 > 代码库 > 哈佛大学构建动态网站--第八讲安全

哈佛大学构建动态网站--第八讲安全

显然的威胁 telnet FTP http MYSQL

不要使用telnet FTP,他们使用明文传输用户名和密码;而使用SFTP,它基本是SSH上的FTP,更安全。


防止SQL注入攻击:mysql_real_escape_string函数,能免受某些攻击。


HTTP: session劫持  fireship


mysql 明文传密码,故要限制可以登录的IP,最好是只有内网,最好将数据库藏到一个网络的后面,用ssh 处理


共享主机下的权限问题:

不可能每个人都拥有一个完全属于自己的服务器,因此就存在着权限设置问题,要么你的网站让网络服务器可读,此时也就让服务器上的其他用户可以查看你的网站代码了,这显然是不愿意的,要么就只有你自己能访问,这样网站就没有意义了,如此一来有了suPHPfastCGI等工具。共享环境下,php以root权限访问,用户上传文件,文件属于root,这样其他用户就没法访问了



cookie与session hijacking

获得了cooki中的sessionid即得到了session劫持 ;为了用户体验服务器并不会检测session来源的ip地址,只检查那一大串随机数。而且就算检测ip也不能真正解决问题,比如星巴克等使用了nat的网络,对外来说其实都是用的一个ip地址。

session hijacking案例:

Physical Access

Packet Sniffing

Session Fixation 固定的session ID

XSS

关于session劫持,主要就是嗅探数据包,而嗅探通信是十分容易,课上使用的嗅探工具是Wireshark


很多网站使用HTTPS,但只用在登录页面。


因此还是会受到类似firesheep这类工具的威胁,比如说用户登录过facebook了,当他再次登录时在浏览器为了方便只输入facebook.com,此时浏览器会自动补全,自动补全为http://facebook.com/,注意自动补全并不是https,因此那么就可能会在向这个地址发送请求时同时发送session cookie,这样一来就危险了,虽然一开始cookie是通过https加密发给你的,但是此时却被浏览器明文发送出去,这是因为通常网站不是全站都使用https,那么是不会将phpsession这些cookie标记为secure的。解决方法可以是到php.ini这样的配置文件中将session cookie标记为secure,这只会在http头信息中加上表示secure的关键字,开启此功能相当于告诉浏览器只有在https连接下才发送此cookie


当然有些辅助工具,比如firefox的插件Force-TLS,(p.s. TLSSSL协议其中的一种)相当于一个看门人,当发现浏览器在发送http时,自动将其改为https。同样的还有HTTPS Everywhere,功能类似,只是实现原理稍有不同。但它们功能有限,只能对特定网站转为https.

session hijacking防范

Hard-to-guess session keys?

Rekey session?

  一种能够减少被攻击而不能根除攻击的方法就是,每访问一个页面都告诉服务器更换使用一个新session id,这样做能够防止之前嗅探你的cookie的攻击者攻击失效。但也有个问题就是攻击者更快的抢占到你的cookie然后登录然后攻击者换页面同时更换了新的session id,那么此时你就会被退出登录了。

Check IP or MAC address?

  之前谈到检测ip地址,显然不能解决问题,而用mac地址依然不能解决问题,因为网卡的mac地址有可能被厂商重复使用,而且就算不管重复的问题,通过http头信息发送mac地址还是会被截获到的,因为http头信息是明文发送的。


  理论上可以通过获取NAT路由器对应的源端口来进行区分检测该局域网内有人伪造我的cookie,,因为路由器的源端口无法伪造的,但这功能需要更多的硬件支持。需要第三层的tcp和第五层的http混合使用,不过实现起来还是挺麻烦,还是不如直接启用SSL简单

Encryption?

  如果不得不在公开场合如机场,咖啡馆的公共wifi下登录,还有个办法就是使用vpn。如果家里有不变的IP地址或者通过某种动态DNS方法,可以通过使用openvpn连接到自己家里的网络上。

  关于网站安全,最好的办法就是全站使用ssl,给全站加密。虽然会提高不少成本。


SSL

使用ssl前需要有ssl证书,即SSL Certificates,首先需要由你自己通过一些命令来产生一个公有密钥和一个私有密钥,命令行环境通常可以使用免费软件OpenSSL。得到两个文件扩展名分别是.key.csr。一个文件是证书签署请求(certificate signing request,将其上传到godaddy等你购买ssl证书的地方,验证通过后会得到另一个文件,其中不仅包含你的公有密钥,还包含他们的数字签名,之后就可以自己参照说明或者google,让ssl为网络服务器配置添加证书后生效,当有人通过https请求你的网站时,他的浏览器和你的网络服务器会告诉他,这就是我的公有密钥,此公有密钥可以被用来加密一条信息给你,同样你可以使用他们的公钥密钥加密一条信息给他们。


对于有使用很多子域名的网站,可以购买更贵一些的通配SSL证书,这样就能作用于子域名了,这比每个域名都买一个证书要划算的多。


HTTP响应包的server:apache/2 x-power-by:php/5.3.3要设为不发送。特定版本的软件有漏洞





SQL注入 

可以使用MySQLi API这些API,能帮助处理很多问题。随意输入‘ mysql_real_escape_string




同源策略,ajax cookie frames


被访问页面urlfoo.com则无法做到:向另一个域名bar.con发送ajax请求并整合响应到foo.com的内容。但有种技术叫JSONP可以绕过此策略,但这需要网站的支持,而比如雅虎财经就不支持此技术,它返回的CSV显然不是JSONP,而且大多数网站都不支持这个技术。





跨站请求伪造CSRF

跨站请求伪造案例:

你登录了股票网站A,然后又不注意登录了某个恶意网站,而恰好这个恶意网站会有个跳转到股票网站A同时会发送请求买入一个股票,于是你就会在不知情的情况下买入了一支股票。跨站请求伪造就是这个意思,跨站表示链接来自别处,可以是email可以是直接在坏人的网站上,请求伪造则表示这是一个请求,但它是伪造的,模仿你的行为,但结果很坏,坏人设法让你买了股票。


跨站请求伪造实现:

坏人甚至连让你点击提交按钮都不用,也可以让你中招,比如以下就有多种通过标签的方式让你中招。

  1. <img src="http://project1.domain.tld/buy.php?symbol=INFX.PK">
  2. <script src="http://project1.domain.tld/buy.php?symbol=INFX.PK">
  3. </script>
  4. <iframe src="http://project1.domain.tld/buy.php?symbol=INFX.PK">
  5. <script>
  6. var img = new Image();
  7. img.src = "http://project2.domain.tld/buy.php?symbol=INFX.PK";
  8. </script>

跨站请求伪造防御:

Use POST for sensitive actions? 无效

  解决办法可以做个确认页面,但还有个更好的办法就是使用post,因为get很容易被人模仿,但是坏人可以通过js做个链接提交表单让你填写表单,也可以是图像提交表单等等多种方法能骗别人提交post请求,通过ajax也能提交post请求

Use HTTP_REFERER?   无效 并不是所有浏览器都发送http_referer,尤其还有安装了某些隐私保护的情况,所以检测超链接的方式不能防止这个攻击。

Append session tokens to URLs? 附加session令牌给url这个方法可行,可以让上面这个攻击变得困难。隐藏token 或者图形验证码

Expire sessions quickly? 减少概率,不能消除

CAPTCHAs?Prompt user to re-login?   给出一个javascript不好解的题目,错误要重新登录




跨站脚本攻击XSS

XSS案例:

下面这个网站vulnerable没有对用户输入进行检测转义,因此被坏人恶意构建了下面这个语句,然后把这整个链接发布,通过欺骗的方式让别人点击,这个链接会把浏览器地址改为badguy.com


vulnerable本来是系那个用变量foo获取用户输入,由于该网站没有对输入进行检测转义,于是被坏人利用构建了特殊语句,去骗其他用户点击然后触发get请求,也许vunlnerable网站意识到这个用户名不对,于是将通过预注入文本框来告诉用户,因而现在vun网站就不小心往html代码中嵌入了坏人构建的js代码,并且是坏人设法让网络服务器做的这些,因此恶意js代码来源就是vun了,所以这就绕过了同源策略的防御。

而且这个整个构造的恶意链接可以通过把一些符号下斜线" / "%3D这类的代码表示出来,因而混淆后面的内容让其看上去只是乱码。

技术分享

XSS防范:

Don’t click links?

Don’t trust user input?Encode all user input?

任何用户输入的内容都要记得使用mysql_real_escape_string函数来转义用户的输入,同样任何回送给用户的输入也要转义,任何文本框的时候,不是用的mysql_real_escape_string,而是使用htmlspecialchars以防止用户键入<&这些具有隐患的字符。




来自为知笔记(Wiz)


哈佛大学构建动态网站--第八讲安全