{"id":609,"date":"2008-08-26T22:07:44","date_gmt":"2008-08-26T20:07:44","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=609"},"modified":"2009-02-11T22:16:55","modified_gmt":"2009-02-11T20:16:55","slug":"winhttp-escaping-problem","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/609","title":{"rendered":"WinHTTP escaping problem"},"content":{"rendered":"<p><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa384092(VS.85).aspx\">WinHttpCrackUrl<\/a> and <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa384093(VS.85).aspx\">WinHttpCreateUrl<\/a> API functions are breaking URL string into components and recompose back to string. There was a mess with passwords and security issues since when putting password into URL is no more acceptable. Experienced users might remember the times when URL could embed password, e.g. <em>ftp:\/\/john:mysecretpassword@host.com\/path<\/em>. Password is lo longer accepted by major applications in a typed in string and no more allowed by updated <a href=\"http:\/\/www.ietf.org\/rfc\/rfc3986.txt\">RFC 3986 &#8220;Uniform Resource Identifier (URI): Generic Syntax&#8221;<\/a>:<\/p>\n<pre>3.2.1.  User Information\r\n\r\n   The userinfo subcomponent may consist of a user name and, optionally,\r\n   scheme-specific information about how to gain authorization to access\r\n   the resource.  The user information, if present, is followed by a\r\n   commercial at-sign (\"@\") that delimits it from the host.\r\n\r\n      userinfo    = *( unreserved \/ pct-encoded \/ sub-delims \/ \":\" )\r\n\r\n   Use of the format \"user:password\" in the userinfo field is\r\n   deprecated.  <strong>Applications should not render as clear text any data\r\n   after the first colon (\":\") character found within a userinfo\r\n   subcomponent unless the data after the colon is the empty string\r\n   (indicating no password).\r\n<\/strong><\/pre>\n<p>What if we don&#8217;t have URLs typed in? But it still convenient to keep password as a part of URL? Luckily there is such thing as compatibility, so we can rely on <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa384276(VS.85).aspx\">WinHTTP<\/a> subsystem to process passwords for us. The problem however is escapement. The most tricky is that it is not a bug, it is documented but is unintuitive. The cracking part would unescape all components if ICU_DECODE flag is provided. The composing part however will only escape (ICU_ESCAPE) the part to the right from port number (whether it is specified or expected to be)!<\/p>\n<p>For example (see source code below):<\/p>\n<pre>g_ppszUrls[3] http:\/\/user:pa<span style=\"color: #008000;\">%40<\/span>ss@site.com\/path?name=value<span style=\"color: #0000ff;\">%20%2F%3A%40<\/span>\r\n.lpszScheme http\r\n.nScheme 1\r\n.lpszHostName site.com\r\n.nPort 80\r\n.lpszUserName user\r\n.lpszPassword pa@ss\r\n.lpszUrlPath \/path\r\n.lpszExtraInfo ?name=value \/:@\r\npszUrl http:\/\/user:pa<span style=\"color: #ff0000;\">@<\/span>ss@site.com\/path?name=value<span style=\"color: #0000ff;\"> \/:@<\/span>\r\npszUrl (ICU_ESCAPE) http:\/\/user:pa<span style=\"color: #ff0000;\">@<\/span>ss@site.com\/path?name=value<span style=\"color: #0000ff;\">%20\/:@<\/span><\/pre>\n<p><!--more-->So, if you care for proper escapement it appears that you have to do it yourself after\/before WinHTTP does the rest of the task.<\/p>\n<p>So let us mention what is the proper RFC-compliant escaping after all:<\/p>\n<pre>  <span class=\"__mozilla-findbar-search\" style=\"padding: 0pt; background-color: yellow; color: black; display: inline; font-size: inherit;\">userinfo<\/span>      = *( unreserved \/ pct-encoded \/ sub-delims \/ \":\" )\r\n...\r\n   pct-encoded   = \"%\" HEXDIG HEXDIG\r\n   unreserved    = ALPHA \/ DIGIT \/ \"-\" \/ \".\" \/ \"_\" \/ \"~\"\r\n   sub-delims    = \"!\" \/ \"$\" \/ \"&amp;\" \/ \"'\" \/ \"(\" \/ \")\"\r\n                 \/ \"*\" \/ \"+\" \/ \",\" \/ \";\" \/ \"=\"<\/pre>\n<p>Visual Studio C++.NET 2008 source code and binary: <a href=\"https:\/\/alax.info\/blog\/wp-content\/uploads\/2008\/08\/winhttpurl0101.zip\">WinHttpUrl01.01.zip<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>WinHttpCrackUrl and WinHttpCreateUrl API functions are breaking URL string into components and recompose back to string. There was a mess with passwords and security issues since when putting password into URL is no more acceptable. Experienced users might remember the times when URL could embed password, e.g. ftp:\/\/john:mysecretpassword@host.com\/path. Password is lo longer accepted by major&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/609\">Read the full article<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,13,12,2],"tags":[118,115,117,488,116,114],"class_list":["post-609","post","type-post","status-publish","format-standard","hentry","category-camoftheday","category-source","category-technology","category-utilities","tag-http","tag-problem","tag-rfc","tag-source","tag-url","tag-winhttp"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/609","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/comments?post=609"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/609\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=609"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=609"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=609"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}