本博推荐文章快速导航: Sql Server2005 Transact-SQL 新兵器学习 MCAD学习 代码阅读总结 ASP.NET状态管理 DB(数据库) WAP WinForm Flex

代码阅读总结之ASP.NET StartKit TimeTracker(角色权限之捉虫笔记)

在ASP.NET StartKit TimeTracker中由于程序设计上的小失误,我们可以利用这个BUG来达到越权访问aspx页面的能力.

我们都知道该系统定义了三种角色,分别为
Administrator(管理员)
Project Manager(项目管理者)
Consultant(顾问)

只有Administrator角色的用户才可以访问管理信息页面(ProjectList.aspx)

现在我来描述一下错误现象:

现在我有一个管理员的帐户ai_ai@126.com.
我们先用这个帐户登陆,去创建一个Consultant角色的帐户:ai_c@126.com
然后马上关闭浏览器.(注意我这里说的关闭是用MOUSE点击浏览器关闭按钮而不是用程序提供的注销按钮)
再打开浏览器进入登陆页,用帐户:ai_c@126.com登陆系统.
这时我们就可以利用顾问角色的帐户访问管理信息页面
http://localhost/TTWebCSVS_cn/ProjectList.aspx?index=2

这个BUG岂不是和系统角色访问权限相背.


现在让我们来找虫
我们可以看到该系统的登陆用户角色信息是存放在一个COOKIE中的.
数据存放前进行了加密,利用了类FormsAuthentication.Encrypt的静态方法.
该COOKIE的名称在Global中定义为一个常量:
public const string UserRoles = "userroles"
这就是BUG之一

现在我们再看Global中Application_AuthenticateRequest事件中另一段代码:
Response.Cookies[UserRoles].Value = cookieStr;
Response.Cookies[UserRoles].Path = "/";
Response.Cookies[UserRoles].Expires = DateTime.Now.AddMinutes(1);
从以上我们可以得知,该COOKIE的有效时间是一分钟.
这样我们在前一登陆帐户关闭后,一分钟内马上利用另一帐户登陆,这样后面的帐户可以取到前一帐户的角色信息.
因为2个登陆帐户用的是同一个叫userroles的COOKIE
这又是BUG之一

为了解决这个BUG,我们可以对程序越微修改
就是把COOKIE名称唯一化.

在protected void Application_AuthenticateRequest(Object sender, EventArgs e)

在代码
if (Request.IsAuthenticated == true) 
{
后面添加
string UserRoles=Global.UserRoles+Context.User.Identity.Name;
这样可以保证每个登陆帐户的角色信息COOKIE名称不一样.

同时注意还要修改,退出按钮事件 (Banner.ascx.cs中)

private void LogOff_Click(object sender, System.EventArgs e)
        
{
            FormsAuthentication.SignOut();

            
string UserRoles=Global.UserRoles+Context.User.Identity.Name;
            
// Invalidate roles token
            Response.Cookies[UserRoles].Value = "";
            Response.Cookies[UserRoles].Path 
= "/";
            Response.Cookies[UserRoles].Expires 
= new System.DateTime(19991012);

            Context.User 
= null;
            Response.Redirect(
"Default.aspx"false);
        }

 

当然还可以有其他解决办法
例如把登陆用户角色信息数据放到系统的身份验证cookie的身份验票的UserData(Cookie中存储的用户定义字符串)中

具体实现可以参考我的另一文章:
代码阅读总结之ASP.NET StartKit TimeTracker(角色权限)
http://www.cnblogs.com/aierong/archive/2004/12/21/79966.html

谢谢!

最后修改于2005年4月18日

posted @ 2005-01-17 14:56 aierong 阅读(3855) 评论(15)  编辑 收藏 网摘 所属分类: Asp.net代码阅读总结

  回复  引用    
#1楼 2005-01-18 09:28 | 木鱼。NET [未注册用户]
我也将微软的TimeTracker权限认证,用到自己的系统中,在客户那演示时碰到了这个问题,谢谢你的讲解!
你的另一篇文章例子也不错,学习!
  回复  引用  查看    
#2楼 2005-01-18 18:13 | Lantaio      
虽然不知道是不是最安全的解决方案,但这样的文章对于像我这样的初学者来说十分有帮助。十分感谢!收藏!
  回复  引用  查看    
#3楼 [楼主]2005-01-18 18:18 | aierong      
哈哈

原来大家都是初学者
希望大家多多总结并交流

谢谢
  回复  引用    
#4楼 2005-01-20 17:19 | 木鱼。NET [未注册用户]
试了你的方法,没解决问题!
不知道是怎么回事,难道是我的页面用的框架,但我把IE关了,重新打开,问题依然存在!
不知道还有没有其它地方需要注意的?

  回复  引用  查看    
#5楼 [楼主]2005-01-21 09:55 | aierong      
我的程序现在没有问题了

你再检测你程序
一定要保证登陆用户角色COOKIE名称唯一

  回复  引用  查看    
#6楼 2005-01-21 11:25 | 木鱼.NET      
我在Global.asax.cs中修改了两处:
1、

Response.Cookies[Globals.UserRoles].Value = cookieStr;
Response.Cookies[Globals.UserRoles].Path = "/";
Response.Cookies[Globals.UserRoles].Expires = DateTime.Now.AddMinutes(1);
替换为:
HttpCookie cookie = new HttpCookie(
                        FormsAuthentication.FormsCookieName, // Name of auth cookie
                        cookieStr); // Hashed ticket

                    // Set the cookie's expiration time to the tickets expiration time
                    if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;

                    // Add the cookie to the list for outgoing response
                    Response.Cookies.Add(cookie);
2、

    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Context.Request.Cookies[Globals.UserRoles].Value);
