none
請問如何防範CSRF攻擊? RRS feed

  • 問題

  • 請問各位大大,本網站為webservice,輸入json字串後會回傳json字串,因為資安的關係,需要防範CSRF攻擊,請問如何防範?有無參考範例?

    Webservice.cs檔案如下:

    using D243.APP_Code;
    using System;
    using System.Web.Services;
    
    //[WebService(Namespace = "http://tempuri.org/")]
    //[WebServiceBinding(ConformsTo = WSRTiProfiles.BasicProfile1_1)]
    
    public class WebService : System.Web.Services.WebService
    {
        public WebService()
        {
            //如果使用設計的元件,請取消註解下列一行
            //InitializeComponent(); 
        }
    
        [WebMethod(Description = "統計規劃資料傳輸")]
        public string AddDIVIDEPAGESTAR(string data)
        {
            try
            {
    
                return new AnsService().addInsList(data);
            }
            catch(Exception ex){
                return "";
            }
            
        }
    }
    

    AnsService.cs檔案如下:

    using Newtonsoft.Json;
    using Services.Interface;
    using System;
    using System.Net;
    using System.Web;
    
    namespace D243.APP_Code
    {
        public class AnsService : BaseService
        {
            public string addInsList(string data)
            {
                var response = new ResponseData();
                GetJson list = new GetJson();
                var result=JsonConvert.DeserializeObject<GetJson>(data);
                //呼叫WSRT_統計規劃資料傳輸_歷程記錄
                BackupLog(result);
                // 檢查帳號是否存在
                if (_COMPANY.DoUserIdExist(result.USERID))
                {
                    var com = _COMPANY.GetByID(result.USERID);
                    //    檢查密碼是否相合
                    if (com.WSRT_PASSWORD == result.PASSWORD)
                    {
                        //    檢查編輯設定是否存在
                        if (_PAGESTAR_MAIN.DoTKTNOExist(result.TKT_NO))
                        {
                            //    檢查統計規劃狀態
                            //    存在 是否為2
                            if (result.TYPE=="2")
                            {
                                //    存加圖表 
                                _PAGESTAR_DETAIL.TKT_NO = result.TKT_NO;
                                _PAGESTAR_DETAIL.USERID = result.USERID;
                                   ...
                                _PAGESTAR_DETAIL.MKDATE = DateTime.Now;
                                _PAGESTAR_DETAIL.MDDATE = DateTime.Now;
                                _PAGESTAR_DETAIL.add();
                                //累加
                                _PAGESTAR_MAIN.AMOUNT = int.Parse(result.S_AMOUNT);
                                _PAGESTAR_MAIN.MDDATE = DateTime.Now;
                                _PAGESTAR_MAIN.edit(result.TKT_NO);
                                response.STATCODE = "S";
                                response.STATDESC = "";
                            }
                            //    註銷 是否為3
                            else if (result.TYPE == "3")
                            {
                                //    主檔改註銷
                                      ...
    
                                _PAGESTAR_MAIN.DELETE_YN = 1;
                                _PAGESTAR_MAIN.MDDATE = DateTime.Now;
                                _PAGESTAR_MAIN.deledit(result.TKT_NO);
                                response.STATCODE = "S";
                                response.STATDESC = "";
                            }
                            else
                            {
                                response.STATCODE = "F";
                                response.STATDESC = "編輯設定已存在,統計規劃狀態錯誤!";
                            }
                        }
                        else
                        {
                            //    不存在 是否為1
                            if (result.TYPE == "1")
                            {
                                //    存資料主檔
                                _PAGESTAR_MAIN.CP_ID = com.CP_ID;
                                _PAGESTAR_MAIN.TKT_NO = result.TKT_NO;
                                _PAGESTAR_MAIN.KNOCKDATE = DateTime.Parse(result.KNOCKDATE.ToString().Substring(0,4)+"-"+ result.KNOCKDATE.ToString().Substring(4, 2) + "-" + result.KNOCKDATE.ToString().Substring(6, 2));
                                _PAGESTAR_MAIN.USERID = result.USERID;
                                _PAGESTAR_MAIN.KNOCKTIME = result.KNOCKTIME;
                                _PAGESTAR_MAIN.HOUR = int.Parse(result.HOUR);
                                  ...
                                _PAGESTAR_MAIN.DELETE_YN = 0;
                                _PAGESTAR_MAIN.MKDATE = DateTime.Now;
                                _PAGESTAR_MAIN.MDDATE = DateTime.Now;
                                _PAGESTAR_MAIN.Add();
                                response.STATCODE = "S";
                                response.STATDESC = "";
                            }
                            else
                            {
                                response.STATCODE = "F";
                                response.STATDESC = "編輯設定尚未建立,統計規劃狀態錯誤!";
                            }
                           
                        }
                    }
                    else
                    {
                        response.STATCODE = "F";
                        response.STATDESC = "密碼不符!";
                    }
                }
                else
                {
                    response.STATCODE = "F";
                    response.STATDESC = "該用戶帳號不存在!";
                }         
               
    
    
                return JsonConvert.SerializeObject(response);
            }
    
            private void BackupLog(GetJson result)
            {
                _WSRT_DIVIDE_TRADE_LOG.FROM = result.FROM;
                _WSRT_DIVIDE_TRADE_LOG.PASSWORD = result.PASSWORD;
                _WSRT_DIVIDE_TRADE_LOG.TKT_NO = result.TKT_NO;
                _WSRT_DIVIDE_TRADE_LOG.TYPE = result.TYPE;
                _WSRT_DIVIDE_TRADE_LOG.KNOCKDATE = result.KNOCKDATE;
                _WSRT_DIVIDE_TRADE_LOG.USERID = result.USERID;
                _WSRT_DIVIDE_TRADE_LOG.KNOCKTIME = result.KNOCKTIME;
                   ...
                _WSRT_DIVIDE_TRADE_LOG.SECOND = result.SECOND;
                _WSRT_DIVIDE_TRADE_LOG.S_AMOUNT = result.S_AMOUNT;
                _WSRT_DIVIDE_TRADE_LOG.PRE_KIND = result.PRE_KIND;
                _WSRT_DIVIDE_TRADE_LOG.MINUTE = result.MINUTE;
                IPHostEntry temp = Dns.GetHostByName(Dns.GetHostName());
                string LocalIp = temp.AddressList[0].ToString();
                _WSRT_DIVIDE_TRADE_LOG.IP = LocalIp;
                _WSRT_DIVIDE_TRADE_LOG.MKDATE = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                _WSRT_DIVIDE_TRADE_LOG.add();
            }
        }
    }
    

    謝謝各位大大!

    2018年10月24日 上午 06:01

解答

  • 您可以參考這篇討論的建議:

    How to prevent CSRF in a RESTful application?

    • 已標示為解答 Eden Knight 2019年9月20日 上午 04:03
    2018年10月24日 上午 11:04
  • 其實不一定是不應出現,而是在 Web Service 擋 CSRF 沒什麼意義,Web Service 本來就是寫來給外來服務或網站叫用。
    當然有些 service 只給內部用,那一定要擋,但是你怎麼確認人家有沒有授權才是重點。例如設計一個 API 可以交換驗證訊息的,在叫用 service 時一定要帶那個驗證訊息 (類似 OAuth access token 的概念),其他叫用一概不予處理,回應 400 之類。

    如果有特別掌握住這個原則,那其實也不需要怕 CSRF (還搞不好是掃瞄軟體誤判)。


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    • 已標示為解答 Eden Knight 2019年9月20日 上午 04:03
    2018年10月30日 下午 01:48
    版主
  • 可以參考看看 之前有自己做的功課

    https://aspnetmars.blogspot.com/2017/04/aspnet-mvc-ajax-ajaxantiforgerytoken.html

    • 已標示為解答 Eden Knight 2019年9月20日 上午 04:03
    2018年11月1日 上午 07:05

所有回覆

  • 您可以參考這篇討論的建議:

    How to prevent CSRF in a RESTful application?

    • 已標示為解答 Eden Knight 2019年9月20日 上午 04:03
    2018年10月24日 上午 11:04
  • Are JSON web services vulnerable to CSRF attacks?

    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2018年10月24日 下午 02:24
    版主
  • 請問有更詳盡的方法或範例嗎? 理論上webservice不應出現CSRF錯誤,目前調查結果,該專案是單純的sebservice專案,該專案也沒有使用cookie,是否有其他可能性,是介面、介面實作、viewmodel的問題,還是遇到bug不能導入很單純的html,謝謝各位大大。
    2018年10月30日 上午 03:45
  • 其實不一定是不應出現,而是在 Web Service 擋 CSRF 沒什麼意義,Web Service 本來就是寫來給外來服務或網站叫用。
    當然有些 service 只給內部用,那一定要擋,但是你怎麼確認人家有沒有授權才是重點。例如設計一個 API 可以交換驗證訊息的,在叫用 service 時一定要帶那個驗證訊息 (類似 OAuth access token 的概念),其他叫用一概不予處理,回應 400 之類。

    如果有特別掌握住這個原則,那其實也不需要怕 CSRF (還搞不好是掃瞄軟體誤判)。


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    • 已標示為解答 Eden Knight 2019年9月20日 上午 04:03
    2018年10月30日 下午 01:48
    版主
  • 可以參考看看 之前有自己做的功課

    https://aspnetmars.blogspot.com/2017/04/aspnet-mvc-ajax-ajaxantiforgerytoken.html

    • 已標示為解答 Eden Knight 2019年9月20日 上午 04:03
    2018年11月1日 上午 07:05
  • 這個專案後來已轉手,目前手邊沒有解答,不過感謝各位大大的熱心答覆!
    2019年9月20日 上午 04:02