cookie加密到没有点前缀的域

时间:2018-03-09 02:14:47

标签: javascript cookies

我有这个奇怪的问题,我无法弄清楚,所以我希望比我聪明的人可以帮忙!

我有一个网站https://example.com(没有子域名)

我有一些设置Cookie的代码,例如

var value="some value";
document.cookie="myCookie="+escape(value)+"; path=/; domain=example.com";

此代码在某些脚本标记的页面加载期间运行。首次加载页面时,我会看到我的cookie集,并在(chrome)dev工具>申请>域列,我看到它在.example.com上设置了一个前导点,这很好。

然后我刷新页面,我的代码再次运行(并且有一个新值被推送到cookie; dunno,如果这很重要)。我查看了应用程序选项卡,现在我看到了一个"重复的" myCookie的条目 - .example.com上的一个和example.com上的另一个(无前导点)。值是相同的。 这对我来说很奇怪,我不知道为什么会这样。有没有人为什么会出现这种情况?

继续沿着这个兔子洞......我再次刷新页面,myCookie上的.example.com值更新,但example.com上的值不更新。更奇怪!

与此同时,我还有其他尝试读取cookie的代码,但显然myCookie上的example.com cookie优先,我得到的值不是最新值(反映在{{1} }} 曲奇饼)。

我已尝试在.example.com.example.com)上明确设置Cookie,但上述行为仍然会发生。另外,据我所知,javascript中没有办法明确引用domain=.example.com上的cookie - .example.com只显示document.cookie一个(但开发工具应用程序选项卡确实如此)显示它?所以这在javascript中公开了吗?)

我无法提供该网站的链接,但我可以尝试回答有人可能需要澄清的任何问题。

但我的主要问题是:任何人都可以解释这可能发生的原因,或者至少提供一些可能指向正确方向的东西吗?或者失败了,或者一些解决方法明确地从example.com读取?

修改

此时,我最好的猜测是网站上的其他,可能是服务器端脚本,正在将Cookie从.example.com复制到.example.com但仅限于价值观发生了变化但这是纯粹的猜测。我还没有能够找到任何客户端证明(但是......)而且我实际上无法访问服务器端的东西。而且无论如何这可能都在吸管。但它是我最好的工作理论ATM,回到网站开发人员询问他们......

更新 - 我找到的新内容/澄清

要明确/重申:我的网站位于example.com子域名。

这似乎只发生在我的cookie中,其中值会更改每个页面加载。值不变的Cookie似乎不会从https://example.com推送到.example.com

即使对于具有动态值的Cookie,它似乎也只是{em} {em>} example.com {em} 时间。.example.com之后,example.com Cookie值在后续页面加载时不会更改,即使example.com版本获得新的动态值。

我创建了一个测试脚本,与我目前观察到这种行为的cookie分开,以便分而治之。我想用尽可能多的设置/读取cookie和blackbox的代码来排除任何恶作剧。

但我看到了同样的行为。我仍然怀疑这是某种服务器wtfery正在进行,例如.example.com cookie将在下一个http请求中发送,然后服务器将它们写回.example.com ..仅在第一次?这是双重情节扭曲。我无法访问服务器端的东西,但我甚至不知道从哪里开始在网站开发人员看到什么。

另请注意,到目前为止,在我和我的同事之间,我们测试了设置问题Cookie的javascript lib /代码,以及其他6个网站上的blackbox脚本(甚至不属于/附属于此问题网站所有)并且能够重现这个问题,这进一步让我们怀疑它是某种服务器配置问题(但同样,我们真的不知道从哪里开始那个)。

