关于ASP.NET的ViewState相关学习

由于ASP.NET存在服务器端控件,但是Web又是无状态的,于是就用到了ViewState,将服务器控件状态信息存储到ViewState,通过与服务器交互进行数据的传递。而ViewState其实是存储在hidden中,这样就很容易被非法获取、篡改。

于是今天的引子就出来了,即初步研究下ViewState相关原理机制,然后一定程度解决前文所述问题。

有两篇好文可以先分享出来:

.Net 反序列化之 ViewState 利用 - 安全客,安全资讯平台 (anquanke.com)https://www.anquanke.com/post/id/221630#h2-4ASP.NET 小技巧:重写 ViewState 的存储目的地,以提高页面性能 - 走看看 (zoukankan.com)http://t.zoukankan.com/RChen-p-338327.html我这里从实用角度做一简化,从代码层面、配置方面简单记录下。

代码层面,ViewState主要就涉及2个Page重写方法:

一个是加载ViewState(来源于客户端)LoadPageStateFromPersistenceMedium()

一个是保存ViewState(然后输出到客户端)SavePageStateToPersistenceMedium(object state)

那么,我们为了防篡改,可以对这两个方法进行重写,对保存ViewState进行加密、对加载ViewState解密处理。

保存ViewState进行加密

        /// <summary>
        /// 传递到前端执行,进行数据加密
        /// </summary>
        /// <param name="viewState"></param>
        protected override void SavePageStateToPersistenceMedium(object viewState)
        {
            LosFormatter format = new LosFormatter();
            StringWriter writer = new StringWriter();
            //序列化
            format.Serialize(writer, viewState);

            string vsRaw = writer.ToString();
            //加密
            string vsText = DESCryptoServiceHelper.Encrypt(vsRaw);

            Pair pair;
            PageStatePersister persister = this.PageStatePersister;
            object newViewState;
            if (viewState is Pair)
            {
                pair = (Pair)viewState;
                persister.ControlState = pair.First;
                newViewState = pair.Second;
            }
            else
            {
                newViewState = viewState;
            }
            //重新保存
            persister.ViewState = vsText;
            persister.Save();
        }

加载ViewState解密

        /// <summary>
        /// 后台加载的时候调用,需要先解密
        /// </summary>
        /// <returns></returns>
        protected override object LoadPageStateFromPersistenceMedium()
        {
            PageStatePersister persister = this.PageStatePersister;
            persister.Load();

            if (persister != null)
            {
                string viewState = persister.ViewState.ToString();

                string vsRaw = DESCryptoServiceHelper.Decrypt(viewState);

                LosFormatter formatter = new LosFormatter();
                //解密
                return formatter.Deserialize(vsRaw);
            }
            return null;
        }

Web.Config配置

<system.web>
    <compilation debug="true" targetFramework="4.0" />
    <pages viewStateEncryptionMode="Always" enableViewStateMac="true"></pages>
</system.web>

配置节点pages,第一个属性控制是否加密,第二个控制是否通过Mac地址加密

结果验证

默认前端的ViewState是可以反序列化的,即便通过第一种方法进行加密后也是可以反序列化的,不过反序列化后的内容,其实是加密的结果,也是可以起到保护作用的;

但是通过Web.Config配置加密后,是无法反序列化的,直接就报错了,看来还是.NET自己的招式比较高级。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值