requests.Session()以意想不到的方式处理cookie(mangling json)

时间:2016-12-08 21:54:32

标签: python-requests aiohttp

我在对客户端请求的响应中填充会话cookie服务器端。通过电线,响应如下所示 - 你可以看到mycookie有一个带有转义引号的json格式:

21:13:54.006488 IP (tos 0x0, ttl 64, id 45515, offset 0, flags [DF], proto TCP (6), length 303, bad cksum 0 (->89fb)!)
    localhost.http-alt > localhost.57738: Flags [P.], cksum 0xff23 (incorrect -> 0x13f5), seq 1:252, ack 247, win 12751, options [nop,nop,TS val 1223327230 ecr 1223325750], length 251
    0x0000:  4500 012f b1cb 4000 4006 0000 7f00 0001  E../..@.@.......
    0x0010:  7f00 0001 1f90 e18a e6ce bb1d 282c d580  ............(,..
    0x0020:  8018 31cf ff23 0000 0101 080a 48ea 7dfe  ..1..#......H.}.
    0x0030:  48ea 7836 4854 5450 2f31 2e31 2032 3030  H.x6HTTP/1.1.200
    0x0040:  204f 4b0d 0a43 6f6e 7465 6e74 2d54 7970  .OK..Content-Typ
    0x0050:  653a 2061 7070 6c69 6361 7469 6f6e 2f6a  e:.application/j
    0x0060:  736f 6e0d 0a43 6f6e 7465 6e74 2d4c 656e  son..Content-Len
    0x0070:  6774 683a 2032 330d 0a53 6574 2d43 6f6f  gth:.23..Set-Coo
    0x0080:  6b69 653a 2070 6965 6b61 726d 613d 227b  kie:.mycookie="{
    0x0090:  5c22 6372 6561 7465 645c 223a 2031 3438  \"created\":.148
    0x00a0:  3132 3331 3633 325c 3035 3420 5c22 7365  1231632\054.\"se
    0x00b0:  7373 696f 6e5c 223a 207b 5c22 7573 6572  ssion\":.{\"user
    0x00c0:  5c22 3a20 5c22 686c 6565 6e65 795c 227d  \":.\"my_name\"}
    0x00d0:  7d22 3b20 4874 7470 4f6e 6c79 3b20 5061  }";.HttpOnly;.Pa
    0x00e0:  7468 3d2f 0d0a 4461 7465 3a20 5468 752c  th=/..Date:.Thu,
    0x00f0:  2030 3820 4465 6320 3230 3136 2032 313a  .08.Dec.2016.21:
    0x0100:  3133 3a35 3120 474d 540d 0a53 6572 7665  13:51.GMT..Serve
    0x0110:  723a 2050 7974 686f 6e2f 332e 3420 6169  r:.Python/3.4.ai
    0x0120:  6f68 7474 702f 312e 312e 360d 0a0d 0a    ohttp/1.1.6....

我使用以下请求代码来获取cookie:

with requests.Session() as s:
    r = s.post(domain+'login')
    c = s.cookies['mycookie']

而c看起来像     '" {created:1481233488 \ 054 session:{user:hleeney}}"'

c [0]是"

我在服务器端使用aiohttp ..

response = web.Response(...)
response.set_cookie(json.dumps({"session":{...}}))

我不确定应该责怪谁:D任何人都可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

我怀疑你可能会责怪Python http.cookies.SimpleCookie

当前aiohttp主人可能会帮助您,您的问题与solved issue类似。

作为一种选择,你可能会责怪自己 - 将未签名的json存储到cookie中非常糟糕不安全的想法无论如何。通常人们使用base64编码和加密签名的字符串。

<强> UPD 即可。 抱歉,aiohttp master对您没有帮助 - 我错过了requests而非aiohttp数据损坏的数据。

答案 1 :(得分:0)

回答“责怪谁”的问题。这很难。它可能是用户(我)有点无知,如果他更聪明,他将永远不会遇到这个问题。但是,根据您的观点,它也可以是以下任何一个。它是一个有趣的软件开发生命周期和标准案例研究。

1)请求的作者: 它确实是一个有趣的代码库,它正在破坏JSON。在撰写本文时,它会覆盖来自http / cookies.py的代码,以便在通过API返回之前修改cookie值。现在,请求的人真的很有帮助,非常酷。他们承认这个缺陷/次优实现虽然从一个角度来看它并没有真正违反RFC 6265(据说可以标准化cookie值)。现在,这个漏洞可能正在支持一个特色&#39;与某些服务器端cookie代码的兼容性(我对它的看法)。存在缺陷的模块被指定用于淘汰,因此在次要版本号上修复和潜在的临时向后兼容性问题被认为是不合需要的并且是浪费。

2)aiohtto_session的作者: 好吧天哪,这些是将JSON放入cookie值的人!他们有错......他们不是吗?好吧,它又复杂了。他们的目的是使用aiohttp作为服务器为安全会话提供简单的API。它们提供了一些实现。一个用于实时使用的加密cookie是将会话数据存储在加密的JSON字符串中。加密时,编码/解码cookie没有问题。当然,cookie不是用于在客户端读取,因此它永远不会存在,因为JSON和JSON永远不会被传输。他们提供的另一个实现是“简单”。会话存储。在这里,他们放弃加密并将会话作为原始JSON字符串传输。这是有问题的,因为JSON实际上不应该以cookie值传输(参见下面的3)。然而,简单的会话存储仅用于测试不是为了实时..仍然可能更好地提供一个简单的存储,不会有可能炸毁其他API,但实际上有这种实现(没有加密的JSON)可能提供一些有价值的测试覆盖场景

3)RFC 6265的作者: 这个RFC在指定cookie标准时应该是明确的。它肯定比先前存在的更好。但我并不相信它的确定性。 cookie值的规格只是有点奇怪和挑剔恕我直言。首先,下面的英语可能会有轻微的误解,因为两个似乎在遗漏逗号和三个错误中有一个错字......再次它的奇怪和挑剔的恕我直言(H在这里代表无知,因为我&#39;我更确定他们知道为什么有意义)

cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E ; US-ASCII characters excluding CTLs, ; whitespace DQUOTE, comma, semicolon, ; and backslash 通过这种方式,将json存储在cookie中的方式听起来并不疯狂,人们可能希望尽管存在潜在的安全漏洞。在我看来,python HTTP API对不兼容的cooke值视而不见 - 它们逃脱DQUOTE并用它们发送反斜杠。无论如何,不​​是我的肥皂盒。

4)用户: 我。从这个旅程开始,我对上述所有内容都一无所知。 cookie标准及其历史,python http实现,请求实现,aiohttp_session实现。我不必要地在客户端测试cookie的明文值。虽然有人可能有一个真正的理由在将来这样做。我有点随机选择了做客户端的请求,所以应该不得不深入研究源代码。

因此,在闭幕式和开玩笑中,我因为聪明到足以创造复杂性而不够聪明而不能避免像这样的SDLC问题而责怪这个人的微不足道的人性。