无论如何,如果它以某种方式帮助任何人,下面是我写的脚本(进一步)测试这个问题。我正在测试总共8个cookie:

  1. test_no_dot_static - 我将example.com设置为静态值
  2. test_no_dot_dynamic - 我设置domain=example.com动态值
  3. test_dot_static - 我将domain=example.com设置为静态值
  4. test_dot_dynamic - 我设置domain=.example.com动态值
  5. test_implicit_no_domain_static - 我设置了一个带有静态值的Cookie,并指定了 domain=.example.com
  6. test_implicit_no_domain_dynamic - 我设置了一个动态值的Cookie,其中指定了 domain=
  7. test_explicit_no_domain_static - 我设置了一个带有静态值的Cookie,其中domain=指定为无值
  8. test_explicit_no_domain_dynamic - 我设置了一个动态值的Cookie,其中没有值指定了domain=
  9. domain= - 这些最初设置在#1, #3上,并且在页面刷新时不会被.example.com欺骗

    example.com - 这些最初设置在#2, #4上。在首页刷新时,原始值将被设置为.example.com cookie / domain。在第二次+页面刷新时,example.com cookie值不会更改(保留原始值),example.com版本会在每个页面加载时获得新值。

    .example.com - 这些最初设置在#5, #7(不是example.com)上,.example.com上永远不会有版本。

    .example.com - 这些最初设置在#6, #8(不是example.com)上,其值会更新每个页面加载,.example.com上永远不会有版本。

    测试代码

    .example.com

    基于提供的评论/答案的另一个更新

    要明确的是,在实践中,问题是我们在页面加载时使用值设置了一些cookie。然后,当页面刷新(或在网站上导航到另一个页面)时,我们读取值,对其执行某些操作,生成新值并再次设置cookie。每次重复加载洗涤漂洗重复。

    问题出在初始页面查看,这些Cookie是在var s_testCookies = { getCookieValue: function(a) { var b = document.cookie.match('(^|;)\\s*' + a + '\\s*=\\s*([^;]+)'); return b ? unescape(b.pop()) : ''; }, getRandomValue: function() { return '' + (new Date()).getTime() + '|' + Math.floor(Math.random() * 100000); }, run: function(data) { var data = data || {}; console.log('------------------------'); console.log('Arg: ', JSON.parse(JSON.stringify(data))); data.previousValue = s_testCookies.getCookieValue(data.name); console.log('Previous: ', JSON.parse(JSON.stringify(data))); data.cookie = data.name + "=" + escape(data.value) + "; path=/;"; data.cookie+= (typeof data.domain!='undefined') && (" domain="+data.domain+";") || ""; document.cookie = data.cookie; data.newValue = s_testCookies.getCookieValue(data.name); console.log('New: ', JSON.parse(JSON.stringify(data))); console.log('------------------------'); } } // end testCookies s_testCookies.run({ 'message': 'no dot static value', 'domain': 'example.com', 'name': 'test_no_dot_static', 'value': 'no dot static value' }); s_testCookies.run({ 'message': 'no dot dynamic value', 'domain': 'example.com', 'name': 'test_no_dot_dynamic', 'value': s_testCookies.getRandomValue() }); s_testCookies.run({ 'message': 'dot static value', 'domain': '.example.com', 'name': 'test_dot_static', 'value': 'dot static value' }); s_testCookies.run({ 'message': 'dot dynamic value', 'domain': '.example.com', 'name': 'test_dot_dynamic', 'value': s_testCookies.getRandomValue() }); s_testCookies.run({ 'message': 'implicit no domain static value', 'name': 'test_implicit_no_domain_static', 'value': 'implicit no domain static value' }); s_testCookies.run({ 'message': 'implicit no domain dynamic value', 'name': 'test_implicit_no_domain_dynamic', 'value': s_testCookies.getRandomValue() }); s_testCookies.run({ 'message': 'explicit no domain static value', 'domain':'', 'name': 'test_explicit_no_domain_static', 'value': 'explicit no domain static value' }); s_testCookies.run({ 'message': 'explicit no domain dynamic value', 'domain':'', 'name': 'test_explicit_no_domain_dynamic', 'value': s_testCookies.getRandomValue() }); 域上设置的。然后在下一页加载时,初始cookie /值将被设置为.example.com,并且exampe.com上的cookie也会获得更新的值。然后在另一个页面加载时,之前的.example.com值不会被加载/推送到cookie的.example.com版本;只有example.com版本更新。所以它只会在第二页加载时被加载/推送到.example.com。不是第3 +。

    同时,example.com cookie优先,并且是我们解析cookie值时返回的example.com。因此,在第3页+页面加载时,我们只是继续获取​​从document.cookie Cookie返回的第2页的值,而不是example.com中的更新值

    同时,我们不能简单地指定.example.com值(domain=以上),因为事实上存在子域名,例如#6 or #8也有读取/更新/写入这些Cookie的代码,如果我们没有指定域名,那么该Cookie只能在mobile.example.com上使用,并且无法在{{1}上读取}。

    UDPATE

    @ffeast 提出以下问题:

      

    curl -I yourdomain返回什么?是否有任何Set-Cookie标头?

    你走了!

    example.com

    我也从浏览器标签看到相同的响应标头。

    所以在最初的http响应中有一些set-cookie标头,是的。它们不是我亲自与我的事物范围有任何关系的饼干,但我可以问它们的用途,如果它有所帮助。示例:

    我注意到没有为它们显式设置mobile.example.com值。这有可能以某种方式为浏览器设置先例,还是我咆哮错误的树?即使它确实如此,我也不认为这只能解释user@host:~$ curl -I https://example.com HTTP/1.1 200 OK X-Powered-By: Express set-cookie: site#lang=en; Path=/;Secure set-cookie: connect.sid=s%3As46fwOPaosGdwis0G_Wdv7gzUs75Q0rr.O1gLsLmrHmmdBXxPWJrIq8UWwOOaQf96qxUlW%2FxnEuM; Path=/; HttpOnly;Secure Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Expires: 0 Content-Type: text/html; charset=utf-8 Content-Length: 19632 ETag: W/"4cb0-bgHMEy79PzLMv7jhB1Lh6A" Vary: Accept-Encoding Date: Fri, 16 Mar 2018 20:42:19 GMT Connection: keep-alive Set-Cookie: SecureCookie=!zPdIdxiz3mOMe2MYzy1p873u0yWtMdduASsHoU06gkaLs306mhR7cb3ir4TA2EG2cQGKmeVWJeYvxA/flQfPQUixqL8WMOfROsTgu3UZZg==; path=/; Httponly; Secure 对我改变价值的饼干,也不仅仅发生在第二页加载(而不是第三次+)?不确定你要去哪里,但我全都耳朵!

2 个答案:

答案 0 :(得分:0)

如果您的目标是在所有子域之间使用cookie共享,允许每个人访问并设置cookie,那么您需要在设置cookie时指定根域。

假设您有sub.example.comsub2.example.comexample.com,并且您希望在他们之间共享Cookie,然后将域设置为example.com。如果您未指定域名,则Cookie只是example.comsub.example.com的属性,但当您将域指定为example.com时,{{1}可以访问该域和它所有的子域来读写。

  

=域名(例如,' example.com'或' subdomain.example.com')。
  如果未指定,则默认为当前文档的主机部分   位置(但不包括子域)。与之前相反   规范,域名中的前导点被忽略,但浏览器   可能拒绝设置包含此类点的cookie。如果域名是   指定的子域名始终包含在内    [来源:developer.mozilla.org]

在example.com中:

example.com

在sub.example.com中:(与上述相同)

var value="some value";
document.cookie="myCookie="+escape(value)+"; path=/; domain=example.com";

在这两种情况下,您都必须将其设置为var value="some value"; document.cookie="myCookie="+escape(value)+"; path=/; domain=example.com"; 。否则可能会出现以下情况

  • example.com中,如果您忘记在同一个地方设置example.com,则只会为example.com创建一个与共享Cookie不同的新Cookie,并且不会与之同步它造成了很多混乱。
  • example.com中,如果您忘记在同一个地方设置sub.example.com,则只会为example.com创建一个与共享Cookie不同的新Cookie,并且不会与之同步它造成了很多混乱。
  • 您不应将Cookie设置为sub.example.com,因为根据上述报价不予理解。

Cookie重复的可能原因:

  1. 第一次加载页面时JavaScript设置cookie,指定.example.com设置domain=example.com的cookie,当第二个请求发出时,浏览器将cookie发送到服务器,服务器上的一些代码接收新cookie的一方将其设置回.example.com。这只能通过检查第二个请求的响应头来验证。
  2. 首次加载页面时,JavaScript会设置Cookie并指定example.com,以设置domain=example.com的Cookie。当页面加载秒时间时,任何JavaScript代码都会错误地设置它而不指定为.example.com设置cookie的domain=example.com。只有在检查设置cookie所涉及的JavaScript代码时才能验证这一点。
  3. 我认为意外创建域/子域特定cookie是您描述的所有异常的原因。查看正在设置cookie的每个代码部分都可以解决问题。

      

    更新:这里发生了什么。

    您正在使用 InvocaJS v3.6.6 AngularJS v1.2.19 ,它们都具有Cookie管理功能。 InvocaJS将数据存储在Cookie中example.com并指定域invoca_session,因此Cookie设置为example.com。 AngularJS第一次看到cookie时没有问题,它会记住它。 AngularJS保留所有cookie的副本,当您通过AngularJS更新任何cookie时,您实际上会修改该副本。然后,AngularJS遍历所有cookie,将其与副本进行比较,以确定和更新AngularJS已更新的cookie。

    InvocaJS反复更改.example.com的值。当AngularJS循环遍历所有cookie并且invoca_session与AngularJS的值不匹配时,它认为该值已被AngularJS更改(如上所述)并且它更新invoca_session的值替换新的旧的价值。 (我测试了它,这正是AngularJS v1.2.19的工作原理)

    问题是Angular v1.2.19在设置cookie时没有指定任何域(之前预测为错误概率#2)。因此,创建一个域名设置为invoca_session的新cookie。之后,当InvocaJS尝试读取cookie时,它会读取为example.com设置的旧cookie。

    AngularJS更改Cookie

    Dev-tools Debugger

    Dev-Tools Debugger 2

    注1:你不明白答案并不总是意味着谁回答了解你的问题。如果你合作一点,你可以在7天前得到这个答案。

    注2:你的黑匣子真的不能证明或反驳我提到的任何可能性。

    注3:如果您现在合作,如果您不想丢弃或升级AngularJS,我可以提供进一步帮助。

答案 1 :(得分:-1)

根据w3schools.com documention,您可以使用函数来构建,获取和检查您的cookie。

您可以查看How do browser cookie domains workherehere,以便更好地了解浏览器和javascript如何处理Cookie设置。

正如您在问题中所说的那样,Firefox也可以看到错误,可能需要注意:

  

与早期的规范相反,域名中的前导点会被忽略,但浏览器可能拒绝设置包含此类点的Cookie。如果指定了域,则始终包含子域。

正如你所说:

  

同时,example.com cookie优先,是我们解析cookie值时返回的一个document.cookie。因此,在第3页+页面加载时,我们只是继续获取​​从example.com cookie返回的第2页的值,而不是.example.com中的更新值

您可以仔细检查是否在第一次加载和将来的页面加载时从子域xxx.example.com加载了某些数据。

验证在将来重新加载期间是否缓存了某些数据。

您最终可能会仔细检查请求中是否存在以下标题:

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

避免缓存问题。