替换为:
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Context.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
相当于把Globals.UserRoles换为FormsAuthentication.FormsCookieName,但其它地方没改,应该判断时 也存在问题,但试了下也成功了,
这个项目客户催的紧,所以先应付一下,等回头再研究!
还请你先分析一下,看问题出在哪?


  回复  引用  查看    
#7楼 [楼主]2005-01-21 23:14 | aierong      
to:木鱼.NET

你用FormsAuthentication类的静态属性FormsCookieName做COOKIE的名称,我认为好象不行吧

我记得FormsAuthentication.FormsCookieName取到的是当前应用程序的已配置 Cookie 名称,它并不唯一.

在ASP.NET StartKit TimeTracker中,我建议你在
Application_AuthenticateRequest事件中
在语句if (Request.IsAuthenticated ) 后
定义一个局部变量,做Cookie名称
string UserRoles=Globals.UserRoles+HttpContext.Current.User.Identity.Name


对了,还要记得修改注销按钮的事件里的Cookie名称


  回复  引用  查看    
#8楼 [楼主]2005-04-18 20:50 | aierong      
上次POST错误

现在修改好了

  回复  引用    
#9楼 2005-04-22 09:42 | tan [未注册用户]
private System.ComponentModel.IContainer components = null;

public Global()
{
InitializeComponent();
}

在你的global.acax.cs文件中多了这两处代码,何故?调试的时候出现错误,如果有这些代码的话,没有则没有问题
我不知道这两处代码的目的是什么?
我也是初学,请多指教
  回复  引用  查看    
#10楼 [楼主]2005-04-22 09:45 | aierong      
@tan

global.acax.cs文件中多了这两处代码

什么意思?

我只在global.acax.cs中添加了一行代码

  回复  引用    
#11楼 2005-07-16 11:52 | zxd9915 [未注册用户]
为什么非用cookieb不可呢?把roles string[]存入hashtable,附加到content.user中不就行了?
  回复  引用    
#12楼 2005-11-19 03:05 | zlp8383178 [未注册用户]
俺想问一下,要是客户端禁用COOKIE,这个方案还可以用吗?
有更完善和友好的方法吗?
热盼联系:
zlp8383178@163.com
谢谢!
  回复  引用  查看    
#13楼 [楼主]2005-11-19 08:46 | aierong      
这种角色权限控制是基于cookie的

要是客户关闭cookie
可以考虑用会话或其他方式
  回复  引用    
#14楼 2006-02-20 18:02 | 周旋武 [未注册用户]
比如我在contacts.ascx 中放置个 label,在Announcements.ascx中放置个按钮,我想让Announcements.ascx点击按钮后,contacts.ascx 中的label中text有所反应。contacts.ascx 和Announcements.ascx加载到同个页面上。希望高手在portal原由代码上再加代码举事例。
  回复  引用    
#15楼 2007-03-20 14:15 | wmjmath [未注册用户]
看贴就回贴,支持!




标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-11-08 09:45 编辑过
Google站内搜索
[推荐职位]上海盛大网络招聘架构师

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》


相关链接: