解决 GAppProxy Set-Cookie 和 HTTPS Cert Bugs

目录 安全, 开源

我自己写了一个类似 GAppProxy 的工具,支持 Python 和 PHP,有兴趣可以看这里

研究 GAppProxy 有两个原因:一、最近 Twitter 不能用,而我常用的 GAppProxy 却不支持我登录 Twitter;二、我最近在琢磨 SSL 证书的问题,正好用 GAppProxy 登录 Twitter 也有证书错误。

第一个 BUG:Set-Cookie Bug

GAPPProxy 目前对 Cookie 的处理有一些问题,主要出在对 header 中的多个 Set-Cookie 域处理错误,就会导致用户登录一些网站错误,无法获得正确的会话 Cookie。

举例,当服务器返回的 header 中有多个 Set-Cookie 域时,比如一般的 wordpress 返回的 header 中,Set-Cookie 域至少有三个:

Set-Cookie:
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-content/plugins; httponly
Set-Cookie:
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-admin; httponly
Set-Cookie:
wordpress_logged_in_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C545dcea44d5e69aec5c1203c64bee061;
path=/; httponly

GAPPProxy 会把它作为一个串传给本地浏览器:

Set-Cookie:
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-content/plugins; httponly,
wordpress_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C8b89cfc80161853957182ddfc481cd72;
path=/wp-admin; httponly,
wordpress_logged_in_776c41a2fee8d137928f3750eb1f0736=admin%7C1247298611%7C545dcea44d5e69aec5c1203c64bee061;
path=/; httponly

这样本地浏览器对 Cookie 的设置就会错误。解决办法很简单,将这个长串用split(', ')切开,同样设置三个 Set-Cookie 域即可。

Update 20090710/Solrex:
有人评论说 ', ' 也是可能在 Cookie 中出现的合法字符串;那么我就另外想了一个办法,先用正则表达式替换将 ', ***=' 替换成 'n***=',再用 'n' 对字符串进行切割。由于在 Cookie 中正常出现的 ', ' 后面会首先跟着 ';' 或 ',',然后才可能出现 =,因此用 ‘, ([^,;]+=)’ 匹配就可以了。而且这次把修改放到服务器端了,原来的客户端就不需要修改了

Patch:

Index: fetchserver/fetch.py
===================================================================
--- fetchserver/fetch.py    (revision 92)
+++ fetchserver/fetch.py    (working copy)
@@ -29,6 +29,7 @@
from google.appengine.ext import webapp
from google.appengine.api import urlfetch
from google.appengine.api import urlfetch_errors
+import re
# from accesslog import logAccess

@@ -153,14 +154,12 @@
             if header.strip().lower() in self.HtohHdrs:
                 # don't forward
                 continue
-            ## there may have some problems on multi-cookie process in urlfetch.
-            #if header.lower() == 'set-cookie':
-            #    logging.info('O %s: %s' % (header, resp.headers[header]))
-            #    scs = resp.headers[header].split(',')
-            #    for sc in scs:
-            #        logging.info('N %s: %s' % (header, sc.strip()))
-            #        self.response.out.write('%s: %srn' % (header, sc.strip()))
-            #    continue
+            # NOTE 20090710/Solrex: Fix multi-cookie process problem
+            if header.lower() == 'set-cookie':
+                scs = re.sub(r', ([^,;]+=)', r'n1', resp.headers[header]).split('n')
+                for sc in scs:
+                    self.response.out.write('%s: %srn' % (header, sc.strip()))
+                continue
             # other
             self.response.out.write('%s: %srn' % (header, resp.headers[header]))
             # check Content-Type

第二个 BUG:HTTPS Cert Bug

简单地来说,GAppProxy HTTPS 连接的实现是一个欺骗本地浏览器的过程,类似于中间人攻击。它首先用 GAE 获得页面的明文,抓到本地,然后假冒 HTTPS 站点与本地浏览器通信。因此它就需要提供一个 SSL 证书,来完成 HTTPS 连接的建立。

但这就有一个问题,SSL 证书哪儿来的?目前 GAppProxy 对所有的站点都使用一个证书,而且这个证书是未经任何授权 CA 认证的证书,因此就会产生很多错误。首先,该证书中的授权机构不是可信 CA,Firefox 和 IE 中捆绑的证书中没有该 CA 的证书;其次,该证书的 CN (Common Name)与站点域名不同,不可用于站点的通信。因此可能每次都需要用户自己点击添加证书例外。

为了避免这种缺陷,我想出来的做法是——自己做 CA,正所谓做事情要专业,要骗就骗彻底点,骗得浏览器神不知鬼不觉。首先,建立 CA 的密钥,自己给自己签发一个证书作为 CA 的根证书,将该 CA 的证书安装到 Firefox 浏览器中,在运行时使用该 CA 为每个 HTTPS 连接的站点签发对应于该站点的证书。由于 Firefox 中已经安装了该 CA 的证书,那么所有该 CA 签发的证书都能够通过 Firefox 的检测了。

