最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】又发现一个C#中解析Set-Cookie的一个bug:无故地添加cookie的path域

C# crifan 8140浏览 0评论

【问题】

模拟登陆:

http://new.guguyu.com/add/

(用户名:72qt

密码:hx123456)

对应的核心部分是:

add php nk 1 url

resp set-cookie uname no path value

然后用代码:

public void emualeLoginAndAdd()
{
    crifanLib crl = new crifanLib();
    Dictionary<string, string> headerDict;
    Dictionary<string, string> postDict;

    //step1: http://new.guguyu.com/add.php
    string addPhpUrl = "http://new.guguyu.com/add.php";
    headerDict = new Dictionary<string, string>();
    headerDict.Add("Referer", addPhpUrl);
    headerDict.Add("DNT", "1");
    headerDict.Add("Accept-Language", "zh-CN");
    string addRespHtml = crl.getUrlRespHtml(addPhpUrl, headerDict: headerDict, charset: "GBK");

    //step2: http://new.guguyu.com/add.php?nk=1
    headerDict = new Dictionary<string, string>();
    headerDict.Add("Referer", addPhpUrl);
    //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
    headerDict.Add("DNT", "1");
    headerDict.Add("Accept-Language", "zh-CN");

    postDict = new Dictionary<string, string>();
    //uname=72qt&pwd=hx123456&Submit.x=44&Submit.y=21
    postDict.Add("uname", txtUserName.Text);
    postDict.Add("pwd", txtPassword.Text);
    postDict.Add("Submit.x", "44");
    postDict.Add("Submit.y", "21");
    string addNk1Url = "http://new.guguyu.com/add.php?nk=1";
    string addNk1RespHtml = crl.getUrlRespHtml(addNk1Url, headerDict: headerDict, postDict: postDict, charset: "GBK");//<script>location.href='/add/'</script>

    //step3: http://new.guguyu.com/add/
    string addUrl = "http://new.guguyu.com/add/";
    headerDict = new Dictionary<string, string>();
    headerDict.Add("Referer", addNk1Url);
    //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
    headerDict.Add("DNT", "1");
    headerDict.Add("allowautoredirect", "false");
    headerDict.Add("Accept-Language", "zh-CN");
    string secondTimeAddRespHtml = crl.getUrlRespHtml(addUrl, headerDict: headerDict, charset: "GBK");// here can got real html

    //step4: http://new.guguyu.com/add/?nk=1
    string addSlashNk1Url = "http://new.guguyu.com/add/?nk=1";
    headerDict = new Dictionary<string, string>();
    headerDict.Add("Referer", addUrl);
    headerDict.Add("allowautoredirect", "false");
    //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
    headerDict.Add("DNT", "1");
    headerDict.Add("Accept-Language", "zh-CN");
    string secondTimeAddNk1RespHtml = crl.getUrlRespHtml(addSlashNk1Url, headerDict: headerDict, charset: "GBK");
}

去调试,结果始终后面的结果不对:

step3去访问:

http://new.guguyu.com/add/

但是得到的,不是正常的html,而是之前的那个:

<script>location.href='/add/'</script>

对应的,step4,获得也不是正常的html,也是上面的那个值。

【解决过程】

1.调试了N个小时,最终找到根本原因了:

 

C#代码:

    resp = (HttpWebResponse)req.GetResponse();
    updateLocalCookies(resp.Cookies, ref curCookies);

中的resp.Cookies,其实是

C#的http库,针对:

{Vary: Accept-Encoding

Content-Encoding:

Content-Length: 53

Content-Type: text/html

Date: Thu, 01 Aug 2013 16:05:12 GMT

Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT

Server: Apache/2.2.9 (APMServ) PHP/5.2.6

X-Powered-By: PHP/5.2.6

}

中的:

Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT

解析后的cookie,但是,由于C#的解析Set-Cookie有bug,导致解析出来的cookie,虽然其他值都对,包括name是UNAME,但是path的值却出错了:

path="add.php"

resp cookies path is add php

而实际上,应该是:

path=""

对应的,抓包出来的是正常的,path是空的:

capture path and domain all empty

2.知道原因后,结果就可以去修改代码了:

主要就是:

要么手动去把cookie的path值清空;

要么去删除错误的cookie,重新自己写代码解析Set-Cookie,以此获得正确的path为空的cookie;

此处用后者,代码为:

        public void emualeLoginAndAdd()
        {
            crifanLib crl = new crifanLib();
            Dictionary<string, string> headerDict;
            Dictionary<string, string> postDict;

            //step1: http://new.guguyu.com/add.php
            string addPhpUrl = "http://new.guguyu.com/add.php";
            headerDict = new Dictionary<string, string>();
            headerDict.Add("Referer", addPhpUrl);
            headerDict.Add("DNT", "1");
            headerDict.Add("Accept-Language", "zh-CN");
            string addRespHtml = crl.getUrlRespHtml(addPhpUrl, headerDict: headerDict, charset: "GBK");

            //step2: http://new.guguyu.com/add.php?nk=1
            headerDict = new Dictionary<string, string>();
            headerDict.Add("Referer", addPhpUrl);
            //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
            headerDict.Add("DNT", "1");
            headerDict.Add("Accept-Language", "zh-CN");

            postDict = new Dictionary<string, string>();
            //uname=72qt&pwd=hx123456&Submit.x=44&Submit.y=21
            postDict.Add("uname", txtUserName.Text);
            postDict.Add("pwd", txtPassword.Text);
            postDict.Add("Submit.x", "44");
            postDict.Add("Submit.y", "21");
            string addNk1Url = "http://new.guguyu.com/add.php?nk=1";
            
            //string addNk1RespHtml = crl.getUrlRespHtml(addNk1Url, headerDict: headerDict, postDict: postDict, charset: "GBK");//<script>location.href='/add/'</script>


            //!!! here, above step, will got a uncorrect cookie
            //which abnormally, pass:
            //Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT
            //into cookie name is "UNAME",but path="/add" -> correct one should be path=""
            //so following, use manually process cookie

            HttpWebResponse addNk1Response = crl.getUrlResponse(addNk1Url, headerDict: headerDict, postDict: postDict);//<script>location.href='/add/'</script>
            String curDomain = crl.extractHost(addPhpUrl);//new.guguyu.com
            CookieCollection parsedCookies = crl.parseSetCookie(addNk1Response.Headers["Set-Cookie"], curDomain);
            CookieCollection curCookies = crl.getCurCookies();
            crl.updateLocalCookies(parsedCookies, ref curCookies);
            crl.setCurCookies(curCookies);
            
            //step3: http://new.guguyu.com/add/
            string addUrl = "http://new.guguyu.com/add/";
            headerDict = new Dictionary<string, string>();
            headerDict.Add("Referer", addNk1Url);
            //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
            headerDict.Add("DNT", "1");
            headerDict.Add("allowautoredirect", "false");
            headerDict.Add("Accept-Language", "zh-CN");
            string secondTimeAddRespHtml = crl.getUrlRespHtml(addUrl, headerDict: headerDict, charset: "GBK");// here can got real html

            //step4: http://new.guguyu.com/add/?nk=1
            string addSlashNk1Url = "http://new.guguyu.com/add/?nk=1";
            headerDict = new Dictionary<string, string>();
            headerDict.Add("Referer", addUrl);
            headerDict.Add("allowautoredirect", "false");
            //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
            headerDict.Add("DNT", "1");
            headerDict.Add("Accept-Language", "zh-CN");
            string secondTimeAddNk1RespHtml = crl.getUrlRespHtml(addSlashNk1Url, headerDict: headerDict, charset: "GBK");
            // here can get real html, which conains
            /*
                         <td colspan='2' align='center'>
              <input style='height: 25px;' name='submit' type='submit' id='submit' value=' 提 交 ' onClick='return Ck();'/>

              <input name='check' type='hidden' value='6283' />
                 <a href='javascript:;' onClick="faka('kadd');"><font color='red' size='3'>【附加新手卡】</font></a>   <a href='?nk=5'><font size='3'>【批量发布新服】</font></a>   全部发完后请到<a href='?nk=10'>管理新服</a>检查一下,确保无误!</td>
             */
        }

 

解析后的cookie,path是空的:

after parse path is empty

