.Net網站架構設計(七)網絡安全


.Net網站架構(七)網絡安全

談到網絡安全,首先得說一下web網站有哪些最常見漏洞。

非法輸入


Unvalidated Input

在數據被輸入程序前忽略對數據合法性的檢驗是一個常見的編程漏洞。隨着OWASP對Web應用程序脆弱性的調查,非法輸入的問題已成為大多數Web應用程序安全漏洞方面的一個普遍現象。

方案:要在web前端,和服務器端對數據的合法性進行驗證

public class PageValidate 

{

private static Regex RegPhone = new Regex("^[0-9]+[-]?[0-9]+[-]?[0-9]$");

private static Regex RegNumber = new Regex("^[0-9]+$");

private static Regex RegNumberSign = new Regex("^[+-]?[0-9]+$");

private static Regex RegDecimal = new Regex("^[0-9]+[.]?[0-9]+$");

private static Regex RegDecimalSign = new Regex("^[+-]?[0-9]+[.]?[0-9]+$"); //等價於^[+-]?\d+[.]?\d+$

private static Regex RegEmail = new Regex("^[\\w-]+@[\\w-]+\\.(com|net|org|edu|mil|tv|biz|info)$");//w 英文字母或數字的字符串,和 [a-zA-Z0-9] 語法一樣

private static Regex RegCHZN = new Regex("[\u4e00-\u9fa5]");



public PageValidate()

{

}





//數字字符串檢查#region 數字字符串檢查

public static bool IsPhone(string inputData)

{

Match m = RegPhone.Match(inputData);

return m.Success;

}

/**//// <summary>

/// 檢查Request查詢字符串的鍵值,是否是數字,最大長度限制

/// </summary>

/// <param name="req">Request</param>

/// <param name="inputKey">Request的鍵值</param>

/// <param name="maxLen">最大長度</param>

/// <returns>返回Request查詢字符串</returns>

public static string FetchInputDigit(HttpRequest req, string inputKey, int maxLen)

{

string retVal = string.Empty;

if(inputKey != null && inputKey != string.Empty)

{

retVal = req.QueryString[inputKey];

if(null == retVal)

retVal = req.Form[inputKey];

if(null != retVal)

{

retVal = SqlText(retVal, maxLen);

if(!IsNumber(retVal))

retVal = string.Empty;

}

}

if(retVal == null)

retVal = string.Empty;

return retVal;

}

/**//// <summary>

/// 是否數字字符串

/// </summary>

/// <param name="inputData">輸入字符串</param>

/// <returns></returns>

public static bool IsNumber(string inputData)

{

Match m = RegNumber.Match(inputData);

return m.Success;

}



/**//// <summary>

/// 是否數字字符串 可帶正負號

/// </summary>

/// <param name="inputData">輸入字符串</param>

/// <returns></returns>

public static bool IsNumberSign(string inputData)

{

Match m = RegNumberSign.Match(inputData);

return m.Success;

}

/**//// <summary>

/// 是否是浮點數

/// </summary>

/// <param name="inputData">輸入字符串</param>

/// <returns></returns>

public static bool IsDecimal(string inputData)

{

Match m = RegDecimal.Match(inputData);

return m.Success;

}

/**//// <summary>

/// 是否是浮點數 可帶正負號

/// </summary>

/// <param name="inputData">輸入字符串</param>

/// <returns></returns>

public static bool IsDecimalSign(string inputData)

{

Match m = RegDecimalSign.Match(inputData);

return m.Success;

}



#endregion



//中文檢測#region 中文檢測



/**//// <summary>

/// 檢測是否有中文字符

/// </summary>

/// <param name="inputData"></param>

/// <returns></returns>

public static bool IsHasCHZN(string inputData)

{

Match m = RegCHZN.Match(inputData);

return m.Success;

}



#endregion



//郵件地址#region 郵件地址

/**//// <summary>

/// 是否是浮點數 可帶正負號

/// </summary>

/// <param name="inputData">輸入字符串</param>

/// <returns></returns>

public static bool IsEmail(string inputData)

{

Match m = RegEmail.Match(inputData);

return m.Success;

}



#endregion



//其他#region 其他



/**//// <summary>

/// 檢查字符串最大長度,返回指定長度的串

/// </summary>

/// <param name="sqlInput">輸入字符串</param>

/// <param name="maxLength">最大長度</param>

/// <returns></returns>

public static string SqlText(string sqlInput, int maxLength)

{

if(sqlInput != null && sqlInput != string.Empty)

{

sqlInput = sqlInput.Trim();

if(sqlInput.Length > maxLength)//按最大長度截取字符串

sqlInput = sqlInput.Substring(0, maxLength);

}

return sqlInput;

}

/**//// <summary>

/// 字符串編碼

/// </summary>

/// <param name="inputData"></param>

/// <returns></returns>

public static string HtmlEncode(string inputData)

{

return HttpUtility.HtmlEncode(inputData);

}

/**//// <summary>

/// 設置Label顯示Encode的字符串

/// </summary>

/// <param name="lbl"></param>

/// <param name="txtInput"></param>

public static void SetLabel(Label lbl, string txtInput)

{

lbl.Text = HtmlEncode(txtInput);

}

public static void SetLabel(Label lbl, object inputObj)

{

SetLabel(lbl, inputObj.ToString());

}

//字符串清理

public static string InputText(string inputString, int maxLength)

{

StringBuilder retVal = new StringBuilder();



// 檢查是否為空

if ((inputString != null) && (inputString != String.Empty))

{

inputString = inputString.Trim();



//檢查長度

if (inputString.Length > maxLength)

inputString = inputString.Substring(0, maxLength);



//替換危險字符

for (int i = 0; i < inputString.Length; i++)

{

switch (inputString[i])

{

case '"':

retVal.Append(""");

break;

case '<':

retVal.Append("<");

break;

case '>':

retVal.Append(">");

break;

default:

retVal.Append(inputString[i]);

break;

}

}

retVal.Replace("'", " ");// 替換單引號

}

return retVal.ToString();



}

/**//// <summary>

/// 轉換成 HTML code

/// </summary>

/// <param name="str">string</param>

/// <returns>string</returns>

public static string Encode(string str)

{

str = str.Replace("&","&");

str = str.Replace("'","''");

str = str.Replace("\"",""");

str = str.Replace(" "," ");

str = str.Replace("<","<");

str = str.Replace(">",">");

str = str.Replace("\n","<br>");

return str;

}

/**//// <summary>

///解析html成 普通文本

/// </summary>

/// <param name="str">string</param>

/// <returns>string</returns>

public static string Decode(string str)

{

str = str.Replace("<br>","\n");

str = str.Replace(">",">");

str = str.Replace("<","<");

str = str.Replace(" "," ");

str = str.Replace(""","\"");

return str;

}



public static string SqlTextClear(string sqlText)

{

if (sqlText == null)

{

return null;

}

if (sqlText == "")

{

return "";

}

sqlText = sqlText.Replace(",", "");//去除,

sqlText = sqlText.Replace("<", "");//去除<

sqlText = sqlText.Replace(">", "");//去除>

sqlText = sqlText.Replace("--", "");//去除--

sqlText = sqlText.Replace("'", "");//去除'

sqlText = sqlText.Replace("\"", "");//去除"

sqlText = sqlText.Replace("=", "");//去除=

sqlText = sqlText.Replace("%", "");//去除%

sqlText = sqlText.Replace(" ", "");//去除空格

return sqlText;

}

#endregion



//是否由特定字符組成#region 是否由特定字符組成

public static bool isContainSameChar(string strInput)

{

string charInput = string.Empty;

if (!string.IsNullOrEmpty(strInput))

{

charInput = strInput.Substring(0, 1);

}

return isContainSameChar(strInput, charInput, strInput.Length);

}



public static bool isContainSameChar(string strInput, string charInput, int lenInput)

{

if (string.IsNullOrEmpty(charInput))

{

return false;

}

else

{

Regex RegNumber = new Regex(string.Format("^([{0}])+$", charInput));

//Regex RegNumber = new Regex(string.Format("^([{0}]{{1}})+$", charInput,lenInput));

Match m = RegNumber.Match(strInput);

return m.Success;

}

}

#endregion



//檢查輸入的參數是不是某些定義好的特殊字符:這個方法目前用於密碼輸入的安全檢查#region 檢查輸入的參數是不是某些定義好的特殊字符:這個方法目前用於密碼輸入的安全檢查

/**//// <summary>

/// 檢查輸入的參數是不是某些定義好的特殊字符:這個方法目前用於密碼輸入的安全檢查

/// </summary>

public static bool isContainSpecChar(string strInput)

{

string[] list = new string[] { "123456", "654321" };

bool result = new bool();

for (int i = 0; i < list.Length; i++)

{

if (strInput == list[i])

{

result = true;

break;

}

}

return result;

}

#endregion

}



失效的訪問控制


Broken Access Control

大部分企業都非常關注對已經建立的連接進行控制,但是,允許一個特定的字符串輸入可以讓攻擊行為繞過企業的控制。

解決方案:

采用Atho2的方式對用戶身份進行驗證;將AccessToken  保存到Cookie里面;設置Cookie失效策略;

當然在分布架構下面;需要用戶集中式Redis集群管理用戶Session,而在應用級是無狀態的。

失效的賬戶和線程管理


Broken Authentication and Session Management

有良好的訪問控制並不意味着萬事大吉,企業還應該保護用戶的密碼、會話令牌、賬戶列表及其它任何可為攻擊者提供有利信息、能幫助他們攻擊企業網絡的內容。

跨站點腳本攻擊


Cross Site Scripting Flaws

這是一種常見的攻擊,當攻擊腳本被嵌入企業的Web頁面或其它可以訪問的Web資源中,沒有保護能力的台式機訪問這個頁面或資源時,腳本就會被啟動,這種攻擊可以影響企業內成百上千員工的終端電腦。
解決方案:要在可能的輸入項中過濾所有

緩存溢出問題


Buffer Overflows

這個問題一般出現在用較早的編程語言、如C語言編寫的程序中,這種編程錯誤其實也是由於沒有很好地確定輸入內容在內存中的位置所致。

注入式攻擊


Injection Flaws

如果沒有成功地阻止帶有語法含義的輸入內容,有可能導致對數據庫信息的非法訪問,在Web表單中輸入的內容應該保持簡單,並且不應包含可被執行的代碼。
解決方案:

1、要使用服務端的可能帶來的服務SQL注入的地方進行驗證;

2、涉及SQL語句查詢是使用SQL變量(強烈推薦)

3、用通用的方法檢驗是否存在特殊字符

namespace YQSH.EIMS
{
using System;
public class SqlPourInto
{
private System.Collections.Specialized.NameValueCollection Param;
public SqlPourInto(System.Collections.Specialized.NameValueCollection param)
{
this.Param = param;
}

public bool HandleParam()
{
if (Param.Count == 0)
return true;
for (int i = 0; i < Param.Count; i++)
if (!IsSafeString(Param[i].ToString()))
return false;
return true ;
}
public bool IsSafeString(string strText)
{
bool bResult = true;
strText = System.Text.RegularExpressions.Regex.Replace(strText, "(<[b|B][r|R]/*>)+|(<[p|P](.|\\n)*?>)", "\n"); //<br>
string[] UnSafeArray = new string[23];
UnSafeArray[0] = "'";
UnSafeArray[1] = "xp_cmdshell ";
UnSafeArray[2] = "declare ";
UnSafeArray[3] = "netlocalgroupadministrators ";
UnSafeArray[4] = "delete ";
UnSafeArray[5] = "truncate ";
UnSafeArray[6] = "netuser ";
UnSafeArray[7] = "add ";
UnSafeArray[8] = "drop ";
UnSafeArray[9] = "update ";
UnSafeArray[10] = "select ";
UnSafeArray[11] = "union ";
UnSafeArray[12] = "exec ";
UnSafeArray[13] = "create ";
UnSafeArray[14] = "insertinto ";
UnSafeArray[15] = "sp_ ";
UnSafeArray[16] = "exec ";
UnSafeArray[17] = "create ";
UnSafeArray[18] = "insert ";
UnSafeArray[19] = "masterdbo ";
UnSafeArray[20] = "sp_ ";
UnSafeArray[21] = ";-- ";
UnSafeArray[22] = "1= ";
foreach (string strValue in UnSafeArray)
{
if (strText.ToLower().IndexOf(strValue) > -1)
{
bResult = false;
break;
}
}
return bResult;
}
}
}


異常錯誤處理


Improper Error Handling

當錯誤發生時,向用戶提交錯誤提示是很正常的事情,但是如果提交的錯誤提示中包含了太多的內容,就有可能會被攻擊者分析出網絡環境的結構或配置。
解決方案:Web.config,中將錯誤配置:

<customErrors mode="RemoteOnly">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>


不安全的存儲


Insecure Storage

對於Web應用程序來說,妥善保存密碼、用戶名及其他與身份驗證有關的信息是非常重要的工作,對這些信息進行加密則是非常有效的方式,但是一些企業會采用那些未經實踐驗證的加密解決方案,其中就可能存在安全漏洞。
解決方案:對於密碼可以采用2次的MD5加密,並驗證密碼得復雜程度。

程序拒絕服務攻擊


Application Denial of Service

與拒絕服務攻擊 (DoS)類似,應用程序的DoS攻擊會利用大量非法用戶搶占應用程序資源,導致合法用戶無法使用該Web應用程序。

解決方案

Ddos攻擊解決方案

代碼解決方案:

解決方案:
1、避免XSS的方法之一主要是將用戶所提供的內容輸入輸出進行過濾。ASP.NET的Server.HtmlEncode()或功能更強的Microsoft Anti-Cross Site Scripting Library。
2、整體網站的過濾處理,下面是通用處理方法。

public class safe_process
{
private const string StrRegex = @"<[^>]+?style=[\w]+?:expression\(|\b(alert|confirm|prompt)\b|^\+/v(8|9)|<[^>]*?=[^>]*?&#[^>]*?>|\b(and|or)\b.{1,6}?(=|>|<|\bin\b|\blike\b)|/\*.+?\*/|<\s*script\b|<\s*img\b|\bEXEC\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\s+(TABLE|DATABASE)";
public static bool PostData()
{
bool result = false;
for (int i = 0; i < HttpContext.Current.Request.Form.Count; i++)
{
result = CheckData(HttpContext.Current.Request.Form[i].ToString());
if (result)
{
break;
}
}
return result;
}

public static bool GetData()
{
bool result = false;
for (int i = 0; i < HttpContext.Current.Request.QueryString.Count; i++)
{
result = CheckData(HttpContext.Current.Request.QueryString[i].ToString());
if (result)
{
break;
}
}
return result;
}

public static bool CookieData()
{
bool result = false;
for (int i = 0; i < HttpContext.Current.Request.Cookies.Count; i++)
{
result = CheckData(HttpContext.Current.Request.Cookies[i].Value.ToLower());
if (result)
{
break;
}
}
return result;
}
public static bool referer()
{
bool result = false;
return result = CheckData(HttpContext.Current.Request.UrlReferrer.ToString());
}
public static bool CheckData(string inputData)
{

if (Regex.IsMatch(inputData, StrRegex))
{
return true;
}
else
{
return false;
}
}
}
在Global.asax中的Application_BeginRequest中調用上面的方法進行處理,代碼如下:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string q = "<div style='position:fixed;top:0px;width:100%;height:100%;background-color:white;color:green;font-weight:bold;border-bottom:5px solid #999;'><br>您的提交帶有不合法參數!</div>";
if (Request.Cookies != null)
{
if (SteelMachining.Common.safe_360.CookieData())
{
Response.Write(q);
Response.End();
}
}

if (Request.UrlReferrer != null)
{
if (SteelMachining.Common.safe_360.referer())
{
Response.Write(q);
Response.End();
}
}

if (Request.RequestType.ToUpper() == "POST")
{
if (SteelMachining.Common.safe_360.PostData())
{

Response.Write(q);
Response.End();
}
}
if (Request.RequestType.ToUpper() == "GET")
{
if (SteelMachining.Common.safe_360.GetData())
{
Response.Write(q);
Response.End();
}
}
}


不安全的配置管理


Insecure Configuration Management

有效的配置管理過程可以為Web應用程序和企業的網絡架構提供良好的保護。

不安全的網絡傳輸

解決方案:對敏感數據進行加密

                  采用安全的傳輸通道(專網,或者VPN)

                   采取加密協議如Https

網絡數據偽造

                 采取數據加密認證

網絡篡改

                 采取數據認證


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com