当前位置:编程学习 > C#/ASP.NET >>

一个asp.net开发的公司内部系统URL问题

情况是这样的。系统现在是稳定的上线了,但是发现一些用户自己随便修改url后面的参数进入页面操作。比如
URL是:Default.aspx?Type=Edit&ID=2012。
有什么方法防止呢,我想到的是URL加密.
但是程序里面都是用 Page.Request.QueryString或者用Page.Request.QueryString.Get("")这两个方法。 
加密了,肯定获取参数时,要解密。
难道 重写 QueryString 和它的Get方法吗?

大家给个好点的方案.. --------------------编程问答-------------------- Edit   2012  重要就加密 不重要就明码  
参见淘宝 查询 --------------------编程问答-------------------- 如果你后台参数是固定的,那你可以用switch() 来限制,必须规定可以参数才可以通过,


 如果是不固定的,那还真的.... --------------------编程问答-------------------- 我觉得加密没有判断范围好。

判断下参数,如果超过范围,就提示错误呗。


--------------------编程问答-------------------- 你可以对url做下编码 对于一般用户他们就不明白了
对于某些页面 你可以多加个参数 生成随机数 过期不候
我推荐的方式
            进行权限验证 不同用户进入不同的页面 根据角色权限进行验证 改了也进不去 或者数据无效 --------------------编程问答-------------------- 目前我想到的也就是生成随机数验证一下 --------------------编程问答--------------------

 #region DES 加密/解密

        private static byte[] key = ASCIIEncoding.ASCII.GetBytes("99999999");
        private static byte[] iv = ASCIIEncoding.ASCII.GetBytes("11111111");





        /// <summary>
        /// DES加密。
        /// </summary>
        /// <param name="pToEncrypt">输入字符串。</param>
        /// <returns>加密后的字符串。</returns>
        public static string DESEncrypt(string pToEncrypt)
        {
                        DESCryptoServiceProvider des = new DESCryptoServiceProvider();   //把字符串放到byte数组中   

            byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
            //byte[]   inputByteArray=Encoding.Unicode.GetBytes(pToEncrypt);   

            des.Key = key;   //建立加密对象的密钥和偏移量 
            des.IV = iv;    //原文使用ASCIIEncoding.ASCII方法的GetBytes方法 
            MemoryStream ms = new MemoryStream();      //使得输入密码必须输入英文文本 
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);

            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();

            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            ret.ToString();
            return ret.ToString();
        }

        /// <summary>
        /// DES解密。
        /// </summary>
        /// <param name="pToDecrypt">输入字符串。</param>
        /// <returns>解密后的字符串。</returns>
        public static string DESDecrypt(string pToDecrypt)
        {
            //MemoryStream ms = null;
            //CryptoStream cs = null;
            //StreamReader sr = null;

            //DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            //try
            //{
            //    ms = new MemoryStream(Convert.FromBase64String(inputString));
            //    cs = new CryptoStream(ms, des.CreateDecryptor(key, iv), CryptoStreamMode.Read);
            //    sr = new StreamReader(cs);
            //    return sr.ReadToEnd();
            //}
            //finally
            //{
            //    if (sr != null) sr.Close();
            //    if (cs != null) cs.Close();
            //    if (ms != null) ms.Close();
            //}

            try
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();

                byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
                for (int x = 0; x < pToDecrypt.Length / 2; x++)
                {
                    int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
                    inputByteArray[x] = (byte)i;
                }

                des.Key = key;   //建立加密对象的密钥和偏移量 
                des.IV = iv;    //原文使用ASCIIEncoding.ASCII方法的GetBytes方法 
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);

                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();

                StringBuilder ret = new StringBuilder();   //建立StringBuild对象,CreateDecrypt使用的是流对象,必须把解密后的文本变成流对象   

                return System.Text.Encoding.Default.GetString(ms.ToArray());
            }
            catch (Exception)
            {
                
                //throw;
                return "";
            }
           
        }

        #endregion
    }


加密参数。

不过要真正的安全就要做好权限。

例如判断ID传值的信息是否允许当前用户查看,再显示信息。 --------------------编程问答--------------------
引用 6 楼 yan267 的回复:
C# code

 #region DES 加密/解密

        private static byte[] key = ASCIIEncoding.ASCII.GetBytes("99999999");
        private static byte[] iv = ASCIIEncoding.ASCII.GetBytes("11111111");





        /……

加密解密的方法 我倒是知道,但是我现在怎么只要修改一个地方,整个程序的url都得以加密.而且获取url参数时 也是得到正确的参数.  --------------------编程问答--------------------
引用 7 楼 yhb417 的回复:
引用 6 楼 yan267 的回复:

C# code

#region DES 加密/解密

private static byte[] key = ASCIIEncoding.ASCII.GetBytes("99999999");
private static byte[] iv = ASCIIEncoding.ASCII.GetBytes("11111111");



……


只修改一个地方的代码。。。。。
--------------------编程问答-------------------- 你可以用伪静态的那种方式,把你要加密解密 在UrlRewriter 所有请求都经过这里,在解析成你要的URL --------------------编程问答-------------------- 仔细想想是需要加密(encrypt)还是需要校验(validate) --------------------编程问答-------------------- 楼主要写几个方法(下面的可以合并,至于是form还是QueryString自己看):
1.url是否静态化,比如csdn的帖子生成,用的是自定义模板,但也有规则
http://topic.csdn.net/u/20120117/10/5eecf9b4-6215-42fc-8d85-454444c85d0b.html?1129
2.request对象检查(是否存在)
3.request对象的合法性(多少、过滤特殊、非法字符什么的)
--------------------编程问答-------------------- 至于加密措施,可以加也可以不加,个人觉得没必要的,url后面的参数本来就是个变数(特定标记参数),不让人修改干嘛呢 --------------------编程问答-------------------- 加密解密的方法 我倒是知道,但是我现在怎么只要修改一个地方,整个程序的url都得以加密.而且获取url参数时 也是得到正确的参数. 

想要获取url还是正确的,可以用一层httphandler进去拦截,在这个handler里面进行解密,然后再转发一下,其它页面就可以正常获取了

至于整个url加密,估计就得有一个专门产生url 的地方了 --------------------编程问答--------------------
引用 10 楼 findcaiyzh 的回复:
仔细想想是需要加密(encrypt)还是需要校验(validate)

是的,我觉得这个实现要简单些,主要是针对不要修改大部分的代码.

引用 8 楼 yan267 的回复:
....

就是只修改小部分的代码,每个aspx页面都继承了一个公共父类,能在这个父类里面做些什么能实现就好,
或者像13说的,用httphandler ,但是这个具体怎么去实现?  --------------------编程问答-------------------- 无需加密,重要的是你需要对操作的页面进行权限的验证,看是否对这个id有操作的权限 --------------------编程问答-------------------- 京东  QQ空间 什么的很多地方都是明文 

分两种
1.在于你传递的是什么类型的数据,涉及到很隐私的就加密
2.页面的权限判断
--------------------编程问答-------------------- 判断 用户是否对 2012 有 EDIT 操作权限 --------------------编程问答-------------------- 没弄个基类判断个权限么,让所有页面继承
--------------------编程问答-------------------- 不止是简单的权限控制的,权限本来就有控制,
但是权限控制的是针对某个功能有没有增删改查功能的问题,

但是针对某个订单的状态到了一定程度,按正常的程序连接是,访问不了的,但是知道最终的编辑页面直接输入url就可以操作 了,还有很多类似的情况。 所以这时URL加密就很有必要。 --------------------编程问答-------------------- 那就用Request.UrlReferrer判断下 --------------------编程问答-------------------- 推荐用权限控制页面
--------------------编程问答-------------------- 但是发现一些用户自己随便修改url后面的参数进入页面操作
--------------------------------------------
页面没有设置权限

和url参数没关系 --------------------编程问答--------------------
引用 14 楼 yhb417 的回复:
引用 10 楼 findcaiyzh 的回复:

仔细想想是需要加密(encrypt)还是需要校验(validate)

是的,我觉得这个实现要简单些,主要是针对不要修改大部分的代码.


引用 8 楼 yan267 的回复:
....

就是只修改小部分的代码,每个aspx页面都继承了一个公共父类,能在这个父类里面做些什么能实现就好,
或者像13说的,用httphandle……


URL重写只能帮你减少解密的代码。
加密的都还是要写的。


URL重写继承
web.config
<add type="URLRewriter" name="HttpModule"/>


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
///URLRewriter 的摘要说明
/// </summary>
public class URLRewriter : System.Web.UI.Page, IHttpModule
{
public URLRewriter()
{
//
//TODO: 在此处添加构造函数逻辑
//
}
    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(this.ReUrl_BeginRequest);
        context.EndRequest += new EventHandler(this.ReUrl_EndRequest);
    }
    private void ReUrl_BeginRequest(object sender, EventArgs e)
    {
        HttpContext Context = ((HttpApplication)sender).Context;
        Context.Response.Buffer = true;
        Context.Response.ExpiresAbsolute = DateTime.Now.AddSeconds(-1.0);
        Context.Response.Expires = 0;
        Context.Response.CacheControl = "no-cache";
        _url = Context.Request.Url.ToString().ToLower();
        _url = _url.Replace("localhost", "111111.axpx");
      //  string urlquest = Context.Request.Url.Query;
       // string url = Context.Request.Url.AbsolutePath;



        Context.Response.Redirect(_url);




    }
    public void Dispose()
    {
    }

    protected string _url = "";
    protected string strUrl
    {
        get { return _url; }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="args"></param>
    private void ReUrl_EndRequest(object sender, EventArgs args)
    {

    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="Context"></param>
    public void ProcessRequest(HttpContext Context)
    {
    }
    /// <summary>
    /// 实现“IHttpHandler”接口所必须的成员
    /// </summary>
    /// <value></value>
    public bool IsReusable
    {
        get { return false; }
    }


}
--------------------编程问答-------------------- 加个密被 在弄个错误页~~~ --------------------编程问答--------------------
引用 19 楼 yhb417 的回复:
不止是简单的权限控制的,权限本来就有控制,
但是权限控制的是针对某个功能有没有增删改查功能的问题,

但是针对某个订单的状态到了一定程度,按正常的程序连接是,访问不了的,但是知道最终的编辑页面直接输入url就可以操作 了,还有很多类似的情况。 所以这时URL加密就很有必要。

既然正常的程序是访问不了的,那么没有权限进入这个页面时就应该直接弹出警告禁止其访问,而不是对url加密
--------------------编程问答-------------------- "showtimeList"
这个属性不就是加载的数据吗?
直接对其分析不就好了
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,