3.经过继续的验证,发现很多参数,是可以去掉的:

        public void emualeLoginAndAdd()
        {
            crifanLib crl = new crifanLib();
            Dictionary<string, string> headerDict;
            Dictionary<string, string> postDict;

            //step1: http://new.guguyu.com/add.php
            string addPhpUrl = "http://new.guguyu.com/add.php";
            headerDict = new Dictionary<string, string>();
            //headerDict.Add("Referer", addPhpUrl);
            //headerDict.Add("DNT", "1");
            //headerDict.Add("Accept-Language", "zh-CN");
            string addRespHtml = crl.getUrlRespHtml(addPhpUrl, headerDict: headerDict, charset: "GBK");

            //step2: http://new.guguyu.com/add.php?nk=1
            headerDict = new Dictionary<string, string>();
            //headerDict.Add("Referer", addPhpUrl);
            //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
            //headerDict.Add("DNT", "1");
            //headerDict.Add("Accept-Language", "zh-CN");

            postDict = new Dictionary<string, string>();
            //uname=72qt&pwd=hx123456&Submit.x=44&Submit.y=21
            postDict.Add("uname", txtUserName.Text);
            postDict.Add("pwd", txtPassword.Text);
            //postDict.Add("Submit.x", "44");
            //postDict.Add("Submit.y", "21");
            string addNk1Url = "http://new.guguyu.com/add.php?nk=1";
            
            //string addNk1RespHtml = crl.getUrlRespHtml(addNk1Url, headerDict: headerDict, postDict: postDict, charset: "GBK");//<script>location.href='/add/'</script>


            //!!! here, above step, will got a uncorrect cookie
            //which abnormally, pass:
            //Set-Cookie: UNAME=72qt%7C61%7C1375373112%7C63101962%7C72qt%7C72qt.com; expires=Fri, 01-Aug-2014 16:05:12 GMT
            //into cookie name is "UNAME",but path="/add" -> correct one should be path=""
            //so following, use manually process cookie

            HttpWebResponse addNk1Response = crl.getUrlResponse(addNk1Url, headerDict: headerDict, postDict: postDict);//<script>location.href='/add/'</script>
            String curDomain = crl.extractHost(addPhpUrl);//new.guguyu.com
            CookieCollection parsedCookies = crl.parseSetCookie(addNk1Response.Headers["Set-Cookie"], curDomain);
            CookieCollection curCookies = crl.getCurCookies();
            crl.updateLocalCookies(parsedCookies, ref curCookies);
            crl.setCurCookies(curCookies);
            
            //step3: http://new.guguyu.com/add/
            string addUrl = "http://new.guguyu.com/add/";
            headerDict = new Dictionary<string, string>();
            //headerDict.Add("Referer", addNk1Url);
            //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
            //headerDict.Add("DNT", "1");
            //headerDict.Add("allowautoredirect", "false");
            //headerDict.Add("Accept-Language", "zh-CN");
            string secondTimeAddRespHtml = crl.getUrlRespHtml(addUrl, headerDict: headerDict, charset: "GBK");// here can got real html

            //step4: http://new.guguyu.com/add/?nk=1
            string addSlashNk1Url = "http://new.guguyu.com/add/?nk=1";
            headerDict = new Dictionary<string, string>();
            //headerDict.Add("Referer", addUrl);
            //headerDict.Add("allowautoredirect", "false");
            //headerDict.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko");
            //headerDict.Add("DNT", "1");
            //headerDict.Add("Accept-Language", "zh-CN");
            string secondTimeAddNk1RespHtml = crl.getUrlRespHtml(addSlashNk1Url, headerDict: headerDict, charset: "GBK");
            // here can get real html, which conains
            /*
                         <td colspan='2' align='center'>
              <input style='height: 25px;' name='submit' type='submit' id='submit' value=' 提 交 ' onClick='return Ck();'/>

              <input name='check' type='hidden' value='6283' />
                 <a href='javascript:;' onClick="faka('kadd');"><font color='red' size='3'>【附加新手卡】</font></a>   <a href='?nk=5'><font size='3'>【批量发布新服】</font></a>   全部发完后请到<a href='?nk=10'>管理新服</a>检查一下,确保无误!</td>
             */
        }

4.其中,用到的crifanLib.cs,详见:

http://code.google.com/p/crifanlib/source/browse/trunk/csharp/crifanLib.cs

 

【总结】

加上之前遇到的一个bug:

【已解决】C#中得到的Http的response中的Set-Cookie的内容的格式不对/错误/不正确 –> 已实现把Set-Cookie部分的字符串解析为CookieCollection

【经验记录】C#中,库函数有bug,会将http所返回的response响应中的headers头信息中的Set-Cookie值,解析错误,丢失部分cookie

算下来,C#的http的库,在解析cookie方面(解析返回的Set-Cookie)方面,真的是,bug奇多,害人不浅啊。

转载请注明:在路上 » 【已解决】又发现一个C#中解析Set-Cookie的一个bug:无故地添加cookie的path域

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (2)

  1. Set-Cookie:HttpOnly是xss跨站防护吧
    小樱10年前 (2015-03-02)回复
87 queries in 0.195 seconds, using 22.26MB memory