<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>manipulate Archive - Robert Skibbe</title>
	<atom:link href="https://robbelroot.de/blog/tag/manipulate/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>alias RobbelRoot – Freelance Full Stack Developer .NET</description>
	<lastBuildDate>Fri, 11 Feb 2022 09:02:54 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://robbelroot.de/wp-content/uploads/2020/12/cropped-favicon-32x32.png</url>
	<title>manipulate Archive - Robert Skibbe</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>&#x1f575;&#xfe0f; Hacking a Webshop – don&#8217;t fall for this common trap!</title>
		<link>https://robbelroot.de/blog/hacking-a-webshop/</link>
					<comments>https://robbelroot.de/blog/hacking-a-webshop/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Sat, 22 Jan 2022 14:49:51 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[bad]]></category>
		<category><![CDATA[budget]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[crud]]></category>
		<category><![CDATA[danger]]></category>
		<category><![CDATA[dangerous]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[hacked]]></category>
		<category><![CDATA[hacker]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[manipulate]]></category>
		<category><![CDATA[manipulating]]></category>
		<category><![CDATA[method]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[post]]></category>
		<category><![CDATA[request]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[shop]]></category>
		<category><![CDATA[vulnerability]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[webapi]]></category>
		<category><![CDATA[webapp]]></category>
		<category><![CDATA[webshop]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=7503</guid>

					<description><![CDATA[<p>Hacking a Webshop So you are interested in hacking a webshop, or in software development security in general? I welcome you to todays post on application security and how to use or protect against this special case. In this example you can simply follow along by just downloading and executing &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/hacking-a-webshop/">&#x1f575;&#xfe0f; Hacking a Webshop – don&#8217;t fall for this common trap!</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-a-webshop-post-image.png"><img fetchpriority="high" decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-a-webshop-post-image.png" alt="Hacking a Webshop – a crappy one, the &quot;Crapshop&quot;" class="wp-image-7506" title="Hacking a Webshop – a crappy one, the &quot;Crapshop&quot;"/></a><figcaption> Hacking a Webshop – a crappy one, the &#8222;Crapshop&#8220;</figcaption></figure>






<h2 class="wp-block-heading" id="hacking-a-webshop">Hacking a Webshop</h2>



<p>So you are interested in <strong>hacking a webshop</strong>, or in <strong>software development security</strong> in general?</p>



<p>I <strong>welcome</strong> you to todays post on application security and <strong>how to use or protect against this special case</strong>.</p>



<p>In <strong>this example</strong> you can <strong>simply follow along</strong> by just <strong>downloading </strong>and executing the <strong>example code</strong>.</p>



<p><strong>Especially when i</strong> first <strong>started </strong>programming, I found a lot of code like the one you will see.</p>



<p>Easy <strong>cart items</strong> just <strong>being added </strong>without enough checking or protection <strong>against </strong>some <strong>malicious </strong>boi.</p>



<h3 class="wp-block-heading" id="i-m-still-working-on-this-article-so-more-content-will-come-in-a-few-hours">I&#8217;m still working on this article, so more content will come in a few hours 🙂</h3>


<div class="async-youtube" data-embed="_XNaOH-1PZI" data-alt="">
    <div class="play-button"></div>      
  </div>



<p><strong>Here </strong>comes <strong>the big thing</strong> – <strong>even today </strong>some shops will still be programmed like that..</p>



<p>So <strong>hacking a webshop</strong> like this will still be possible for some of those badly programmed ones.</p>



<p><strong>On my journey</strong> i <strong>continiously asked </strong>myself the &#8222;<strong>why</strong>&#8220; behind that problem.</p>



<p><strong>Most of the time</strong>, you will potentially find the <strong>same answer</strong> as i already did.</p>



<p>We need to <strong>consider</strong> the <strong>different </strong>aspects, or the different <strong>roles </strong>here:</p>



<ul class="wp-block-list"><li>the <strong>customer</strong>, <strong>ordering </strong>the software</li><li>a <strong>developer </strong>actually <strong>creating </strong>that piece of application</li><li>the <strong>users using </strong>that software</li></ul>



<h2 class="wp-block-heading" id="how-bad-software-is-created-the-roles">How bad software is created – the roles</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-a-webshop-Customer-and-Developer-role.png"><img decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-a-webshop-Customer-and-Developer-role.png" alt="Hacking a webshop - Customer and Developer role" class="wp-image-7517" title="Hacking a webshop - Customer and Developer role"/></a><figcaption>Hacking a webshop &#8211; Customer and Developer role</figcaption></figure>



<p><strong>When thinking about</strong> that <strong>bad software</strong> which is actually <strong>vulnerable </strong>to a hacker, we have to <strong>consider </strong>the involved <strong>roles</strong>.</p>



<p>As i <strong>already mentioned</strong> above, there are <strong>3 roles involved</strong>, but <strong>one </strong>isn&#8217;t really responsible in the process itself, so..</p>



<p><strong>For sure</strong>, this <strong>also depends on the type of project</strong> and if theres something like a special beta phase, etc.</p>



<p>Let&#8217;s have <strong>a basic look</strong> at <strong>those roles </strong>and see what we can like expect or take into consideration.</p>



<h3 class="wp-block-heading" id="an-end-user"><a href="https://emojiterra.com/de/stehende-person/">&#x1f9cd;</a> An end user</h3>



<figure class="wp-block-image size-full is-resized"><a href="https://robbelroot.de/wp-content/uploads/2022/01/How-developers-imagine-the-end-user.gif"><img decoding="async" src="https://robbelroot.de/wp-content/uploads/2022/01/How-developers-imagine-the-end-user.gif" alt="How developers imagine the end user" class="wp-image-7525" width="345" height="194" title="How developers imagine the end user"/></a><figcaption>How developers imagine the end user</figcaption></figure>



<p>The <strong>end user can</strong> like <strong>report </strong>some <strong>problems </strong>he found, <strong>but </strong>for <strong>security thingys</strong>, this <strong>mostly won&#8217;t</strong> be the case.</p>



<p>You <strong>can&#8217;t expect a normal user</strong> to actually tell you about your security.</p>



<p>He <strong>won&#8217;t get in touch</strong> in a (any) way, where he <strong>could </strong>really understand <strong>or judge </strong>that thing.</p>



<p><strong>Obviously </strong>it <strong>isn&#8217;t his responsibility</strong> either, so forget about that as quick as possible!</p>



<p>You <strong>can be glad</strong>, <strong>if</strong> an end <strong>user </strong>actually <strong>takes </strong>the <strong>time </strong>to report a problem he faced.</p>



<p>This is great, because you then have the nice <strong>chance</strong> <strong>to </strong>actually <strong>fix </strong>that.</p>



<p><strong>End users</strong> just <strong>want one thing</strong>, or well we could say 3 things – u<strong>se </strong>your god damn (sorry) <strong>app </strong>as:</p>



<ul class="wp-block-list"><li><strong>easy</strong></li><li><strong>intuitive</strong></li><li>and <strong>bug free</strong></li></ul>



<p>as possible – full stop!</p>



<p>So if that happens to you, <strong>be glad your customer did that</strong> and <strong>give </strong>him some <strong>treat</strong>!</p>



<p>In the past <strong>i</strong> pretty much <strong>contacted every company </strong>where i faced some problem by email.</p>



<p><strong>Some of them</strong> were <strong>nice </strong>and gave like some sort of bonus, <strong>some of them</strong> were <strong>ignorant.</strong></p>



<p>There even were <strong>some </strong>companies, where they just <strong>got pissed</strong> and argued, but well..</p>



<p><strong>Don&#8217;t be</strong> that <strong>last kind </strong>of company!</p>



<h3 class="wp-block-heading" id="the-devs-customer"><a href="https://emojipedia.org/money-with-wings/">&#x1f4b8;</a> The (devs) customer</h3>



<figure class="wp-block-image size-full is-resized is-style-default"><a href="https://robbelroot.de/wp-content/uploads/2022/01/The-developers-customer.jpg"><img loading="lazy" decoding="async" src="https://robbelroot.de/wp-content/uploads/2022/01/The-developers-customer.jpg" alt="The developers customer" class="wp-image-7531" width="320" height="183" title="The developers customer"/></a><figcaption>The developers customer</figcaption></figure>



<p><strong>Now </strong>we are getting to the <strong>first interesting role</strong> as this one probably <strong>made </strong>this whole <strong>situation start</strong>.</p>



<p>There is <strong>one guy</strong> or even a whole company <strong>with a plan</strong> of a software (hopefully they have a plan..).</p>



<p>They may want to outsource that software due to missing time inside the original team.</p>



<p>It <strong>could also be</strong> another type of <strong>person </strong>– like a private one – which <strong>has </strong>an <strong>idea</strong>.</p>



<p>In a <strong>typical scenario</strong>, the <strong>problem </strong>we are discussing here is <strong>mostly faced</strong>, <strong>when hiring </strong>a (maybe) unexperienced freelancer.</p>



<p>As I have seen it in my past a lot as well, this <strong>also counts for</strong> like <strong>small agencies</strong>.</p>



<p><strong>Even if </strong>most persons think, that about <strong>everything is the developers fault</strong>, theres more to consider.</p>



<p>Especially he <strong>customer has a chance to control</strong> this process and the <strong>outcoming quality</strong> as well.</p>



<p>Why/How? Well, let me do <strong>one quick example</strong>:</p>



<p><strong>If you want a ferrari</strong> and you want to &#8222;vroom, vroom&#8220;, then <strong>you will</strong> <strong>have to pay for that</strong>.</p>



<p>The <strong>problem </strong>here <strong>with &#8222;little&#8220; customers</strong> is, that they commonly want that big &#8222;Amazony&#8220; application.</p>



<p><strong>All </strong>the <strong>possibilities </strong>and <strong>strengths </strong>and more, but they <strong>only want to pay for like a basic</strong> &#8222;add, edit, delete, list&#8220;-<strong>thingy</strong>.</p>



<p><strong>Furthermore </strong>this <strong>also </strong>sometimes <strong>applies to &#8222;bigger&#8220; companies</strong>, as they <strong>want to save</strong> money as well..</p>



<p><strong>Obviously that won&#8217;t work</strong>..</p>



<h2 class="wp-block-heading" id="developer-developing-firm"><a href="https://emojiterra.com/man-technologist/">&#x1f468;&#x200d;&#x1f4bb;</a> Developer (developing firm)</h2>



<figure class="wp-block-image size-full is-resized"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Software-Developer-working-Hacking-a-webshop.jpg"><img loading="lazy" decoding="async" src="https://robbelroot.de/wp-content/uploads/2022/01/Software-Developer-working-Hacking-a-webshop.jpg" alt="Software Developer working - Hacking a webshop" class="wp-image-7607" width="320" height="214" title="Software Developer working - Hacking a webshop"/></a><figcaption>Software Developer working &#8211; Hacking a webshop</figcaption></figure>



<p>The <strong>last role</strong> is likely to be the <strong>most responsible one</strong>, as <strong>important </strong>and <strong>fundamental tasks </strong>lie on its shoulders.</p>



<p>However most projects start <strong>with </strong>the actual <strong>contact from </strong>the <strong>developers to </strong>the <strong>customer</strong>.</p>



<p>This can be done by like some <strong>freelancing platform</strong>, <strong>creating </strong>the <strong>basic </strong>&#8222;<strong>frame</strong>&#8220; around that project.</p>



<p>You can believe me when i say, that <strong>at this point</strong> there can already be <strong>so many things going wrong</strong>.</p>



<p>I&#8217;m talking about <strong>budget</strong>, <strong>milestones</strong>, <strong>communication </strong>between the different parties, the <strong>final deadline</strong> and <strong>more</strong>..</p>



<p>But i think that&#8217;s <strong>part of another big story</strong>, so I&#8217;ll just continue..</p>



<p><strong>Going over </strong>the <strong>experience </strong>of the working <strong>team</strong>, <strong>next to </strong>the experience and <strong>tools of </strong>the <strong>individual developer</strong>.</p>



<p>The <strong>vulnerable spot</strong> that you will see in a moment, is <strong>mostly created by inexperienced</strong> devs.</p>



<p>For sure, such <strong>big mistakes</strong> can also be created through <strong>being close to a deadline</strong> and whatsoever reason.</p>



<p>I mean this <strong>won&#8217;t be any excuse</strong>, because:</p>



<ul class="wp-block-list"><li>either you <strong>have that budget</strong> you need to accomplish the work</li><li>or you&#8217;ve <strong>told the client</strong>, that this is <strong>not realistic</strong> and therfore <strong>won&#8217;t work</strong></li></ul>



<h2 class="wp-block-heading" id="jumping-in-the-code-of-hacking-a-webshop">Jumping in the code of hacking a webshop</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Webshop-hack-thumbnail.png"><img loading="lazy" decoding="async" width="1920" height="1080" src="https://robbelroot.de/wp-content/uploads/2022/01/Webshop-hack-thumbnail.png" alt="Hacking a webshop – Thumbnail" class="wp-image-7611" title="Hacking a webshop – Thumbnail"/></a><figcaption>Hacking a webshop – Thumbnail</figcaption></figure>



<p><strong>Before </strong>we actually <strong>start talking about the code</strong> behind, I would <strong>recommend downloading </strong>the <strong>code</strong>.</p>



<p>To do so, <strong>go to the bottom</strong> of the page and download that <strong><a href="https://bit.ly/hacking-a-webshop-download" target="_blank" rel="noreferrer noopener">&#8222;crapshop.zip&#8220; file</a></strong>, <strong>or just</strong> the link <strong>here</strong>!</p>



<p><strong>Extract </strong>the containing <strong>project folder</strong> to a location of your desire <strong>and </strong>we are like <strong>ready to go</strong>.</p>



<h3 class="wp-block-heading" id="prolog">Prolog</h3>



<p><strong>Keep in mind</strong> that our <strong>focus </strong>in this blog post <strong>is </strong>to actually <strong>understand and hack</strong> the crappy webshop itself.</p>



<p>So I pretty much <strong>won&#8217;t use time on explaining</strong> how to setup the <strong>Slim web application</strong> (API), or the concepts.</p>



<p>I <strong>will concentrate on</strong> the specific web api <strong>route and </strong>the process of <strong>adding a product to</strong> our <strong>cart</strong>.</p>



<p>Please <strong>also </strong>keep in mind, that there are <strong>so many</strong> other <strong>things which could be improved</strong>.</p>



<p>I just <strong>tried to come up with a quick</strong>, usable <strong>example</strong>, <strong>nothing more</strong>, so..</p>



<h3 class="wp-block-heading" id="prerequisites">Prerequisites</h3>



<p><strong>Before </strong>you are <strong>able to </strong>start or <strong>execute </strong>the code, you <strong>should have some tools</strong> ready:</p>



<ul class="wp-block-list"><li>The used package manager <strong>composer</strong> (<strong><a href="https://getcomposer.org/" target="_blank" rel="noreferrer noopener">weblink to composer</a></strong>)</li><li>A code editor like <strong><a href="https://code.visualstudio.com/" target="_blank" rel="noreferrer noopener">Visual Studio Code</a></strong></li><li><strong>Installed PHP binaries</strong> e. g. through WinNMP or XAMPP, or raw..</li></ul>



<h3 class="wp-block-heading" id="installing-dependencies-with-composer">Installing dependencies with composer</h3>



<p>In the <strong>first step</strong> you <strong>need to</strong> use the composer package manager to <strong>install dependencies</strong>.</p>



<p>You can <strong>do so by opening the project folder</strong> <strong>in </strong>like a Visual Studio Code <strong>terminal</strong>, or the normal console.</p>



<p>Then go ahead and <strong>execute the following command to install</strong> the <strong>dependencies</strong>:</p>



<pre class="wp-block-code"><code>composer install</code></pre>



<h3 class="wp-block-heading" id="starting-the-app">Starting the app</h3>



<p><strong>After everything</strong> is <strong>installed </strong>successfully you can <strong>start the app using</strong> the native PHP server.</p>



<p>To <strong>run that native PHP server</strong> you can execute this command here:</p>



<pre class="wp-block-code"><code>php -S localhost:8000 public/index.php</code></pre>



<p>It <strong>will </strong>basically <strong>start the server</strong> at the &#8222;public/index.php&#8220; location, with &#8222;localhost&#8220; as host and listening port 8000.</p>



<p>After that, visit &#8222;<strong>https://localhost:8000</strong>&#8220; in your favourite browser and you will see the webshop starting page:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-a-webshop-starting-page.png"><img loading="lazy" decoding="async" width="1229" height="574" src="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-a-webshop-starting-page.png" alt="Hacking a webshop starting page" class="wp-image-7634" title="Hacking a webshop starting page"/></a><figcaption>Hacking a webshop starting page</figcaption></figure>



<h3 class="wp-block-heading" id="a-little-product-search-page">A little product search page</h3>



<p>After you have started the server, you can <strong>now navigate to the product search page</strong>.</p>



<p>Do so by <strong>clicking th</strong>e &#8222;Products&#8220;-link and you will see a basic <strong>page with listed products</strong>.</p>



<p><strong>Just for fun</strong> I&#8217;ve implemented a little <strong>search functionality</strong>, but this <strong>isn&#8217;t really necessary</strong> here.</p>



<p><strong>Let&#8217;s see what happens</strong>, if you <strong>click on</strong> that &#8222;add to cart&#8220;-<strong>button </strong>on the listing page:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Clicking-the-add-to-cart-button-inside-our-hacky-webshop-example.png"><img loading="lazy" decoding="async" width="1273" height="949" src="https://robbelroot.de/wp-content/uploads/2022/01/Clicking-the-add-to-cart-button-inside-our-hacky-webshop-example.png" alt="Clicking the add to cart button inside our hacky webshop example" class="wp-image-7640" title="Clicking the add to cart button inside our hacky webshop example"/></a><figcaption>Clicking the add to cart button inside our hacky webshop example</figcaption></figure>



<p>As you can see there is <strong>a POST request being executed to our backend </strong>at &#8222;/api/cart/add-product&#8220;.</p>



<h3 class="wp-block-heading" id="the-clientside-code">The clientside code</h3>



<p>Let&#8217;s take a <strong>look at the code which triggered the request</strong> (you can find it in &#8222;public/js/page_products.js&#8220;):</p>



<pre class="EnlighterJSRAW" data-enlighter-language="js" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="page_products.js" data-enlighter-group="">document.addEventListener('click', function (e) {
  if (e.target.classList.contains('btnAddToCart')) {
    addProductToCart(e.target);
  }
});

function addProductToCart(btnAddToCart) {
  var id = parseInt(btnAddToCart.dataset.id);
  var price = parseFloat(btnAddToCart.dataset.price);
  var xhr = new XMLHttpRequest();
  xhr.open("POST", '/api/cart/add-product', true);
  xhr.setRequestHeader('Content-Type', 'application/json');
  // xhr.onload = function () {
  //   location.reload();
  // };
  xhr.send(JSON.stringify({
    id,
    price,
  }));
}</pre>



<p>There isn&#8217;t much more going on than <strong>registering that click-callback</strong> <strong>on </strong>the <strong>document </strong>and reacting to that.</p>



<p><strong>If</strong> an element with our &#8222;.<strong>btnAddToCart</strong>&#8222;-class <strong>is clicked</strong>, we respond to that by <strong>executing</strong> the &#8222;addProductToCart&#8220;-<strong>function</strong>.</p>



<p><strong>The function</strong> itself <strong>will pull</strong> the <strong>id and the price</strong> from the corresponding &#8222;data&#8220;-attribute.</p>



<p>After that, it <strong>will send a new</strong> &#8222;XMLHttpRequest&#8220; <strong>to the server</strong> and that&#8217;s it.</p>



<p><strong>If</strong> you <strong>want to refresh</strong> the page after doing so, you can <strong>uncomment the lines</strong> with &#8222;onload&#8220;.</p>



<p>I&#8217;ve <strong>omitted it on purpose</strong> as this <strong>will </strong>mostly <strong>clear the network history</strong> and you won&#8217;t be able to see the request. </p>



<h3 class="wp-block-heading" id="the-dangerous-web-api-endpoint">The dangerous web api endpoint</h3>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Dangerous-web-api-hacking-a-webshop.jpg"><img loading="lazy" decoding="async" width="1280" height="640" src="https://robbelroot.de/wp-content/uploads/2022/01/Dangerous-web-api-hacking-a-webshop.jpg" alt="Dangerous web api - hacking a webshop" class="wp-image-7675" title="Dangerous web api - hacking a webshop"/></a><figcaption>Dangerous web api &#8211; hacking a webshop</figcaption></figure>



<p><strong>After </strong>explaining the <strong>client code</strong> which has been executed above, we will <strong>now focus on the server</strong> side.</p>



<p><strong>You may</strong> have already <strong>guessed the problem</strong> in our case, but <strong>let&#8217;s dive deeper</strong> anyways.</p>



<p>Go ahead, <strong>step into your code editor</strong> and <strong>open </strong>the &#8222;<strong>src/Controller/CartController.php</strong>&#8222;-file.</p>



<p><strong>When </strong>you have the <strong>file ready</strong>, <strong>focus on the </strong>&#8222;addProduct&#8220;-function, which represents the corresponding endpoint.</p>



<h3 class="wp-block-heading" id="the-code-explained">The code explained</h3>



<p>In the <strong>first two lines</strong>, we will <strong>pull the json contents</strong> sent by javascript:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    $json = $request->getBody();
    $data = json_decode($json, true);</pre>



<p><strong>Then </strong>we&#8217;re <strong>checking</strong>, <strong>if</strong> the needed <strong>data </strong>– product id and price – have been <strong>provided</strong>.</p>



<p><strong>If</strong> those are <strong>not present</strong>, <strong>we </strong>will <strong>respond with </strong>a nice <strong>400 Http response status</strong>, which means &#8222;bad request&#8220;.</p>



<p><strong>Additionally </strong>there will be some c<strong>ode identifying what</strong> the actual <strong>problem </strong>was:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    if (!array_key_exists('id', $data)) {
      return $response
        ->withJson([ 'code' => 'ID_MISSING' ], 400);
    }

    if (!array_key_exists('price', $data)) {
      return $response
        ->withJson([ 'code' => 'PRICE_MISSING' ], 400);
    }</pre>



<p>Next we are fetching and parsing the id, to check if it&#8217;s kinda correct, so like above &#8222;0&#8220;.</p>



<p>Sure this <strong>could be done better</strong>, <strong>but </strong>this is <strong>enough </strong>for this purpose..</p>



<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    $id = intval($data['id']);
    if ($id &lt;= 0) {
      return $response
        ->withJson([ 'code' => 'INVALID_ID' ], 400);
    }</pre>



<p>After that, we are <strong>fetching </strong>the <strong>product information</strong> from our small &#8222;ProductService&#8220;-class.</p>



<p>This <strong>enables </strong>us <strong>checking</strong>, <strong>if</strong> that <strong>product is </strong>actually a product <strong>from our</strong> &#8222;database&#8220;.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    $product = $this->productService->getProductById($id);
    if (!$product) {
      return $response
        ->withJson([ 'code' => 'PRODUCT_NOT_FOUND' ], 404);
    }</pre>



<p><strong>NOW </strong>the <strong>important </strong>and dangerous <strong>part</strong> starts, which is <strong>accepting the price from the client</strong> side.</p>



<p><strong>Later I&#8217;ll sum up how to correctly</strong> work with that price <strong>and what</strong> you should also take into <strong>consideration</strong>.</p>



<p>I mean I added the small thingy, that we are <strong>at least checking</strong>, <strong>that </strong>the <strong>price can&#8217;t be negative</strong>, so &#8222;it&#8217;s something&#8220;.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    $price = floatval($data['price']);
    if ($price &lt;= 0) {
      return $response
        ->withJson([ 'code' => 'INVALID_PRICE' ], 400);
    }</pre>



<p><strong>Then we are doing</strong> some <strong>basic cart stuff</strong> like fetching the cart from the session (which could also be done by database).</p>



<p>We are also <strong>checking if the product has already been added</strong> to that cart.</p>



<p><strong>If</strong> it has been already added, we just <strong>increment</strong> this <strong>quantity </strong>for now, <strong>if not</strong>, it&#8217;s <strong>added in general</strong>.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    $cart = $this->session->get('cart') ?? [];

    $alreadyExists = null;
    foreach ($cart as $key => $value) {
      $item = $cart[$key];
      if ($item['id'] === $id &amp;&amp; $item['price'] === $price) {
        $alreadyExists = $key;
        break;
      }
    }

    if ($alreadyExists !== null) {
      $cart[$alreadyExists]['quantity'] = $cart[$alreadyExists]['quantity'] + 1;
    } else {
      $cart[] = [
        'id' => $id,
        'title' => $product['title'],
        'thumbnail' => $product['thumbnail'],
        'quantity' => 1,
        'price' => $price,
      ];
    }</pre>



<p><strong>In </strong>the <strong>last step</strong> we are just <strong>setting the new value for</strong> our <strong>cart </strong>inside the session <strong>and </strong>we are <strong>returning a response</strong> to the client.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    $this->session->set('cart', $cart);

    return $response;</pre>



<h2 class="wp-block-heading" id="manipulating-that-request-hacking-a-webshop">Manipulating that request – hacking a webshop</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Manipulating-the-request-attacking-the-api.jpg"><img loading="lazy" decoding="async" width="1280" height="736" src="https://robbelroot.de/wp-content/uploads/2022/01/Manipulating-the-request-attacking-the-api.jpg" alt="Manipulating the request attacking the api" class="wp-image-7678" title="Manipulating the request attacking the api"/></a><figcaption>Manipulating the request attacking the api</figcaption></figure>



<p>It&#8217;s <strong>now time</strong> <strong>to </strong>get to the final point of <strong>creating</strong> our <strong>own version of that request</strong>.</p>



<p>To work on that <strong>we need to analyse the request being sent</strong> and provide our own data.</p>



<p><strong>Then </strong>we need to <strong>re-send that request</strong> with our own data <strong>being accepted by the server</strong>.</p>



<p>The <strong>easiest way</strong> to do so <strong>is</strong> by <strong>opening</strong> that <strong>network tab</strong> of the webbrowser console, again.</p>



<h3 class="wp-block-heading" id="opening-the-browsers-developer-tools">Opening the browsers developer tools</h3>



<p><strong>Visit </strong>the <strong>product list page</strong> once again and <strong>open the browser console</strong> with F12.</p>



<p><strong>Go to</strong> the <strong>network tab</strong> and then <strong>execute the code</strong> by clicking that &#8222;<strong>add to cart</strong>&#8222;-button.</p>



<p><strong>Now </strong>you could <strong>inspect the request</strong> itself by just left clicking it:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Inspecting-the-add-product-api-request.png"><img loading="lazy" decoding="async" width="879" height="403" src="https://robbelroot.de/wp-content/uploads/2022/01/Inspecting-the-add-product-api-request.png" alt="Inspecting the add product api request" class="wp-image-7681" title="Inspecting the add product api request"/></a><figcaption>Inspecting the add product api request</figcaption></figure>



<p><strong>We </strong>already <strong>know </strong>which <strong>data </strong>is <strong>send</strong>, <strong>therefore </strong>we <strong>don&#8217;t</strong> really need to <strong>inspect </strong>the &#8222;<strong>payload</strong>&#8222;-tab to get an idea.</p>



<p><strong>Now </strong>the easiest way to test a custom request is, to <strong>right click that &#8222;add-product&#8220;</strong> on the left, which opens a context menu.</p>



<p><strong>There </strong>you can <strong>select </strong>the &#8222;<strong>Copy</strong>&#8220; and &#8222;<strong>Copy as fetch</strong>&#8220; items – to <strong>copy the fetch instructions into your clipboard</strong>.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Copying-the-web-api-request-as-fetch.png"><img loading="lazy" decoding="async" width="541" height="503" src="https://robbelroot.de/wp-content/uploads/2022/01/Copying-the-web-api-request-as-fetch.png" alt="Copying the web api request as fetch" class="wp-image-7686" title="Copying the web api request as fetch"/></a><figcaption>Copying the web api request as fetch</figcaption></figure>



<p><strong>Now</strong>, in the <strong>final step</strong>, you can then <strong>copy the clipboard</strong> contents <strong>to </strong>your &#8222;<strong>Console</strong>&#8222;-tab.</p>



<p><strong>There </strong>you can actually <strong>make</strong> your <strong>custom changes</strong> like <strong>changing </strong>the <strong>product </strong>id which you want to put in your cart.</p>



<p>The <strong>most important thing</strong> here is, <strong>we can change the price</strong>, too!</p>



<h3 class="wp-block-heading" id="executing-with-manipulated-request-data">Executing with manipulated request data</h3>



<p>So <strong>go ahead</strong> and do something <strong>like this</strong> here:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Changing-the-request-body-creating-our-request.png"><img loading="lazy" decoding="async" width="667" height="388" src="https://robbelroot.de/wp-content/uploads/2022/01/Changing-the-request-body-creating-our-request.png" alt="Changing the request body creating our request" class="wp-image-7691" title="Changing the request body creating our request"/></a><figcaption>Changing the request body creating our request</figcaption></figure>



<p><strong>I changed</strong> the product <strong>id </strong>to &#8222;3&#8220; <strong>and </strong>the <strong>price </strong>to something low like &#8222;5&#8220;.</p>



<p><strong>Hit enter</strong> on your keyboard <strong>while</strong> the <strong>console is focused</strong> and the request will be executed.</p>



<p><strong>After that</strong> you can <strong>visit the cart</strong> and you will see the <strong>expensive item now</strong> as a <strong>very cheap</strong> one!</p>



<p><strong>In the end</strong>, <strong>this is</strong> how our <strong>final cart screen</strong> looks like:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Final-cart-screen-with-manipulated-price.png"><img loading="lazy" decoding="async" width="1279" height="817" src="https://robbelroot.de/wp-content/uploads/2022/01/Final-cart-screen-with-manipulated-price.png" alt="Final cart screen with manipulated price" class="wp-image-7696" title="Final cart screen with manipulated price"/></a><figcaption>Final cart screen with manipulated price</figcaption></figure>



<h2 class="wp-block-heading" id="conclusion-hacking-a-webshop">Conclusion – Hacking a webshop</h2>



<p>So <strong>at the end</strong> of this interesting blog post, i think <strong>we can agree on</strong> one thing: <strong>Never trust the client side</strong>!!</p>



<p><strong>For normal users</strong>, the client side may be the <strong>bright side of life</strong>, but <strong>not for us</strong> as <strong>developers</strong>!</p>



<p><strong>Next to many other things</strong> which could&#8217;ve been improved or being implemented at all, <strong>theres the dangerous main thing</strong>.</p>



<p>The <strong>product price gets send by the client and trusted by the server</strong>, which is (in mortal combat language) &#8222;fatality&#8220;!</p>



<p><strong>Instead of this</strong>, <strong>you should</strong> actually <strong>have </strong>some sort of <strong>dataset </strong>in your database, to <strong>pull the price</strong> at request.</p>



<p>The <strong>client saying</strong>: &#8222;<strong>I want that product</strong> in my cart&#8220; is <strong>not a problem</strong> at all.</p>



<p><strong>Next thing</strong> you should <strong>keep in mind</strong> when designing/creating such a type of thing also has to do with like pricing.</p>



<p><strong>Even if</strong> you <strong>pull </strong>that <strong>price from the database</strong> at the moment the customer puts it into the cart, <strong>think about changes</strong>.</p>



<p><strong>When some guy</strong> using like a CRM to <strong>change that price while</strong> a customer has the <strong>product inside its cart</strong>, that could also be a problem.</p>



<h2 class="wp-block-heading" id="downloads">Downloads</h2>



<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link" href="https://bit.ly/hacking-a-webshop-download" target="_blank" rel="noreferrer noopener">crapshop.zip</a></div>
</div>



<h2 class="wp-block-heading" id="related-posts">Related posts</h2>



<ul class="wp-block-list"><li><a href="https://robbelroot.de/blog/hacking-a-net-application/" target="_blank" rel="noreferrer noopener"><strong>Hacking a NET Application</strong></a></li></ul>
<p>Der Beitrag <a href="https://robbelroot.de/blog/hacking-a-webshop/">&#x1f575;&#xfe0f; Hacking a Webshop – don&#8217;t fall for this common trap!</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/hacking-a-webshop/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
	</channel>
</rss>
