WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
85028
[BlackBerry] Cookies should be checked during parsing to improve performance.
https://bugs.webkit.org/show_bug.cgi?id=85028
Summary
[BlackBerry] Cookies should be checked during parsing to improve performance.
Jason Liu
Reported
2012-04-26 20:24:28 PDT
If a cookie coming in has a domain with domain="opera.com, the domain of the cookie will be saved in memory (and database) as '"opera.com'. The cookie will never be used because '"' is never used in a request domain. The expected behavior is to throw out the cookie immediately.
Attachments
Patch
(8.53 KB, patch)
2012-04-27 20:39 PDT
,
Jason Liu
no flags
Details
Formatted Diff
Diff
Patch
(8.53 KB, patch)
2012-04-27 23:39 PDT
,
Jason Liu
no flags
Details
Formatted Diff
Diff
Patch
(8.46 KB, patch)
2012-05-16 02:57 PDT
,
Jason Liu
no flags
Details
Formatted Diff
Diff
Show Obsolete
(2)
View All
Add attachment
proposed patch, testcase, etc.
Jason Liu
Comment 1
2012-04-27 20:39:14 PDT
Created
attachment 139330
[details]
Patch
Jason Liu
Comment 2
2012-04-27 23:39:40 PDT
Created
attachment 139342
[details]
Patch
Joe Mason
Comment 3
2012-04-30 07:52:15 PDT
The approach looks good. size_t dotPosition = parsedValue.find(".", 1); That looks wrong, though. The original code skipped this check if the domain did not start with a dot. So originally we had (where x is any character that isn't a dot): .xxxxx - accepted .xx.xx - accepted xxxxxx - REJECTED xxx.xx - accepted This is the same as searching for the dot from position 0, not 1. Also we have lost this check: 162 // ignore domain security if protocol doesn't have domains 163 if (shouldIgnoreDomain(cookie->protocol())) 164 return false; 165 166 // Reject Cookie if domain is empty 167 if (!cookie->domain().length()) 168 return true; We should check this in the parser, after the switch statement when both protocol and domain have been read.
Rob Buis
Comment 4
2012-05-04 12:14:17 PDT
Comment on
attachment 139342
[details]
Patch Based on Joe's comments, Jason needs to look into that, so r- for now.
Jason Liu
Comment 5
2012-05-06 18:52:40 PDT
(In reply to
comment #3
)
> The approach looks good. > > size_t dotPosition = parsedValue.find(".", 1); > > That looks wrong, though. The original code skipped this check if the domain did not start with a dot. So originally we had (where x is any character that isn't a dot): > > .xxxxx - accepted > .xx.xx - accepted > xxxxxx - REJECTED > xxx.xx - accepted > > This is the same as searching for the dot from position 0, not 1.
We check if the domain contains an embedded dot. And originally we had: .xxxxx - rejected not accepted .xx.xx - accepted xxxxxx - REJECTED xxx.xx - accepted So this is the same as searching for the dot from 1, not 0.
> Also we have lost this check: > > 162 // ignore domain security if protocol doesn't have domains > 163 if (shouldIgnoreDomain(cookie->protocol())) > 164 return false; > 165
If the protocol doesn't have domains, the code path won't contain domain parsing. So drop this "if" check in parsing.
> 166 // Reject Cookie if domain is empty > 167 if (!cookie->domain().length()) > 168 return true; >
size_t dotPosition = realDomain.find(".", 1); This is including length check.
Joe Mason
Comment 6
2012-05-07 08:16:31 PDT
In the original code: if (cookie->domain()[0] == '.') { // Check if the domain contains an embedded dot. size_t dotPosition = cookie->domain().find(".", 1); if (dotPosition == notFound || dotPosition == cookie->domain().length()) { LOG_ERROR("Cookie %s is rejected because its domain does not contain an embedded dot.\n", cookie->toString().utf8().data()); return true; } } // The request host should domain match the Domain attribute. // Domain string starts with a dot, so a.b.com should domain match .a.b.com. // add a "." at beginning of host name, because it can handle many cases such as // a.b.com matches b.com, a.b.com matches .B.com and a.b.com matches .A.b.Com // and so on. String hostDomainName = url.host(); hostDomainName = hostDomainName.startsWith(".") ? hostDomainName : "." + hostDomainName; if (!hostDomainName.endsWith(cookie->domain(), false)) { LOG_ERROR("Cookie %s is rejected because its domain does not domain match the URL %s\n", cookie->toString().utf8().data(), url.string().utf8().data()); return true; } // We should check for an embedded dot in the portion of string in the host not in the domain // but to match firefox behaviour we do not. return false; So for .xxxxx, cookie->domain()[0] is '.' and it skips the first "if" statement entirely. Then the second "if" statement looks only at url.host() so the dot position in the domain doesn't matter. Then it returns false, meaning "do not reject this cookie". Am I reading that wrong? The new code does: // Check if the domain contains an embedded dot. size_t dotPosition = parsedValue.find(".", 1); if (dotPosition == notFound || dotPosition == parsedValue.length()) LOG_AND_DELETE("Invalid cookie %s (domain): it does not contain an embedded dot", cookie.ascii().data()); So for ".xxxxx", dotPosition is notFound since it's starting at position 1 and not position 0. Which means it marks the cookie invalid and deletes it. I'm assuming the old code is correct. If not, we should file a different PR to fix the issue since this is a performance patch and should not cause any behaviour differences.
Jason Liu
Comment 7
2012-05-08 02:27:14 PDT
(In reply to
comment #6
)
> In the original code: > > if (cookie->domain()[0] == '.') { > // Check if the domain contains an embedded dot. > size_t dotPosition = cookie->domain().find(".", 1); > if (dotPosition == notFound || dotPosition == cookie->domain().length()) { > LOG_ERROR("Cookie %s is rejected because its domain does not contain an embedded dot.\n", cookie->toString().utf8().data()); > return true; > } > } > > // The request host should domain match the Domain attribute. > // Domain string starts with a dot, so a.b.com should domain match .a.b.com. > // add a "." at beginning of host name, because it can handle many cases such as > // a.b.com matches b.com, a.b.com matches .B.com and a.b.com matches .A.b.Com > // and so on. > String hostDomainName = url.host(); > hostDomainName = hostDomainName.startsWith(".") ? hostDomainName : "." + hostDomainName; > if (!hostDomainName.endsWith(cookie->domain(), false)) { > LOG_ERROR("Cookie %s is rejected because its domain does not domain match the URL %s\n", cookie->toString().utf8().data(), url.string().utf8().data()); > return true; > } > > // We should check for an embedded dot in the portion of string in the host not in the domain > // but to match firefox behaviour we do not. > > return false; > > > So for .xxxxx, cookie->domain()[0] is '.' and it skips the first "if" statement entirely. Then the second "if" statement looks only at url.host() so the dot position in the domain doesn't matter. Then it returns false, meaning "do not reject this cookie". > > Am I reading that wrong? >
In the original code: if (cookie->domain()[0] == '.') { For .xxxxx, it won't skip this if statement. it will go into this if branch and rejected by the following codes. // Check if the domain contains an embedded dot. size_t dotPosition = cookie->domain().find(".", 1); if (dotPosition == notFound || dotPosition == cookie->domain().length()) { LOG_ERROR("Cookie %s is rejected because its domain does not contain an embedded dot.\n", cookie->toString().utf8().data()); return true; } So there is no change in behaviour.
Joe Mason
Comment 8
2012-05-08 07:01:12 PDT
Wow. How did I read that so wrong? Ok, so the new code has the opposite problem. With the old code: .xxxxx - REJECTED .xx.xx - accepted xxxxxx - accepted xxx.xx - accepted With the new code: .xxxxx - REJECTED .xx.xx - accepted xxxxxx - REJECTED xxx.xx - accepted The old code only did the check when the domain started with a dot, but the new code always does it.
Jason Liu
Comment 9
2012-05-08 18:58:36 PDT
(In reply to
comment #8
)
> Wow. How did I read that so wrong? > > Ok, so the new code has the opposite problem. With the old code: > > .xxxxx - REJECTED > .xx.xx - accepted > xxxxxx - accepted > xxx.xx - accepted > > With the new code: > > .xxxxx - REJECTED > .xx.xx - accepted > xxxxxx - REJECTED > xxx.xx - accepted > > The old code only did the check when the domain started with a dot, but the new code always does it.
(In reply to
comment #8
)
> Wow. How did I read that so wrong? > > Ok, so the new code has the opposite problem. With the old code: > > .xxxxx - REJECTED > .xx.xx - accepted > xxxxxx - accepted > xxx.xx - accepted > > With the new code: > > .xxxxx - REJECTED > .xx.xx - accepted > xxxxxx - REJECTED > xxx.xx - accepted > > The old code only did the check when the domain started with a dot, but the new code always does it.
CookieParser::parseOneCookie { ... case 'D': case 'd' : { ... // If the domain does not start with a dot, add one for security checks, // For example: ab.c.com dose not domain match b.c.com; String realDomain = parsedValue[0] == '.' ? parsedValue : "." + parsedValue; ... } These codes will add '.' for xxxx. So xxxx becomes .xxxx before checking in the old code. And then rejected. The new code will check xxxx directly and drop it. So there is no change in behaviour for xxxx.
Jason Liu
Comment 10
2012-05-11 00:26:13 PDT
Would you help me review it again?
Joe Mason
Comment 11
2012-05-11 09:17:03 PDT
(In reply to
comment #10
)
> Would you help me review it again?
In case anyone was waiting for to weigh in, Jason's convinced me. The actual reviewer should double-check, though.
George Staikos
Comment 12
2012-05-12 11:14:45 PDT
Comment on
attachment 139342
[details]
Patch I'm ok with it in principle but haven't reviewed it in detail.
Jason Liu
Comment 13
2012-05-15 03:16:17 PDT
Would you approve this patch? :) And this is blocking my another cookie patch.
WebKit Review Bot
Comment 14
2012-05-15 23:37:18 PDT
Comment on
attachment 139342
[details]
Patch Rejecting
attachment 139342
[details]
from commit-queue. Failed to run "['/mnt/git/webkit-commit-queue/Tools/Scripts/webkit-patch', '--status-host=queues.webkit.org', '-..." exit_code: 2 Last 500 characters of output: ED at 138. 1 out of 1 hunk FAILED -- saving rejects to file Source/WebCore/platform/blackberry/CookieManager.cpp.rej patching file Source/WebCore/platform/blackberry/CookieManager.h patching file Source/WebCore/platform/blackberry/CookieParser.cpp Hunk #1 succeeded at 230 (offset 5 lines). Hunk #2 succeeded at 249 (offset 5 lines). Failed to run "[u'/mnt/git/webkit-commit-queue/Tools/Scripts/svn-apply', u'--force', u'--reviewer', u'George Sta..." exit_code: 1 cwd: /mnt/git/webkit-commit-queue/ Full output:
http://queues.webkit.org/results/12709325
Jason Liu
Comment 15
2012-05-16 02:57:41 PDT
Created
attachment 142209
[details]
Patch
WebKit Review Bot
Comment 16
2012-05-16 04:42:29 PDT
Comment on
attachment 142209
[details]
Patch Clearing flags on attachment: 142209 Committed
r117261
: <
http://trac.webkit.org/changeset/117261
>
WebKit Review Bot
Comment 17
2012-05-16 04:42:35 PDT
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug