{"id":575,"date":"2022-01-27T18:13:36","date_gmt":"2022-01-27T18:13:36","guid":{"rendered":"https:\/\/lyhinslab.org\/?p=575"},"modified":"2023-06-20T23:05:51","modified_gmt":"2023-06-20T23:05:51","slug":"how-white-box-hacking-works-invoiceplane-a-lot-of-xss-and-a-couple-of-bac-vulnerabilities","status":"publish","type":"post","link":"https:\/\/lscp.llc\/index.php\/2022\/01\/27\/how-white-box-hacking-works-invoiceplane-a-lot-of-xss-and-a-couple-of-bac-vulnerabilities\/","title":{"rendered":"How White-Box hacking works: InvoicePlane &#8211; A Lot Of XSS And A Couple Of BAC Vulnerabilities"},"content":{"rendered":"\n<p>Hi all! <a rel=\"noreferrer noopener\" href=\"https:\/\/www.invoiceplane.com\/\" data-type=\"URL\" data-id=\"https:\/\/www.invoiceplane.com\/\" target=\"_blank\">InvoicePlane<\/a> is a self-hosted open source application for managing your quotes, invoices, clients and payments. After a brief review, we found the following issues:<\/p>\n\n\n\n<p><strong><em>A pile of stored XSS.<\/em><\/strong> This Cross-Site Scripting is naturally everywhere. Javascript is being executed in different places of the application:<br>&nbsp;&nbsp;&nbsp;&nbsp;In&nbsp;field&nbsp;&#8220;Invoice&nbsp;#&#8221;&nbsp;of&nbsp;invoice,&nbsp;appearing:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"http:\/\/%7Bdomain%7D\/index.php\/invoices\/view\/%7Binvoice_id%7D\">http:\/\/{domain}\/index.php\/invoices\/view\/{invoice_id}<\/a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"http:\/\/%7Bdomain%7D\/index.php\/dashboard\">http:\/\/{domain}\/index.php\/dashboard<\/a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"http:\/\/%7Bdomain%7D\/index.php\/invoices\/status\/all\">http:\/\/{domain}\/index.php\/invoices\/status\/all<\/a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"http:\/\/%7Bdomain%7D\/index.php\/clients\/view\/%7Bclient_id%7D\">http:\/\/{domain}\/index.php\/clients\/view\/{client_id}<\/a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"http:\/\/%7Bdomain%7D\/index.php\/guest\">http:\/\/{domain}\/index.php\/guest<\/a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"http:\/\/%7Bdomain%7D\/index.php\/guest\/invoices\/status\/open\">http:\/\/{domain}\/index.php\/guest\/invoices\/status\/open<\/a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;In guest URL, e.g.:&nbsp;<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"http:\/\/%7Bdomain%7D\/index.php\/guest\/view\/invoice\/Nmdzjv5fVJb3IHYhL8eTM6RaWX1s7gKc\">http:\/\/{domain}\/index.php\/guest\/view\/invoice\/Nmdzjv5fVJb3IHYhL8eTM6RaWX1s7gKc<\/a><br>&nbsp;&nbsp;&nbsp;&nbsp;In&nbsp;fields&nbsp;&#8220;VAT&nbsp;ID&#8221;&nbsp;and&nbsp;&#8220;Taxes&nbsp;Code&#8221;&nbsp;of&nbsp;client,&nbsp;appearing:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;In guest URL, e.g.:&nbsp;<a rel=\"noreferrer noopener\" target=\"_blank\" href=\"http:\/\/%7Bdomain%7D\/index.php\/guest\/view\/invoice\/Nmdzjv5fVJb3IHYhL8eTM6RaWX1s7gKc\">http:\/\/{domain}\/index.php\/guest\/view\/invoice\/Nmdzjv5fVJb3IHYhL8eTM6RaWX1s7gKc<\/a><br>&nbsp;&nbsp;&nbsp;&nbsp;In&nbsp;fields&nbsp;&#8220;Client&nbsp;Name&#8221;&nbsp;and&nbsp;&#8220;Client&nbsp;Surname&#8221;&nbsp;of&nbsp;client,&nbsp;appearing:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http:\/\/{domain}\/index.php\/guest\/invoices\/view\/{invoice_id}<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1210\" height=\"815\" src=\"https:\/\/lyhinslab.org\/wp-content\/uploads\/2022\/01\/Img.-1-Changing-Invoice-to-XSS-injection.png\" alt=\"\" class=\"wp-image-577\"\/><figcaption class=\"wp-element-caption\"><meta charset=\"utf-8\">Image 1. Changing Invoice# to XSS injection<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1209\" height=\"814\" src=\"https:\/\/lyhinslab.org\/wp-content\/uploads\/2022\/01\/Img.-2-Srcipt-execution.png\" alt=\"\" class=\"wp-image-578\"\/><figcaption class=\"wp-element-caption\"><meta charset=\"utf-8\">Image 2. Script execution<\/figcaption><\/figure>\n\n\n\n<p>That&#8217;s a set of vulnerable to XSS fields in the app. It has no encoding data on output nor has no input validation.<\/p>\n\n\n\n<p><strong><em>BAC in handling invoice status. <\/em><\/strong>Imagine that you had recently closed a kind of really valuable invoice, in fact, for a big amount of money. Its change can make quite a lot of problems if it&#8217;s already paid and not intended for further modification. Believe it or not, it&#8217;s quite easy to do if you have access to control invoice information before it comes paid. Here are steps to reproduce BAC in <meta charset=\"utf-8\">handling invoice status:<br><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Admin marks the absolutely normal invoice as &#8220;paid&#8221; (see img. 3) with POST request like this (we can intercept this by Burp Suite Community Edition (which is free) for example) (see img. 4):<\/li>\n\n\n\n<li>Return to the browser and see how your invoice is now marked as &#8220;Read only&#8221; (see img. 5).<\/li>\n\n\n\n<li>Back to the Burp Suite and go to the &#8220;Repeater&#8221; section.<\/li>\n\n\n\n<li>Change invoice_status_id in request&#8217;s parameters from 4 to 1 (see img. 6) and then send it.<\/li>\n\n\n\n<li>Return to the browser and see that invoice is still marked as &#8220;Read only&#8221; but now it&#8217;s a draft and we have the option to delete it (see img. 7). (If we click it, it successfully deletes)<br>Note: we can change not only the invoice_status_id parameter through this BAC but, for example, the invoice_number parameter (we can put in it XSS injection for instance).<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/lscp.llc\/wp-content\/uploads\/2022\/01\/Img.-3-Admin-marks-absolutely-normal-invoice-as-paid-1.png\"><img decoding=\"async\" width=\"1208\" height=\"813\" data-id=\"586\" src=\"http:\/\/lscp.llc\/wp-content\/uploads\/2022\/01\/Img.-3-Admin-marks-absolutely-normal-invoice-as-paid-1.png\" alt=\"\" class=\"wp-image-586\"\/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/lscp.llc\/wp-content\/uploads\/2022\/01\/Img.-4-Request-interception-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1002\" height=\"653\" data-id=\"587\" src=\"http:\/\/lscp.llc\/wp-content\/uploads\/2022\/01\/Img.-4-Request-interception-2.png\" alt=\"\" class=\"wp-image-587\"\/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/lscp.llc\/wp-content\/uploads\/2022\/01\/Img.-5-Invoice-now-marked-as-Read-only-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1204\" height=\"817\" data-id=\"588\" src=\"http:\/\/lscp.llc\/wp-content\/uploads\/2022\/01\/Img.-5-Invoice-now-marked-as-Read-only-1.png\" alt=\"\" class=\"wp-image-588\"\/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/lscp.llc\/wp-content\/uploads\/2022\/01\/Img.-6-Changing-invoice_status_id-in-requests-parameters-from-4-to-1-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1002\" height=\"652\" data-id=\"589\" src=\"http:\/\/lscp.llc\/wp-content\/uploads\/2022\/01\/Img.-6-Changing-invoice_status_id-in-requests-parameters-from-4-to-1-1.png\" alt=\"\" class=\"wp-image-589\"\/><\/a><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/lscp.llc\/wp-content\/uploads\/2022\/01\/Img.-7-Invoice-still-marked-as-Read-only-but-now-its-a-draft-and-we-have-option-to-delete-it-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1208\" height=\"819\" data-id=\"590\" src=\"http:\/\/lscp.llc\/wp-content\/uploads\/2022\/01\/Img.-7-Invoice-still-marked-as-Read-only-but-now-its-a-draft-and-we-have-option-to-delete-it-1.png\" alt=\"\" class=\"wp-image-590\"\/><\/a><\/figure>\n<figcaption class=\"blocks-gallery-caption wp-element-caption\">Image 3 \u2013 7. Steps to reproduce BAC in <meta charset=\"utf-8\"><\/meta>handling invoice status<\/figcaption><\/figure>\n\n\n\n<p><meta charset=\"utf-8\"><strong><em><meta charset=\"utf-8\"><strong><em><meta charset=\"utf-8\">BAC in handling access to draft invoices<\/em><\/strong>.<\/em><\/strong> The third issue appears from the guest&#8217;s side. <meta charset=\"utf-8\">Guest (Read-Only) users can access drafts of their clients&#8217; invoices while meant to have access only to paid and opened ones.<br>Step to reproduce this issue is quite easy: we need to go by the link with the invoice_id that we can enumerate <a href=\"http:\/\/{domain}\/index.php\/guest\/invoices\/view\/{invoice_id that in draft}\">http:\/\/{domain}\/index.php\/guest\/invoices\/view\/{invoice_id that in draft}<\/a> and see info about an invoice that we should not be able to see.<\/p>\n\n\n\n<p>That&#8217;s all with it and we wish you enjoy the rest of your day!  <\/p>\n\n\n\n<p><em><em>LL advises all the researchers to avoid breaking real applications<\/em>&nbsp;<em>illegally. This fun leads to broken businesses and lives, and, most likely, will not make an attacker really rich.<\/em><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi all! InvoicePlane is a self-hosted open source application for managing your quotes, invoices, clients and payments. After a brief review, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-575","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/lscp.llc\/index.php\/wp-json\/wp\/v2\/posts\/575","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lscp.llc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lscp.llc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lscp.llc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lscp.llc\/index.php\/wp-json\/wp\/v2\/comments?post=575"}],"version-history":[{"count":0,"href":"https:\/\/lscp.llc\/index.php\/wp-json\/wp\/v2\/posts\/575\/revisions"}],"wp:attachment":[{"href":"https:\/\/lscp.llc\/index.php\/wp-json\/wp\/v2\/media?parent=575"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lscp.llc\/index.php\/wp-json\/wp\/v2\/categories?post=575"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lscp.llc\/index.php\/wp-json\/wp\/v2\/tags?post=575"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}