Chrome调试时的net::ERR_BLOCKED_BY_CLIENT错误

2017 Jun 14

在用Chrome做调试时,发现始终不能GET某个.js资源。 在“Network”里,发现对这个.js的GET请求没有显示任何status code(不是常见的404错误)。 在Console里,发现有如下的报错:

GET http://foo.com/bar.js net::ERR_BLOCKED_BY_CLIENT

最后发现是Chrome的AbBlock插件引起的问题。 因为bar.js里有一些弹框的代码,所以AbBlock为了阻止弹框广告,阻止了对它的请求和执行。 在域上禁用AbBlock后,就一切正常了。

web

Session Management Cheat Sheet

2017 Mar 2

OWASP出品的关于session的非常详细的cheat sheet。 重点讲了如何安全地管理session。 session做为一种和用户名&密码等效的认证手段,session管理的安全性是很重要的。

web

JSON Web Token和Cookie的比较

2016 Dec 18

JSON Web Token (JWT)和基于cookie的认证机制的比较。

基于cookie的authentication需要在服务端记状态。 而JWT是stateless的,这样服务的水平扩展性更好(不用考虑类似session replication这样的问题)。 不像cookie,JWT可以cross domain。 使用JWT后,API的使用者可以不局限于浏览器,这样对mobile app更友好。 session机制需要一些服务端查找,相比而言可能JWT的性能会好点。

想起了Rails的EncryptedCookieStore。 EncryptedCookieStore和JWT一样也是完全存在于client端。 和JWT的一个不同点是EncryptedCookieStore会加密内容,JWT不会(JWT只是sign)。

基于cookie的session机制可以在服务端让session失效。 JWT则需要在客户端做失效。

web

安全地存储用户密码

2016 Nov 16

在存储密码的数据库被攻破的前提下,破解密码的成本越高则密码的安全性就越高。 一般来说,密码在存储到数据库前都经过hash加密。 需要考虑hash函数的性能对密码安全性的影响。 比如对于SHA256来说,当前的普通计算机能在一秒内计算数百万的hash值,定制的计算机则可以提供每秒数十亿次的hash运算。 在这种情况下,很多密码安全的设计都变得不再安全。

首先,最不安全的方式是明文存储密码。 其次,对密码明文进行sha1加密、对密码明文进行sha1加密时加上固定的salt值、为每个用户分配不同的salt值都是不安全的。

推荐使用bcrypt加密密码。 bcrypt相比sha1等来说更慢,这意味着破解密码的cpu成本更高。 比如log_rounds值设为10时,大概需要100毫秒来计算hash值。 还可以通过增加log_rounds值来抵消未来计算机运算能力的提高。 一些bcrypt实现还原生支持per-user-salt。

Dropbox也主要采用了per-user-salt加bcrypt来存储用户密码。 Dropbox在用bcrypt hash之前,会先用SHA512对密码做预处理——把密码hash成512 bit的定长字符串。 预处理有两个作用:一是对于很短的密码,提高它的entropy(熵);二是防止输入密码过长造成潜在的DoS attacks风险(bcrypt很“慢”)。 Dropbox还引入了global pepper(既有“盐”又有“胡椒粉”)——对bcrypt的hash值再用AES256做进一步的加密。 pepper存储在数据库之外的地方。AES256是对称加密,方便未来更新pepper值。

web

Ruby on Rails框架的历史

2016 Nov 15

Rails从0.9.3版本开始到当前版本的所有Changelogs。 自“底”向“上”过一遍这些Changelogs,可以了解一个web框架(该有)的功能和演化。

Changelog(总)是了解一个软件(新)功能的最佳文档。

web

Cross-Site Scripting (XSS)

2016 Oct 22

来自Ruby on Rails Security Guide的一个章节,内容基本上是和特定web框架无关的,推荐一读。

web

Sessions

2016 Oct 21

来自Ruby on Rails Security Guide的一个章节,内容基本上是和特定web框架无关的,推荐一读。

web

Cross-Site Request Forgery (CSRF)

2016 Oct 21

来自Ruby on Rails Security Guide的一个章节,内容基本上是和特定web框架无关的,推荐一读。

web

Encode String before Put It into URL

2016 Oct 18

在实现、测试OneFeed的tag功能时,发现tag c++不能正常工作,

<a href="<%= '/posts?tag=' + t.name %>" class="..."><%= t.name %></a>

请求/posts?tag=c++到达server端后,params[:tag]的值为c ,导致数据库查询没有返回正确的结果。

原因是构造href时没有对tag的name做encode,而+恰好是URL规范里的特殊字符,它代表一个空格

Within the query string, the plus sign is reserved as shorthand notation for a space. Therefore, real plus signs must be encoded.

所以,在把一个字符串拼接到URL里前,要先把它encode一下。 毕竟,不是每次测试时都有足够运气使用像c++这样测试数据,提前发现bug。

在Rails里可以通过下面的方法来encode一个字符串,

URI.encode 'c++ java'
# => "c++%20java" 空格被encode,URL规范的特殊字符“+”没有被encode
ERB::Util.url_encode 'c++ java'
#=> "c%2B%2B%20java" 所有字符都被encode,包括像"+", "/", "?"这样的保留字符
<!-- fix: u是url_encode的alias -->
<a href="<%= '/posts?tag=' + u(t.name) %>" class="..."><%= t.name %></a>

关于URL decode,大部分web框架都会自动decode。

注意⚠️,“URL”也包括同一页面内的anchor

<a href="#need-to-encode-too">about</a>
<div id="need-to-encode-too">About us...</div>

另外,在准备测试数据时,别忘了中文;中文也是需要encode的。

web