常见网站漏洞及解决办法

来源:互联网 发布:潜意识的力量 知乎 编辑:程序博客网 时间:2024/04/28 15:28

自己最近也刚开始学习网站安全的技术,以下有写的不对的地方还请高手多指点啊.

  网站漏洞主要集中在动态网页中,静态网站基本不存在什么漏洞。

1.sql注入和跨站点脚本攻击

2.上传漏洞

3.文本编辑器漏洞

4.网站目录及密码安全

解决办法:

1.sql注入和跨站点脚本攻击:对这类漏洞来说就是用一些安全扫描工具进行检测,然后修复,以下是我个人总结的一点小知识:

对于asp网站:

一。跨站点攻击

1.在需要用户或管理员输入数据的地方用js去除危险字符

js脚本:

function RemoveBad(strTemp) {

strTemp = strTemp.replace(/[$ <> & % ' ( ) + - = " ; / ]/g, "")

return strTemp;

}

//asp脚本方法

<%

      '过滤掉危险的html和特殊字符,防止跨网站攻击

    function nohtml(str)

             dim re

             Set re=new RegExp

             re.IgnoreCase =true

             re.Global=True

             re.Pattern="(/<.[^/<]*/>)"

             str=re.replace(str," ")

             re.Pattern="(/<//[^/<]*/>)"

             str=re.replace(str,"")

             

             re.Pattern="([/'/&/-/+/=/(/)/;/[/]/{/}])" '去除特殊符号

             str=re.replace(str,"")            

             

             nohtml=str

             set re=nothing

       end function

             

       '对要显示的数据进行编码,防止显示危险字符

       function showdata(str)

              showdata=server.HTMLEncode(nohtml(str))

       end function

%>

 

对于aspx网站来说,有一个通用的安全检测类是很重要的,以下是个人总结:

namespace DZ.Security
{
    //输入数据安全性相关
    public class Sec
    {
        #region 检测输入的内容是否有攻击的可能性
        /// <summary>
        /// 检测输入的内容是否有攻击的可能性
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string par_queryString_forStr(string str)
        {
            //大于20很可能是注入攻击

            string str_process = null;

            if (str.Length > 20)
            {
                str_process = str.Substring(0, 20);

            }
            else
            {
                str_process = str;

            }

            return str_process;

        }
        #endregion

        #region 检测int 类型的id号的和法性
        /// <summary>
        /// 检测int 类型的id号的和法性
        /// </summary>
        /// <param name="str">要检测的字符</param>
        /// <returns></returns>
        public static string par_queryString_forId(string str)
        {
            //ID数字 整型 最大值65535 不超过5个数字

            string str_process = null;

            if (str.Length > 5)
            {
                str_process = str.Substring(0, 5);

            }
            else
            {
                str_process = str;

            }

            return str_process;
        }
        #endregion

        #region 硬性过滤脏字符串
        /// <summary>
        /// 硬性过滤脏字符串
        /// </summary>
        /// <param name="str">要处理的字符串</param>
        /// <returns></returns>
        public static string par_filter_forNews(string str)
        {
            //硬性过滤
            //依次为 **竞争对手,拿我的免费产品卖钱的家伙
            string[] filterStr = {
      **
                                  
          //领风五年,域名:
         
   };

            int filterLen = filterStr.Length;

            for (int i = 0; i < filterLen; i++)
            {
                str = str.Replace(filterStr[i], "");
            }

            return str;

        }
        #endregion        

        #region 对危险的html,Sql标记和特殊符号进行过滤
        /// <summary>
        /// 对危险的html,Sql标记和特殊符号进行过滤
        /// </summary>
        /// <param name="strHtml">要过滤的字符串</param>
        /// <returns>过滤后的字符串</returns>
        public static string FilterToTxt(string strHtml)
        {           
            string[] aryReg = {                     
                        @"<script[^>]*?>.*?</script>",
                        @"<(///s*)?!?((/w+:)?/w+)(/w+(/s*=?/s*(([""'])(//[""'tbnr]|[^/7])*?/7|/w+)|.{0})|/s)*?(///s*)?>",
                        @"([/r/n])[/s]+",
                        @"&(quot|#34);",
                        @"&(amp|#38);",
                        @"&(lt|#60);",
                        @"&(gt|#62);",
                        @"&(nbsp|#160);",
                        @"&(iexcl|#161);",
                        @"&(cent|#162);",
                        @"&(pound|#163);",
                        @"&(copy|#169);",
                        @"&#(/d+);",
                        @"-->",
                        @"<!--.*/n",
                        @"select",                                   
                        @"delete",                                    
                         @"update",                                   
                         @"insert into",                                    
                @"Insert",
                         @"Delete",
                         @"update",
                         @"create",
                         @"drop",
                         @"exec",
                         @"dri",
                        @"[^/w/.@-]"
                           };

            string strOutput = strHtml;

            for (int i = 0; i < aryReg.Length; i++)
            {
                Regex regex = new Regex(aryReg[i], RegexOptions.IgnoreCase);
                strOutput = regex.Replace(strOutput, string.Empty);
            }

            return strOutput;
        }
        #endregion

    }

 

    //数据加密,解密
    public class EncAndDec
    {
        public string _QueryStringKey = "logowang"; //URL传输参数加密Key abcdefgh
        public string _PassWordKey = "hgfedcba";   //PassWord加密Key

        #region url 参数加密解密
        public static string UrlDecode(string input)
        {
            return HttpUtility.UrlDecode(input);
        }

        public static string UrlEncode(string input)
        {
            return HttpUtility.UrlEncode(input);
        }
        #endregion


        #region md5字符串加密
        /// <summary>
        /// md5字符串加密
        /// </summary>
        /// <param name="str">要加密字符串</param>
        /// <returns></returns>
        public string MD5Encrypt(string str)
        {
            try
            {
                byte[] hashvalue = (new MD5CryptoServiceProvider()).ComputeHash(Encoding.UTF8.GetBytes(str));
                return BitConverter.ToString(hashvalue);
            }
            catch
            {
                return String.Empty;
            }
        }
        #endregion


        #region 加密解密相关

        /// <summary>
        /// 加密URL传输的字符串
        /// </summary>
        /// <param name="QueryString">要加密的字符串</param>
        /// <returns></returns>
        public string EncryptQueryString(string QueryString)
        {
            return Encrypt(QueryString, _QueryStringKey);
        }


        /// <summary>
        /// 解密URL传输的字符串
        /// </summary>
        /// <param name="QueryString">要解密的字符串</param>
        /// <returns></returns>
        public string DecryptQueryString(string QueryString)
        {
            return Decrypt(QueryString, _QueryStringKey);
        }

        ///
        /// 加密帐号口令
        ///
        ///
        ///
        public string EncryptPassWord(string PassWord)
        {
            return Encrypt(PassWord, _PassWordKey);
        }


        /// <summary>
        /// 解密帐号口令
        /// </summary>
        /// <param name="PassWord"></param>
        /// <returns></returns>
        public string DecryptPassWord(string PassWord)
        {
            return Decrypt(PassWord, _PassWordKey);
        }


        /// <summary>
        /// DEC 加密过程
        /// </summary>
        /// <param name="pToEncrypt">要加密的字符串</param>
        /// <param name="sKey">加密密钥</param>
        /// <returns></returns>
        public string Encrypt(string pToEncrypt, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider(); //把字符串放到byte数组中

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

            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); //建立加密对象的密钥和偏移量
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);   //原文使用ASCIIEncoding.ASCII方法的GetBytes方法
            System.IO.MemoryStream ms = new System.IO.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>
        /// DEC 解密过程
        /// </summary>
        /// <param name="pToDecrypt">要解密的字符串</param>
        /// <param name="sKey">解密密钥</param>
        /// <returns></returns>
        public string Decrypt(string pToDecrypt, string sKey)
        {
            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 = ASCIIEncoding.ASCII.GetBytes(sKey); //建立加密对象的密钥和偏移量,此值重要,不能修改
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            System.IO.MemoryStream ms = new System.IO.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());
        }


        /// <summary>
        /// 检查己加密的字符串是否与原文相同
        /// </summary>
        /// <param name="EnString">加密的url</param>
        /// <param name="FoString">加密的Password</param>
        /// <param name="Mode">1:检测url参数,2:检测Password</param>
        /// <returns></returns>
        public bool ValidateString(string EnString, string FoString, int Mode)
        {
            switch (Mode)
            {
                default:
                case 1:
                    if (Decrypt(EnString, _QueryStringKey) == FoString.ToString())
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                case 2:
                    if (Decrypt(EnString, _PassWordKey) == FoString.ToString())
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
            }
        }
        #endregion
    }
}

 

 

