@@ -64,8 +64,16 @@ bool CookieManager::SetCookie(std::string url, std::string cookie_data) {
64
64
return true ;
65
65
}
66
66
67
- int CookieManager::GetCookies (std::string url, std::vector<BrowserCookie>* all_cookies) {
67
+ int CookieManager::GetCookies (std::string url,
68
+ std::vector<BrowserCookie>* all_cookies) {
68
69
LOG (TRACE) << " Entering CookieManager::GetCookies" ;
70
+ std::wstring wide_url = StringUtilities::ToWString (url);
71
+ CComPtr<IUri> parsed_url;
72
+ ::CreateUri (wide_url.c_str(), Uri_CREATE_ALLOW_RELATIVE, 0, &parsed_url);
73
+ DWORD url_scheme = 0 ;
74
+ parsed_url->GetScheme (&url_scheme);
75
+ bool is_secure_url = URL_SCHEME_HTTPS == url_scheme;
76
+
69
77
HookSettings hook_settings;
70
78
hook_settings.hook_procedure_name = " CookieWndProc" ;
71
79
hook_settings.hook_procedure_type = WH_CALLWNDPROC;
@@ -77,24 +85,34 @@ int CookieManager::GetCookies(std::string url, std::vector<BrowserCookie>* all_c
77
85
78
86
// Get all cookies for the current URL visible to JavaScript.
79
87
std::wstring scriptable_cookie_string =
80
- this ->SendGetCookieMessage (StringUtilities::ToWString (url) ,
81
- WD_GET_SCRIPTABLE_COOKIES,
82
- &hook);
88
+ this ->SendGetCookieMessage (wide_url ,
89
+ WD_GET_SCRIPTABLE_COOKIES,
90
+ &hook);
83
91
std::map<std::string, std::string> scriptable_cookies;
84
92
this ->ParseCookieString (scriptable_cookie_string, &scriptable_cookies);
85
93
86
- // Get all cookies for the current URL, including HttpOnly cookies.
87
- std::wstring httponly_cookie_string =
88
- this ->SendGetCookieMessage (StringUtilities::ToWString (url),
94
+ // Get all cookies for the insecure version of the current URL,
95
+ // which will include HttpOnly cookies.
96
+ std::wstring insecure_cookie_string =
97
+ this ->SendGetCookieMessage (wide_url,
89
98
WD_GET_HTTPONLY_COOKIES,
90
99
&hook);
91
- std::map<std::string, std::string> httponly_cookies;
92
- this ->ParseCookieString (httponly_cookie_string, &httponly_cookies);
100
+ std::map<std::string, std::string> insecure_cookies;
101
+ this ->ParseCookieString (insecure_cookie_string, &insecure_cookies);
102
+
103
+ // Get all cookies for the current secure URL. This will include
104
+ // HttpOnly cookies.
105
+ std::wstring secure_cookie_string =
106
+ this ->SendGetCookieMessage (wide_url,
107
+ WD_GET_SECURE_COOKIES,
108
+ &hook);
109
+ std::map<std::string, std::string> secure_cookies;
110
+ this ->ParseCookieString (secure_cookie_string, &secure_cookies);
93
111
94
112
// Get all of the persistent cookie files in the cache for the
95
113
// URL currently being browsed.
96
114
std::wstring file_list = this ->SendGetCookieMessage (
97
- StringUtilities::ToWString (url) ,
115
+ wide_url ,
98
116
WD_GET_COOKIE_CACHE_FILES,
99
117
&hook);
100
118
std::vector<std::wstring> files;
@@ -106,28 +124,35 @@ int CookieManager::GetCookies(std::string url, std::vector<BrowserCookie>* all_c
106
124
for (std::vector<std::wstring>::const_iterator file_iterator = files.begin ();
107
125
file_iterator != files.end ();
108
126
++file_iterator) {
109
- this ->ReadPersistentCookieFile (*file_iterator, &persistent_cookies);
127
+ this ->ReadPersistentCookieFile (*file_iterator,
128
+ is_secure_url,
129
+ &persistent_cookies);
110
130
}
111
131
112
- // Loop through the entire list of cookies, including HttpOnly cookies.
113
- // If the cookie exists as a persistent cookie, use its data from the
114
- // cache. If the cookie is found in the list of cookies visible to
115
- // JavaScript, set the HttpOnly property of the cookie to false.
116
- std::map<std::string, std::string>::const_iterator it = httponly_cookies.begin ();
117
- for (; it != httponly_cookies.end (); ++it) {
132
+ // Loop through the entire list of cookies, including HttpOnly and secure
133
+ // cookies. If the cookie exists as a persistent cookie, use its data from
134
+ // the cache. If the cookie is found in the list of cookies visible to
135
+ // JavaScript, set the HttpOnly property of the cookie to false. If the
136
+ // cookie is found in the list of cookies set on the insecure version of
137
+ // the URL, set the Secure property of the cookie to false.
138
+ std::map<std::string, std::string>::const_iterator it = secure_cookies.begin ();
139
+ for (; it != secure_cookies.end (); ++it) {
118
140
BrowserCookie browser_cookie;
119
141
if (persistent_cookies.find (it->first ) != persistent_cookies.end ()) {
120
142
browser_cookie = persistent_cookies[it->first ];
143
+ } else {
144
+ browser_cookie.set_name (it->first );
145
+ browser_cookie.set_value (it->second );
146
+ browser_cookie.set_is_httponly (scriptable_cookies.find (it->first ) == scriptable_cookies.end ());
147
+ browser_cookie.set_is_secure (insecure_cookies.find (it->first ) == insecure_cookies.end ());
121
148
}
122
- browser_cookie.set_name (it->first );
123
- browser_cookie.set_value (it->second );
124
- browser_cookie.set_is_httponly (scriptable_cookies.find (it->first ) == scriptable_cookies.end ());
125
149
all_cookies->push_back (browser_cookie);
126
150
}
127
151
return 0 ;
128
152
}
129
153
130
154
void CookieManager::ReadPersistentCookieFile (const std::wstring& file_name,
155
+ const bool include_secure_cookies,
131
156
std::map<std::string, BrowserCookie>* cookies) {
132
157
LOG (TRACE) << " Entering CookieManager::ReadPersistentCookieFile" ;
133
158
HANDLE file_handle = ::CreateFile (file_name.c_str (),
@@ -153,11 +178,22 @@ void CookieManager::ReadPersistentCookieFile(const std::wstring& file_name,
153
178
// a line containing a single asterisk ('*'). Split the file
154
179
// content on this delimiter, and parse each record.
155
180
std::vector<std::string> persistent_cookie_strings;
156
- StringUtilities::Split (cookie_file_contents, " \n *\n " , &persistent_cookie_strings);
181
+ StringUtilities::Split (cookie_file_contents,
182
+ " \n *\n " ,
183
+ &persistent_cookie_strings);
157
184
std::vector<std::string>::const_iterator cookie_string_iterator = persistent_cookie_strings.begin ();
158
- for (; cookie_string_iterator != persistent_cookie_strings.end (); ++cookie_string_iterator) {
159
- BrowserCookie persistent_cookie = this ->ParsePersistentCookieInfo (*cookie_string_iterator);
160
- cookies->insert (std::pair<std::string, BrowserCookie>(persistent_cookie.name (), persistent_cookie));
185
+ for (;
186
+ cookie_string_iterator != persistent_cookie_strings.end ();
187
+ ++cookie_string_iterator) {
188
+ BrowserCookie persistent_cookie =
189
+ this ->ParsePersistentCookieInfo (*cookie_string_iterator);
190
+ if (include_secure_cookies || !persistent_cookie.is_secure ()) {
191
+ // Omit the cookie if it's 'secure' flag is set and we are *not*
192
+ // browsing using SSL.
193
+ cookies->insert (
194
+ std::pair<std::string, BrowserCookie>(persistent_cookie.name (),
195
+ persistent_cookie));
196
+ }
161
197
}
162
198
}
163
199
@@ -281,27 +317,54 @@ LRESULT CALLBACK CookieWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
281
317
COPYDATASTRUCT* data = reinterpret_cast <COPYDATASTRUCT*>(call_window_proc_struct->lParam );
282
318
webdriver::HookProcessor::CopyDataToBuffer (data->cbData , data->lpData );
283
319
} else if (WD_GET_HTTPONLY_COOKIES == call_window_proc_struct->message ||
284
- WD_GET_SCRIPTABLE_COOKIES == call_window_proc_struct->message ) {
320
+ WD_GET_SCRIPTABLE_COOKIES == call_window_proc_struct->message ||
321
+ WD_GET_SECURE_COOKIES == call_window_proc_struct->message ) {
285
322
std::wstring url = webdriver::HookProcessor::CopyWStringFromBuffer ();
286
323
int driver_process_id = static_cast <int >(call_window_proc_struct->wParam );
287
- DWORD get_cookie_error = 0 ;
324
+
288
325
DWORD get_cookie_flags = 0 ;
289
- if (WD_GET_HTTPONLY_COOKIES == call_window_proc_struct->message ) {
326
+ if (WD_GET_HTTPONLY_COOKIES == call_window_proc_struct->message ||
327
+ WD_GET_SECURE_COOKIES == call_window_proc_struct->message ) {
290
328
get_cookie_flags = INTERNET_COOKIE_HTTPONLY;
291
329
}
292
330
331
+ CComPtr<IUri> uri_pointer;
332
+ HRESULT hr = ::CreateUri (url.c_str (), Uri_CREATE_ALLOW_RELATIVE, 0 , &uri_pointer);
333
+ DWORD scheme = 0 ;
334
+ uri_pointer->GetScheme (&scheme);
335
+ CComBSTR scheme_bstr;
336
+ uri_pointer->GetSchemeName (&scheme_bstr);
337
+ CComBSTR host_bstr;
338
+ uri_pointer->GetHost (&host_bstr);
339
+ CComBSTR path_bstr;
340
+ uri_pointer->GetPath (&path_bstr);
341
+
342
+ // Get only the cookies for the base URL, omitting port, if there is one.
343
+ // N.B., we only return cookies secure cookies when browsing a site using
344
+ // SSL. The browser won't see cookies with the 'secure' flag for sites
345
+ // visited using plain http.
346
+ std::wstring parsed_uri = L" http" ;
347
+ if ((WD_GET_SECURE_COOKIES == call_window_proc_struct->message ||
348
+ WD_GET_SCRIPTABLE_COOKIES == call_window_proc_struct->message ) &&
349
+ URL_SCHEME_HTTPS == scheme) {
350
+ parsed_uri.append (L" s" );
351
+ }
352
+ parsed_uri.append (L" ://" );
353
+ parsed_uri.append (host_bstr);
354
+ parsed_uri.append (path_bstr);
355
+
293
356
// Call InternetGetCookieEx once to get the size of the buffer needed,
294
357
// then call again with the appropriately sized buffer allocated.
295
358
DWORD buffer_size = 0 ;
296
- BOOL success = ::InternetGetCookieEx (url .c_str (),
359
+ BOOL success = ::InternetGetCookieEx (parsed_uri .c_str (),
297
360
NULL ,
298
361
NULL ,
299
362
&buffer_size,
300
363
get_cookie_flags,
301
364
NULL );
302
365
if (success) {
303
366
webdriver::HookProcessor::SetDataBufferSize (buffer_size);
304
- ::InternetGetCookieEx (url .c_str(),
367
+ ::InternetGetCookieEx (parsed_uri .c_str(),
305
368
NULL,
306
369
reinterpret_cast<LPTSTR>(webdriver::HookProcessor::GetDataBufferAddress()),
307
370
&buffer_size,
0 commit comments