Web安全之C#语法学习

来源:互联网 发布:屏幕右下角激活windows 编辑:程序博客网 时间:2024/05/07 21:23

要让别人认识到代码中存在安全问题,就必须自己对开发语言具有一定了解,以前从未接触过C#,现在通过源代码静态分析平台总结一下C#语言中的安全知识点:

SQL注入

string sql = String.Format("UPDATE TBND_IE SET B_E={0} WHERE BEG_DATE='{1}' AND I_E='{2}' AND A_E='{3}' AND M_E='{4}'", Volume, Date, Id.I_E, Id.A_E, Id.M_E);......using (DbCommand dbCommand = DBFactory.MD.GetSqlStringCommand(sql))  //sink点

String.Format是将指定的 String类型的数据中的每个格式项替换为相应对象的值的文本等效项,如果上面的Date等对象的值来源于不可信数据源,sql字符串中就有可能引入污染数据源,后面执行数据库操作时,就有可能导致sql注入。

GetStoredProcCommand方法用于存储过程命令;
GetSqlStringCommand方法用于 SQL 文本命令,两个方法都会返回一个 DbCommand 对象

用于 SQL 语句的 DbCommand对象

使用 GetSqlStringCommand 方法创建用于内联 SQL 语句的 DbCommand 对象。特定的 SQL 命令在方法调用时做为一个参数进行传递。下列代码展示了如何使用 GetSqlStringCommand:

Database db = DatabaseFactory.CreateDatabase();string sqlCommand = "Select ID, LastName, FirstName From Cs";DbCommand dbCommand = db.GetSqlStringCommand(sqlCommand);

用于存储过程的 DbCommand 对象
要执行存储过程,必须使用 GetStoredProcCommand 方法来创建 DbCommand 对象。要执行存储过程的名称在方法调用时做为一个参数传递。下列代码展示了如何使用 GetStoredProcCommand:

Database db = DatabaseFactory.CreateDatabase();DbCommand dbCommand = db.GetStoredProcCommand("GetProductsByCategory");**

XML外部实体注入

var path = HttpContext.Current.Server.MapPath("~/Configuration/Ak.xml");...System.Xml.XmlDocument document = new System.Xml.XmlDocument();document.Load(path);   //sink

预防 XXE 攻击的最佳方式就是禁用 XML 实体解析,因此最好将document的XmlResolver 属性设置为 null 来禁用 XML Entity 解析。如:

document.XmlResolver = null;

如果必须应用程序中处理外部实体,应使用以下功能创建一个自定义 XmlResolver:
- 设置请求超时,预防无限延迟攻击
- 限制将检索的数据量
- 限制 XmlResolver 检索本地主机上的资源

另:[ 任何继承、重载、扩展XmlDocument的类都被视为sink点]

存储型XXS

public partial class IBCashTransferSearch : xQuant.Web.UI.Base.PageBaseEx{    protected void gvTrade_RowDataBound(object sender, GridViewRowEventArgs e){        HyperLink btnView = e.Row.FindControl("btnView") as HyperLink;        string sD = DataBinder.Eval(e.Row.DataItem, "SD").ToString(); //source点        string strMsg = string.Empty;        OTCManager mgr = new OTCManager();        XPOTCTrade trade = mgr.GetId(int.Parse(sD));        switch (strType)           {            case TradeType.CashTransferSealIn:                 btnView.NavigateUrl = string.Format("../Trade/Special/frmClear CashTransferDown.aspx?FromUrl=AccountSearch&TradeID={0}", sD);   //sink点             ...           }    }}

DataBinder.Eval(Object, String)方法是 在运行时计算数据绑定表达式 (返回对象的值)

GridViewCommandEventArgs 来自webcontrol,因此e.Row.DataItem视为不可信数据

btnView.NavigateUrl 视为sink点的原因是通过“HyperLink”控件可以在网页上创建链接,使用户可以在应用程序中的各个网页之间移动。“HyperLink”控件可以显示可单击的文本或图像。与大多数 ASP.NET 控件不同,用户单击“HyperLink”控件并不会在服务器代码中引发事件,此控件只起到导航的作用。

反射型XSS

      string strInst = Request["iD"].ToString();//source点      ClientScript.RegisterStartupScript(this.GetType(), "para", "<script>iD=" + strInst.Trim() + "</script>"); //sink点

ClientScript.RegisterStartupScript(this.GetType(),*),运行前端页面JS脚本,this.GetType()即指代当前页面Page。

134     namespace xQuant.Web.WebSite.UI.Limit.Report145     {156         public partial class VaRDetailRpt : System.Web.UI.Page167         {168             public string P_ID179             {280                 get251                 {252                     return this.hdP_ID.Value;243                 }254                 set265                 {276                     this.hdP_ID.Value = value;   //sink点287                 }278             }

System.Web.UI.Page ,Page类,表示从 ASP.NET Web 应用程序的宿主服务器请求的 .aspx 文件(又称为 Web 窗体页)。
this.hdP_ID.Value = value; 类似于将给页面控件赋值。

public partial class AcctSubjectBalanceView : xQuant.Web.UI.Base.LogonPageBase{    protected void ge_Rd(object sender, GridViewRowEventArgs e){         e.Row.Cells[0].Text = "<a href=\"#\" onclick=\"openwindow('" + string.Format(url, DataBinder.Eval(e.Row.DataItem, "fefe"), txtDate.Text.Trim(), InstID, "1") + "','grg',800,580)\" style=\"color:blue;\">what </a>&nbsp;" +         ...

e.Row.Cells[0].Text:某个控件要显示的内容,这里如果传入不可信数据,就有可能发生反射型XSS.

236     string currentClearingDate = TTRD_DAYEND_FLOW.GetCurrentDate();        ....335         ReStart(txtDate.Text);   //source点

txtDate.Text,获取某个控件中的值,这个值可能来源于不可信数据。

跨站脚本:弱验证

this.gvTaskParamList.Rows[StringHelper.GetInt(this.txtT_XML.ToolTip)].Cells[3].Text =Server.HtmlEncode(this.txtT_XML.Text);

给StringHelper.GetInt(this.txtT_XML.ToolTip)].Cells[3].Text控件赋值的数据来自不可信数据源,有可能造成跨站脚本漏洞。

Xpath注入

33         public class LimitClient : xQuant.Web.UI.Base.ServiceBase            ... 1037           private string GetNodeValue(XmlDocument xmlDoc, string strAttribute, string strKey)    //sink点1038           {1039               if (string.IsNullOrEmpty(strAttribute.Trim()) || string.IsNullOrEmpty (strKey.Trim())) return string.Empty;  1041               XmlNodeList nodeList = null;1042               string[] strKeys = strKey.Split('&');1043               if (strKeys.Count() == 2)1044                   nodeList = xmlDoc.SelectNodes("//ATYPE[@KEY='" + strKeys[1] + "']/PTYPE[@KEY='" + strKeys[0] + "']");  //sink点                }

如果strkey带有污点数据,就会在1044行造成xpath注入。
xmlDoc.SelectNodes(xpath,namespace) //假设xmlDoc为根节点,整个文档下的查询
还是xmlDoc.ChildNodes[i].SelectNodes(xpath,namespace) //节点下的查询

缺少XML验证

8      namespace xQuant.Model.IrCurve9      {10         [Serializable]11         public class GroupItem12         {            ...21             public static List<GroupItem> LoadFromXml(string xmlString)22             {23                 List<GroupItem> r = new List<GroupItem>();    25                 if (string.IsNullOrEmpty(xmlString))26                     return r; [1]XmlTextReader.Create(new StringReader(xmlString)):semantic_2527                 XmlReader xml = XmlTextReader.Create(new StringReader(xmlString));//sink

程序直接解析来自不可信赖的XML文档,会给攻击者提供恶意注入等非法攻击的机会;程序解析来自不可信赖资源的XML时,应该使用DTD,XDR 或 XSD 验证 XML 文档。详细验证方法参考。
详细请参考如何使用 C# 通过.NET 中的 DTD,XDR 或 XSD 验证 XML 文档

路径遍历

33     string fileName = Path.Combine(HttpRuntime.BinDirectory, logConfigFile);34     if (!File.Exists(fileName))       ...

HttpRuntime.BinDirectory:获取当前应用程序的 /bin 目录的物理路径,将这个路径直接用于文件操作不是一个安全的做法。
路径遍历是应用程序对用户可控制的输入未经合理验证,就传给一个文件API;攻击者可能会使用一些特殊的字符(如“..”和“/”)摆脱受保护的限制,访问一些受保护的文件或目录,从而可以越权访问或者覆盖敏感数据。

路径遍历的防御主要是需对用户提交的内容进行严格的过滤,这里主要指过滤目录跳转符”..”、”/”,字符截断符”%00”,dir命令等。也可采用黑白名单策略。如或者创建一份资源白名单,允许其中的字符出现在资源名称中、只运行合法后缀的文件出现在资源名称中。

非托管资源未释放

        {        ...            XPBond xp = new XPBond(true); //source点            xp.SaveType = SaveType.Insert;            QueryBond(xp, reader, true);                return xp; //sink点        }

程序在发生异常或处理不当的时候可能无法释放非托管的资源。最常见的一类非托管资源是包装操作系统资源的对象,例如文件,窗口,网络连接,数据库连接,画刷,图标等。

任何包含非托管资源的类,都应该继承IDisposable接口;实现Dispose()方法,在其中释放托管资源和非托管资源,并将对象本身从垃圾回收器中移除(垃圾回收器不在回收此资源); 实现类析构函数,在其中释放非托管资源。
MSDN建议按照下面的模式实现IDisposable接口:

 public class Foo: IDisposable {     public void Dispose()     {        Dispose(true);        GC.SuppressFinalize(this);     }     protected virtual void Dispose(bool disposing)     {        if (!m_disposed)        {            if (disposing)            {               // Release managed resources            }            // Release unmanaged resources            m_disposed = true;        }     }     ~Foo()     {        Dispose(false);     }     private bool m_disposed; }

HTTP消息头注入

            cookie.Value = Request.QueryString["token"];

程序将未经验证的数据直接插入HTTP头文件,可能会造成HTTP响应截断等攻击,引发跨站脚本,cookie操纵等漏洞。
HTTP消息头注入的防御方法:在恰当位置进行输入验证和过滤,最保险的方法是创建安全字符白名单,只允许白名单里的字符出现在Http消息头文件中。

NUll引用

                                   试图将secuInstructionOut转为SecuInstruction类型,如失败,则返回null                           SecuInstruction secuInstructionIn = secuInstructionOut.Clone() as SecuInstruction; //source     secuInstructionIn.BizType = xQuant.Model.XPO.Set.XPSetInstructionSecu.BIZTYPE_TRANSFERIN;//sink

as 运算符类似于强制转换操作。当用as操作符进行类型转换的时候,首先判断当前对象的类型, 当类型满足要求后才进行转换。但是,如果转换不可行,as 会返回 null 而不是引发异常.

目录

    • SQL注入
    • XML外部实体注入
    • 存储型XXS
    • 反射型XSS
    • 跨站脚本弱验证
    • Xpath注入
    • 缺少XML验证
    • 路径遍历
    • 非托管资源未释放
    • HTTP消息头注入
    • NUll引用
      • 目录

0 0
原创粉丝点击