2.在需要显示数据的地方用Html.encode()方法进行编码,如下:

在执行页中我们加入:

strUserName =server.HTMLEncode(Request.QueryString("userName"))

strUserName =server.HTMLEncode(Request.Form("userName"))

 

二。sql输入攻击

主要是在数据查询页面,对传过来的参数进行安全检测,避免不符合要求的参数进行数据库查询。如下:

if(Not IsNumeric(id)) then

      Response.write("没有相关数据")

else

      进行数据查询并显示数据

end if

 

 

2.上传漏洞:主要是对用户上传的文件进行检测,这个特别是在编写程序时特别重要,以下是我用到的aspx。上传检测代码:

 #region 实现图片上传lblhasPic,FileUpload1 lbladdArtic
    protected void upLoadPic(Label lblp, Label lblisSuccess, FileUpload fileload)
    {
        lblisSuccess.Text = "";
        lblp.ForeColor = System.Drawing.Color.Red;

        if (fileload.HasFile)
        {

            string fileContentType = fileload.PostedFile.ContentType;

            #region 获取上传文件的文件名并判断文件的合法性
            bool fileOk = true;
            string name = fileload.PostedFile.FileName; // 客户端文件路径
            FileInfo file = new FileInfo(name);
            string fileName = file.Name; // 文件名称

            if (fileName.Contains(";"))//上传文件含有分号,很有能是上传图片木马的前兆
            {
                fileOk = false;
            }
            #endregion

            if (fileOk)
            {
                if (fileContentType == "image/bmp" || fileContentType == "image/gif" || fileContentType ==

    "image/pjpeg")
                {
                    int isHasPic;//视频图片是否存在            


                    string relImgPath = "/hqvideo/advancedusers/VideoPictures/" + Session["username"].ToString() + "/" + Request.QueryString["ID"].ToString() + "/";

                    String path = Server.MapPath(relImgPath);//保存上传文件的文件夹upload虚拟路径对应的实际路径
                    string pt = path;
                    // picFileName = fileName;

                    if (!Directory.Exists(pt)) //如果文件夹不存在则创建
                    {
                        Directory.CreateDirectory(pt);
                    }

                    string webFilePath = pt + fileName; // 服务器端文件路径

                    //向数据库中添加视频信息
                    isHasPic = addVideoPic(fileName, relImgPath + fileName, txbpicinfo.Text, 0);
                    if (isHasPic != -1)
                    {

                        try
                        {
                            fileload.SaveAs(webFilePath); // 使用 SaveAs 方法保存文件

                            //最后一部高级验证,图片上传后的操作,判断是否真的是图片
                            StreamReader sr = new StreamReader(webFilePath, Encoding.Default);
                            string img = "";
                            string strContent = sr.ReadToEnd();
                            sr.Close();
                            string str = "request|script|.getfolder|.createfolder|.deletefolder|.createdirectory|.deletedirectory|.saveas|wscript.shell|script.encode|server.|.createobject|execute|activexobject|language=|public|dim";
                            foreach (string s in str.Split('|'))
                                if (strContent.IndexOf(s) != -1)
                                {
                                    File.Delete(webFilePath);
                                    img = "No";
                                    break;
                                }
                            //删除源文件
                            if (img == "No" && File.Exists(webFilePath))
                            {
                                File.Delete(webFilePath);//如果文件已经存在就删除
                                lblp.ForeColor = System.Drawing.Color.Red;
                                lblp.Text = "提示:文件格式不正确";
                            }
                            else
                            {
                                lblp.ForeColor = System.Drawing.Color.Green;

                                lblp.Text = "提示:文件“" + fileName + "”成功上传";
                            }
                         
                            txbpicinfo.Text = "";

                        }
                        catch (Exception ex)
                        {
                            lblp.Text = "提示:文件上传失败,失败原因:" + ex.Message;
                        }
                    }
                    else
                    {
                        lblp.Text = "提示:文件已经存在,请重命名后上传";
                    }

 

                }
                else
                {
                    lblp.Text = "提示:文件类型不符";
                }
            }
            else
            {
                lblp.Text = "请先选择要上传的图片";
            }
        }

        else
        {
            lblp.Text = "提示:文件类型不符";
        }


    }
    #endregion

 

 3.对文本编辑器漏洞来说主要的还是上传漏洞,如果再自己的项目中没有用到上传的功能还是把上传功能关闭,对新下载的文本编辑器,删除里面的实例程序一般都会以_开头,最好对文本编辑器所在的目录进行用户身份的验证。

 

4.

网站目录不要采取带有明显管理员信息的目录,如:admin,manager,等。采取自定义的命名方式。。可有效提高安全性,黑客在想进入你的后台时要先找到登陆地址,如果用上述的目录来说,就少了一份安全性,还有的网站为了方便管理,干脆把后台登陆地址放到了前台页面上,这样不是给黑客提供了方便吗?

有些网站后台密码太简单,这种问题很多是在一些企业网站里,由于企业用户缺乏安全知识,往往密码很简单,增加网站密码的安全性也是很重要的。

原创粉丝点击