【原創】C#通用許可權管理-程式安全檢查,這些你一定要考慮到位

來源:互聯網
上載者:User

標籤:

       接觸通用許可權已經一年,現在使用已經很熟練,分享通用許可權管理下面的一些好的開發思想。

       安全性漏洞對於一個小項目來說,可能不是特別的重視,對於一個大項目來說,這是特別重要需要注意的,特別是在項目開發中的就要警惕,下面我列舉一些項目開發中需要注意的安全

  1. 頁面文字框的檢查,每個文字框填寫的內容是什麼類型就是必須用Regex進行強制限制,不能隨便輸入無用的資訊,這是第一步
  2. 對於C/S的程式,我們可以直接用Regex來限制,對於B/S的頁面程式,我們也是需要js驗證和後台代碼的驗證,因為瀏覽器可以禁止js,讓js不起作用,所以我們採取的方式就是兩步走,js驗證後,需要後台對資料還要嚴格的校正,防止惡意資料進入資料庫,守好大門很重要。
  3. 介面調用安全,通過Post和Get調用介面,知道了伺服器的外網IP可以直接調用,所以盡量使用內網,這個就是很大的安全隱患。
  4. 防止Sql注入,特別非數位文字框,使用者直接可以填寫update語句,必須要檢查,也可以通過限制文字框的字元長度來控制,有很多程式員總是忘記這一點,字串長度要和資料庫表中的欄位通過計算的出來,不能太長也不能太短。

     軟體開發中,用到最多的兩個HTML元素就是input文字框和button標籤,當使用者通過鍵盤,滑鼠操作文字框將文字內容輸入,點擊提交我們需要第一步就進行資料校正。

  • B/S文字框

    需要的Regex用到每個文字框中,這裡共用一個收集的比較好的Regex連結常用Regex

    通過一些頁面安全檢查工具進行檢測,這裡先列舉我們開發中用到的安全檢查工具AppScan Source,它的一些提示,這裡也給出一個連結,AppScan使用分享    

  • C/S文字框

    開發DevExpress Winform程式的Dev提供了很好的正則限制,1

  • 介面安全

  當我們的介面通過外網調用的時候是很不安全的,別人知道了URL後可以很輕鬆的進行調用,由於公司簡訊介面現在是我負責,每天都在不停的調用傳送簡訊的介面,很多用戶端進行調動,產生的簡訊都有上萬條,如果被駭客知道了,那這個就是簡訊的轟炸機了,所以為了安全起見在介面中做了一下處理,通過內網IP調用介面,外網IP停止使用,看下代碼

1             //擷取請求的Url地址2             var ipAddress = DotNet.Business.Utilities.GetIPAddress(true);3             //必須是內網Ip請求才可以調用介面,做安全檢查,不符合要求,直接返回4             if (!IpHelper.IsLocalIp(ipAddress))5             {6                 result = (int)MessageStatus.IpError;7                 return result;    8             }

     代碼其實沒有特別多,就幾行代碼,這樣就可以達到安全的要求了,用戶端調用必須填寫內網的網域名稱或者IP請求地址,這樣程式才能通過檢查,我們來看下擷取IP地址的這個方法,參數true就是代表了你的伺服器是否啟用了代理方式,一般伺服器如果沒有通過nginx代理的話就可以不填寫了,如果伺服器是被代理過的一定要填寫true,這樣才可以擷取到請求用戶端的真是IP地址。

 1         /// <summary> 2         /// 擷取用戶端ip地址 3         /// </summary> 4         /// <param name="transparent">是否使用了代理</param> 5         /// <returns>ip地址</returns> 6         public static string GetIPAddress(bool transparent = false) 7         { 8             string ip = string.Empty; 9             if (System.Web.HttpContext.Current != null)10             {11                 if (transparent)12                 {13                     if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)14                     {15                         ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();16                     }17                 }18                 if (string.IsNullOrWhiteSpace(ip))19                 {20                     if (HttpContext.Current.Request.ServerVariables["HTTP_VIA"] != null)21                     {22                         ip = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();23                     }24                     else25                     {26                         ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString();27                     }28                 }29             }30             return ip;31         }

     接下來我們看下檢查是否是本地IP地址的方法,內網地址一般都是192.168等等開頭的IP是伺服器的內網地址,所以我們判斷一下開頭就可以得到是否是內網IP的結果。

 1         /// <summary> 2         /// 檢查是否是內網IP 3         /// </summary> 4         /// <param name="ipAddress"></param> 5         /// <returns></returns> 6         public static bool IsLocalIp(string ipAddress) 7         { 8             bool result = false; 9             if (!string.IsNullOrEmpty(ipAddress))10             {11                 if (ipAddress.StartsWith("192.168.") 12                     || ipAddress.StartsWith("172.")13                     || ipAddress.StartsWith("10."))14                 {15                     result = true;16                 }17             }18             return result;19         }    
  • Sql安全

對於前台請求的普通文字框,入庫之前一定要做防止Sql語句檢查,在通用許可權管理的代碼中,我們一般使用強型別的實體進行資料庫的增刪改查,不適用拼接Sql語句的方式進行資料庫操作, 本人一直很反感拼接Sql然後提交資料庫執行,雖然這個在調試的時候很好很快的找到Sql語句的錯誤在哪裡,但是從程式嚴謹的角度思考這是不正確的,物件導向告訴我們多使用實體,多使用強型別。還在拼接Sql語句一般都是剛進入工作的菜鳥喜歡乾的事情,所以開發中一定要多使用ORM快速開發架構(我個人推薦通用許可權管理ORM開發架構),相容多個資料庫,可以靈活切換,執行速度快,UI層不拼接Sql語句,參數化查詢,多表查詢,分頁。

對於Sql注入漏洞,可以參考一下 Sql注入漏洞,對於我們提交到背景參數值我們一定要做安全性檢查。

 1         #region public static string SqlSafe(string value) 檢查參數的安全性 2         /// <summary> 3         /// 檢查參數的安全性 4         /// </summary> 5         /// <param name="value">參數</param> 6         /// <returns>安全的參數</returns> 7         public static string SqlSafe(string value) 8         { 9             value = value.Replace("‘", "‘‘");10             // value = value.Replace("%", "‘%");11             return value;12         }13         #endregion

看下完整的分頁請求案例代碼,這就是通用許可權管理的一些安全小總結

 

        #region public ActionResult List(Pager pager, string beginDate, string endDate, string oldRecordKey, string newValue) 擷取修改記錄        /// <summary>        /// 擷取修改記錄        /// </summary>        /// <param name="pager">分頁實體</param>        /// <param name="beginDate">開始日期</param>        /// <param name="endDate">結束日期</param>        /// <param name="oldRecordKey">原主索引值,一般是單號</param>        /// <param name="newValue">修改後新的值</param>        /// <returns></returns>        public ActionResult List(Pager pager, string beginDate, string endDate, string oldRecordKey, string newValue)        {            var dt1 = DateTime.Now;            var dbHelper = DbHelperFactory.GetHelper(BaseSystemInfo.BusinessDbType, BaseSystemInfo.BusinessDbConnectionString);            var paramaterList = new List<KeyValuePair<string, object>>();            var listWhere = new List<string>();//查詢條件            string conditions = null;            //變更日期範圍            if (!string.IsNullOrEmpty(beginDate) && !string.IsNullOrEmpty(endDate))            {                listWhere.Add(string.Format("{0} BETWEEN TO_DATE({1}, ‘yyyy-mm-dd hh24:mi:ss‘) AND TO_DATE({2}, ‘yyyy-mm-dd hh24:mi:ss‘)", ZTO_MODIFYEntity.FieldCREATE_DATE, dbHelper.GetParameter("beginTime"), dbHelper.GetParameter("endTime")));                paramaterList.Add(new KeyValuePair<string, object>("beginTime", DbLogic.SqlSafe(Convert.ToDateTime(beginDate + " 00:00:00").ToString(BaseSystemInfo.DateTimeFormat))));                paramaterList.Add(new KeyValuePair<string, object>("endTime", DbLogic.SqlSafe(Convert.ToDateTime(endDate + " 23:59:59").ToString(BaseSystemInfo.DateTimeFormat))));            }            //原主索引值            if (!string.IsNullOrEmpty(oldRecordKey))            {                listWhere.Add(string.Format(" {0}  =  {1}", ZTO_MODIFYEntity.FieldRECORED_KEY_OLD, dbHelper.GetParameter(ZTO_MODIFYEntity.FieldRECORED_KEY_OLD)));                paramaterList.Add(new KeyValuePair<string, object>(dbHelper.GetParameter(ZTO_MODIFYEntity.FieldRECORED_KEY_OLD), DbLogic.SqlSafe(oldRecordKey)));            }            //修改後新值            if (!string.IsNullOrEmpty(newValue))            {                listWhere.Add(string.Format(" {0}  =  {1}", ZTO_MODIFYEntity.FieldVALUE_NEW, dbHelper.GetParameter(ZTO_MODIFYEntity.FieldVALUE_NEW)));                paramaterList.Add(new KeyValuePair<string, object>(dbHelper.GetParameter(ZTO_MODIFYEntity.FieldVALUE_NEW), DbLogic.SqlSafe(newValue)));            }            //不是超級管理員或者高許可權使用者只能看自己的            if (!HasRole())            {                listWhere.Add(string.Format(" {0}  =  {1}", ZTO_MODIFYEntity.FieldCREATE_MAN_ID, dbHelper.GetParameter(ZTO_MODIFYEntity.FieldCREATE_MAN_ID)));                paramaterList.Add(new KeyValuePair<string, object>(dbHelper.GetParameter(ZTO_MODIFYEntity.FieldCREATE_MAN_ID), UserInfo.Id));            }            //擷取排序欄位            var sortField = Request["sort"];            if (string.IsNullOrEmpty(sortField))            {                sortField = ZTO_MODIFYEntity.FieldCREATE_DATE;            }            sortField += (" " + Request["direction"]);            int totalRows;            if (listWhere.Count > 0)            {                conditions += string.Join(" AND ", listWhere);//構建查詢條件            }            //返回列名稱            var backFieldList = new[]            {                string.Format("({0}||‘-‘||{1}){0}",ZTO_MODIFYEntity.FieldTABLE_CODE,ZTO_MODIFYEntity.FieldTABLE_NAME),                ZTO_MODIFYEntity.FieldCREATE_DATE,                ZTO_MODIFYEntity.FieldRECORED_KEY_OLD,                ZTO_MODIFYEntity.FieldCOLOUM_CODE,                ZTO_MODIFYEntity.FieldCOLOUM_NAME,                ZTO_MODIFYEntity.FieldVALUE_OLD,                ZTO_MODIFYEntity.FieldVALUE_NEW,                ZTO_MODIFYEntity.FieldCREATE_MAN            };            var dt = DbLogic.GetDataTableByPage(dbHelper, out totalRows, ZTO_MODIFYEntity.TableName, string.Join(",", backFieldList), pager.pageNo, pager.pageSize, conditions, paramaterList, sortField);            Hashtable ht = BuildHt(dt, totalRows, dt1);            return Json(ht, JsonRequestBehavior.AllowGet);        }        #endregion

 

好的ORM架構可以協助我們在工作中應對一些簡單的介面,節約時間,就是節約生命。

正在看本人部落格的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,日後必有一番作為!旁邊有“推薦”二字,你就順手把它點了吧,相得准,我分文不收;相不準,你也好回來找我!

 

【原創】C#通用許可權管理-程式安全檢查,這些你一定要考慮到位

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.