这个方法比较麻烦,而且需要电脑上有 openssl,对于 Linux 完全没有问题,对于 Windows 可能就有点儿困难了。所以我这里就给出个思路,具体实现就不谈了。
您可以在 http://share.solrex.org/ibuild/ 找到我修改后的代码,感兴趣的话可以下载下来看看。

长按识别二维码关注《边际效应》
长按识别二维码关注《边际效应》

21 条评论

  • Iron_Feet
    2009-07-09

    自从你上次告诉我这个东东后,我一直都没时间弄上了用一下>_<

  • zz
    2009-07-09

    第一个bug不错

    cert添加到信任列表一次就行

  • lala
    2009-07-09

    有点复杂啊

  • YYUU
    2009-07-10

    的确很好用,最大BUG没有了

  • gengmao
    2009-07-13

    firefox里好像不能添加cert到信任列表?

  • gengmao
    2009-07-13

    在add exception -> get certificate 时总是time out

  • 园子
    2009-07-13

    非常专业的文章

    可以做个链接吗?

  • Solrex
    2009-07-13

    @园子
    做链接完全没有问题,关键是我希望我的链接列表里都是真实姓名,恐怕您不一定乐意提供 :)
    如果您愿意提供的话,请发 Email 给我,我会将您添加入链接列表。

  • angeloudy
    2009-07-20

    还是谈谈linux下怎么实现吧

  • Solrex
    2009-07-22

    @angeloudy
    我已经放了一个我修改过的包在 http://share.solrex.cn/ibuild/,感兴趣的话,自己下载下来琢磨琢磨吧 :)

  • iceout
    2009-08-04

    奇怪了,在我电脑上,1.0.1不能用,1.0.0 cookies和https都没解决

    1.0.1
    Exception happened during processing of request from ('127.0.0.1', 36718)
    Traceback (most recent call last):
    File "/usr/lib/python2.6/SocketServer.py", line 558, in process_request_thread
    ......
    File "/home/iceout/download/gappproxy-solrex/client/proxy.py", line 256, in do_METHOD
    self.wfile.write(zlib.decompress(dat))
    error: Error -3 while decompressing data: incorrect header check
    =========================================================================
    1.0.0访问https时出现
    Error opening CA private key ./ca/ca.key
    14264:error:02001002:system library:fopen:No such file or directory:bss_file.c:352:fopen('./ca/ca.key','r')
    14264:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:354:
    unable to load CA private key

  • Solrex Yang
    2009-08-04

    @iceout
    这都是 bug,我已经解决了,不过还没有更新,抱歉 :)
    我明天会发布一个新包

  • 我的浏览器地址栏中有哪些网站? | Coolxll's Secret Garden
    2009-08-08

    [...] Firefox:http://opac.lib.sjtu.edu.cn/ Chrome:http://blog.solrex.cn/articles/fix-gappproxy-set-cookie-and-https-cert-bugs.html [...]

  • 7lemon
    2009-08-14

    有没有做成exe的包?在windows下搞不定了。。。

  • xdata
    2010-03-26

    这个是不是把 https降为http的那个解决方案啊. 看着有点像,
    不能下载东西哦.

    有时候需要下载一些文件都不能下载的,

    还是有很多的缺点啊....

  • 自制根证书,解决 GApp Proxy 的 HTTPS Cert Bug - Joyful Thinking
    2010-05-17

    [...] Yang 学长的 Blog 上有一个方法(《解决 GAppProxy Set-Cookie 和 HTTPS Cert Bugs》): 简单地来说,GAppProxy HTTPS [...]

  • thinkinight
    2010-08-15

    这个要记下来,我用gapproxy登录不了google的服务应该也是第一个原因,要解决一下

  • icyomik
    2010-10-09

    有兴趣,不过不一定能看懂,看看先,现在用的是WallProxy。

  • 熊猫慢慢
    2010-12-14

    @Solrex Yang google app engine Error -3 while decompressing data: incorrect header check请问这个怎么解决

  • SecretaryPolitics
    2011-01-14

    您好,请问下.在哪里可以下载到解决Gapproxy的SSL加密错误的证书呢?请您看到后联系下.谢谢.

  • simonchen
    2011-02-26

    SSLError: [Errno 1] _ssl.c:480: error:14094418:SSL
    routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

    我已导入了ssl/root.p12根证书在browser, 为什么还是出现上面错误?thank you! Simon

发表评论

电子邮件地址不会被公开。 必填项已用*标注