摘要: Azure Services Platform入门专题受到了越来越多人的关注,并被网络上许多网站进行转载。作者感到非常荣幸。目前这套入门教程已基本成型,我将它做成索引便于大家查阅。对 IT168 等网站无视国家法律未经作者许可擅自篡改版权进行转载的龌龊侵权行为表示最深的鄙视。
阅读全文
posted @
2009-04-17 16:59 流牛木马 阅读(4858) |
评论 (12) |
编辑
经过特邀评委们艰难的抉择,赢在淘宝的30强、10强终于出炉啦!(排名不分先后)
稍后将在应用展示页面添加特邀评审团评语!敬请期待哦~
第三轮评选——特邀评审团 赵立威 微软(中国)开发工具与平台事业部首席顾问 杨巍
Google中国战略合作总监 白鸦 支付宝首席用户体验规划师 徐毅律 上海新中欧创业投资管理有限公司合伙人 王文彬
淘宝开放平台副总裁
原文见 http://open.taobao.com/bbs/read.php?tid=6310
posted @
2009-12-29 13:26 流牛木马 阅读(95) |
评论 (0) |
编辑
摘要:

Google Wave已经公测一个月了,再全世界范围内都掀起了一股索要Google Wave的热潮。做为一个有思想的程序员,除了为Google Wave自身的新特性感动兴奋和赞叹以外, 我们还好奇Google Wave 提供的API能干些什么。流牛木马在这里为您介绍它。
阅读全文
posted @
2009-11-13 22:27 流牛木马 阅读(2184) |
评论 (15) |
编辑
昨天我因为我网站(http://freesms.cloudapp.net )收到了恶意攻击,我发布了ASP.NET网站限制访问频率一文,引起了博客园各位高手的激烈讨论,很多朋友朋友提出了一些疑问与改进意见,我感到非常开心。后来我也继续思考了很多,现将我的想法写下来,希望高手们再来看看,不吝赐教。o(∩_∩)o
在众多网友中,最需要感谢的是在博客园网友王玮。你的由“ASP.NET网站限制访问频率”想到的两点问题 一文中,提到了两个问题:第一是验证码不能够明文存在Cookie中;第二是IP地址可以欺骗某些验证方式。
这两个问题非常好,非常感谢 。 第一个问题确实存在的,我现在已经用了加密,已经不能够绕过验证了。第二个问题对于我的系统来说是不存在的,因为我的代码中并没有使用你说的那两种获取IP的方式,你无法欺骗我的系统。
总结了大家的观点,我们主要做以下几点讨论:
- 采用Cookie记录验证码是最方便的方式,无论是从开发成本还是从维护、运营成本来看,都是性价比最高的。在不至于太严格要求的网站中,建议采用Cookie的方式。
- 验证码如果需要存入Cookie中,需要加密。加密方式有很多,最普通的是md5。但是现在网上已有很多md5密码数据库(如 http://www.cmd5.com/),有的甚至提供API,所以单纯只使用md5是靠不住的。在我的加密中,我将传统生成md5的方式做了一些修改,基本能够保证恶意访问者无法通过加密的Cookie来获取到真实验证码。
public static string GetMd5(string str)
{
string cl =DateTime.Now.Month+ str + DateTime.Now.Day;//将真实验证码加上前缀与后缀后再加密;
string pwd = "";
MD5 md5 = MD5.Create();//实例化一个md5对像
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
s.Reverse(); //翻转生成的MD5码
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
for (int i = 3; i < s.Length-1; i++) //只取MD5码的一部分;恶意访问者无法知道我取的是哪几位。
{
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
pwd = pwd + (s[i]<198?s[i]+28:s[i]).ToString("X"); // 进一步对生成的MD5码做一些改造。
}
return pwd;
}
- 限制频繁访问是一定要做的。
在我的网站中,正常访问的用户不可能在4小时内访问200次以上。这是有统计来源的。根据我采用的一些统计代码,我发现访问最频繁的用户,在4小时内访问的最大值仅为76次,而且这是一个最特殊的特例而已。
所以如果我一旦发现有用户在4小时内访问太多次数, 几乎就可以判断他为恶意用户。
这不是一个最绝对的判断方式,但仍然是可行性最高、成本最低的。
- 限制频繁访问的方式,使用Cache最好,使用XML最次。
在ASP.NET网站限制访问频率一文中,我提出了使用Cache来记录用户的IP、访问方式、访问次数。这也是参考了很多大型网站防止DoS攻击的方式。
有朋友提出,使用Cache或许会造成服务器资源开销,建议使用XML;如果XML太大,可以分成零碎模块。
我的观点是,XML文件的效率确实太差。以前我测试过,十万行数据的XML文件,一次读写操作就接近1秒,更不用说网站的频繁访问、需要频繁操作XML文件了。然后同样的十万条Cache数据,占用内容仅为几十M(如一条数据占用1k内存,十万条占用100M;然后实际操作中,1条数据远没有1k),处理速度在10毫秒内。
不仅如此,就算我们把访问记录到XML文件中,我们对它进行读写操作,也是要将它载入内存的。而十万行数据的XML文件,与十万行Cache中的KeyValue对,占用的内存也是不能同日而语的。
综上所述,使用XML文件进行记录,不仅不能够减少服务器压力(内存、硬盘、CPU计算次数),反而还增加了服务器压力、大大增加了请求响应时间。最好的方式仍然是使用Cache。
暂时就这些吧。。希望大家继续给点意见,也可以去我的网站(http://freesms.cloudapp.net/)试试,看你能不能够找到漏洞进行破解 。o(∩_∩)o 非常感谢博客园的朋友,跟你们交流我非常开心!
posted @
2009-09-20 14:04 流牛木马 阅读(1775) |
评论 (50) |
编辑
最近做了一个免费发短信的小网站(http://freesms.cloudapp.net/),但发现最近有人破解了我的验证码,以每3秒/条的速度用我的短信服务来发他的广告。更换验证码程序和过滤关键字只是治标不治本的方法,为了彻底阻止此类事件的发生,我们还是来看一下怎样通过优化程序来实现。
其实同样的程序除了防止别人滥发请求以外,还对预防拒绝服务(DoS)攻击同样适用哦。不妨来看看。
基本目标:限制同一IP访问网站的频率。比如,我们限制为每240分钟来自同一IP的用户最多只能够访问首页40次、其他页面200次。
比如您现在可以打开http://freesms.cloudapp.net/ 这个网站试一试,刷新40次,就可以发现您在4小时内无法再次访问到正确的网站内容了。
基本思想:
- 用HttpContext.Cache记录访问次数
- 将IP值与用户访问方式作为共同的Key,可以对用户的不同访问方式做不同的限制。
- 超出限额时调用Response.End()。
具体代码:
一、 定义持续时间
在本例中,我们使用240分钟作为一次限制的时间。
private const int DURATION = 240
二、定义访问方式枚举
针对不同的访问方式进行不同的限制。在本例中,我们只区分两种访问方式:正常访问与PostBack。在正常应用中,您还可以根据需要增加访问不同页面的限制。
public enum ActionTypeEnum
{
Normal=40,
Postback=100
}
三、判断逻辑
- 在某IP第一次采用某种访问方式进行访问时,增加Cache的Key=访问方式+IP,返回True
- 如果Key已经存在,增加访问次数,返回True
- 如果超出次数,返回False
public static bool IsValid(ActionTypeEnum actionType)
{
HttpContext context = HttpContext.Current;
if (context.Request.Browser.Crawler) return false;
string key = actionType.ToString() + context.Request.UserHostAddress;
int hit = (Int32)(context.Cache[key] ?? 0);
if (hit > (Int32)actionType) return false;
else hit++;
if (hit == 1)
{
context.Cache.Add(key, hit, null, DateTime.Now.AddMinutes(DURATION), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
}
else
{
context.Cache[key] = hit;
}
return true;
}
四、在页面中调用
判断函数需要在页面的OnInit方法中调用。在这里需要使用一些自己定义的逻辑,来进行不同访问方式的判断。下面的例子是一个最简单的,只区分正常访问与Postback。
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!IsPostBack)
{
if (!ActionValidator.IsValid(ActionValidator.ActionTypeEnum.Normal))
{
Response.Write("您发送得太频繁,被系统判断为广告。广告或其他定制业务请联系邮箱admin@cloudera.cn,谢谢。- http://freesms.cloudapp.net");
Response.End();
}
}
else
{
if (!ActionValidator.IsValid(ActionValidator.ActionTypeEnum.Postback))
{
Response.Write("您发送得太频繁,被系统判断为广告。广告或其他定制业务请联系邮箱admin@cloudera.cn,谢谢。- http://freesms.cloudapp.net");
Response.End();
}
}
}
PS: 敌人总是狡诈的 ,后来我又发现那个人通过使用代理来变换IP ,继续通过我的服务发送广告。这就要继续优化程序了,比如把广告内容的md5也作为key记录下来。也许您也一样,需要面对各种各样的“敌情”。呵呵,希望本文对您有所帮助!
posted @
2009-09-19 20:36 流牛木马 阅读(2711) |
评论 (40) |
编辑