{"id":151,"date":"2023-04-15T13:44:00","date_gmt":"2023-04-15T06:44:00","guid":{"rendered":"https:\/\/n45ht.or.id\/blog\/?p=151"},"modified":"2024-12-14T22:54:09","modified_gmt":"2024-12-14T15:54:09","slug":"exploiting-httpstatusio-an-xss-via-protocol-handling","status":"publish","type":"post","link":"https:\/\/n45ht.or.id\/blog\/exploiting-httpstatusio-an-xss-via-protocol-handling\/","title":{"rendered":"Exploiting HTTPStatus.io: An XSS via Protocol Handling"},"content":{"rendered":"\n<p><strong>httpstatus.io<\/strong> is a tool that allows you to check HTTP status codes, headers, and redirects. For example, when you submit a URL or domain, <strong>httpstatus.io<\/strong> will check the HTTP status code and where the domain will be redirected, such as when the HTTP status code is 301, 302, etc.<\/p>\n\n\n\n<p>Let me walk you through an interesting scenario I explored with <strong>httpstatus.io<\/strong>.<\/p>\n\n\n\n<p><strong>Step-by-Step Exploit:<\/strong><\/p>\n\n\n\n<p>I started by submitting a normal URL, for example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"HTML\" class=\"language-HTML\">https:\/\/google.com<\/code><\/pre>\n\n\n\n<p>The response was normal, as expected.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"208\" src=\"https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io2_-1024x208.png\" alt=\"\" class=\"wp-image-153\" style=\"width:509px;height:auto\" srcset=\"https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io2_-1024x208.png 1024w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io2_-300x61.png 300w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io2_-768x156.png 768w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io2_.png 1184w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, I decided to submit a domain <strong>without a protocol<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"HTML\" class=\"language-HTML\">google.com<\/code><\/pre>\n\n\n\n<p>The server automatically added the protocol (either HTTP or HTTPS) to the domain and turned it into:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"244\" src=\"https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io3_-1024x244.png\" alt=\"\" class=\"wp-image-154\" style=\"width:475px;height:auto\" srcset=\"https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io3_-1024x244.png 1024w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io3_-300x72.png 300w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io3_-768x183.png 768w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io3_.png 1199w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"HTML\" class=\"language-HTML\">protocol:\/\/google.com<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"256\" src=\"https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io4_-1024x256.png\" alt=\"\" class=\"wp-image-155\" style=\"width:489px;height:auto\" srcset=\"https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io4_-1024x256.png 1024w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io4_-300x75.png 300w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io4_-768x192.png 768w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io4_.png 1204w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>At this point, everything seemed normal, and the server treated the domain like a regular URL. However, I noticed something interesting when I sent a specific <strong>payload<\/strong> instead of a typical URL.<\/p>\n\n\n\n<p>I used <strong>JavaScript<\/strong> as the protocol and crafted an XSS payload as the domain. The resulting payload looked like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"HTML\" class=\"language-HTML\">javascript:\/\/%0aalert(document.domain);\/\/<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"252\" src=\"https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io5_-1024x252.png\" alt=\"\" class=\"wp-image-156\" style=\"width:465px;height:auto\" srcset=\"https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io5_-1024x252.png 1024w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io5_-300x74.png 300w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io5_-768x189.png 768w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io5_.png 1206w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>When clicking the resulting link, a <strong>window dialog<\/strong> popped up with an alert, executing my JavaScript payload.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"472\" src=\"https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io6_-1024x472.png\" alt=\"\" class=\"wp-image-157\" style=\"width:475px;height:auto\" srcset=\"https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io6_-1024x472.png 1024w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io6_-300x138.png 300w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io6_-768x354.png 768w, https:\/\/n45ht.or.id\/blog\/wp-content\/uploads\/2024\/12\/httpstatus.io6_.png 1270w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>By exploiting how <strong>httpstatus.io<\/strong> handles the protocol and domain input, I was able to trigger an <strong>XSS<\/strong> vulnerability. This technique relies on the server treating JavaScript as a protocol and the payload as the domain, ultimately executing a script when the URL is clicked.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>httpstatus.io is a tool that allows you to check HTTP status codes, headers, and redirects. For example, when you submit a URL or domain, httpstatus.io will check the HTTP status code and where the domain will be redirected, such as when the HTTP status code is 301, 302, etc. Let me walk you through an [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":152,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[9],"class_list":["post-151","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-research","tag-cross-site-scripting"],"_links":{"self":[{"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/posts\/151","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/comments?post=151"}],"version-history":[{"count":1,"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/posts\/151\/revisions"}],"predecessor-version":[{"id":158,"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/posts\/151\/revisions\/158"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/media\/152"}],"wp:attachment":[{"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/media?parent=151"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/categories?post=151"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/n45ht.or.id\/blog\/wp-json\/wp\/v2\/tags?post=151"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}