Lab: Multi endpoint race conditions

Predict a potential collision

After starting the exercise, the shop should look like the screenshot. We click on the ‘My account’ link at the top right to log in to the application.

In the login form, we enter wiener as the user name and peter as the password and click on the ‘Log in’ button

Our account should look like this.

We now switch to the shop and buy a gift card. We study the shopping process in general and the shopping basket mechanism, in particular the restrictions that determine what we can order. To go to the shop, click on the ‘Home’ link in the top right-hand corner.

In the shop, we now search for the gift card and click on ‘View details’.

If we scroll down on the product page of the gift card, we see the button ‘Add to cart’, which we have to click in order to add the gift card to the shopping basket.

Now we switch to our shopping basket and complete the order. To do this, we click on the shopping basket symbol at the top right.

We finalise the order by clicking on the ‘Place order’ button.

The gift card code is now stored in our account.

We now switch to the Burp Suite and open the Burp Proxy there. In the Burp Proxy we open the ‘HTTP history’ tab. Here we now search for all requests that are related to the shopping basket. This would be the request POST /cart, which adds products to the shopping basket, and the request POST /cart/checkout, which transmits our order. If we add a new gift card to our shopping basket, the request GET /cart appears in the ‘HTTP history’.

We now send the request GET /cart to Burp Repeater. To do this, we move the mouse over the request and press the right mouse button. A context menu appears in which we select the option ‘Send to Repeater’.

In the Burp Repeater, we now send the request once without the Cookie header and then with the Cookie header. As you can see, the shopping basket is empty if we send the request without the Cookie header.

If we now send the request with a Cookie header, our shopping basket is no longer empty. From this we can conclude that the status of the shopping basket is saved in our session on the server side. In addition, all transactions in the shopping basket are linked to our session ID or the associated user ID. This means that there is a risk of a collision.

Please note that the transmission and confirmation of a successful order takes place within a single enquiry/response cycle. Please note that there may be a certain period of time between the validation of the order and its final confirmation. During this period, it is possible to add further items to the order after the server has checked the available credit.

Benchmark the behavior

Now we send the two requests POST /cart and POST /cart/checkout to the Burp Repeater. To do this, right-click on the request and click on the ‘Send to Repeater’ option in the context menu.

In the Burp Repeater, we now create a tab group with the two requests. To do this, we click on the ‘plus sign’ next to the tabs.

In the menu, we now select ‘Create tab group’.

We now enter the name of the tab group, in this exercise we select ‘RC-3’. When selecting the selection of tabs, we need the two tabs of the requests POST /cart and POST /cart/checkout.

The tab group should now look like this.

If you have any questions about tab groups, the Burp Suite documentation can help. Now we want to send the requests sequentially via a connection. To do this, we need to click on the ‘Arrow down’ to the right of the ‘Send’ button.

The following menu appears:

The ‘Send’ button now looks like this:

We now send the tab group a few times in succession and pay attention to the response times. As we can see, the response to the first request takes significantly longer than the second request.

You can find more information about sequential sending via a connection in the Burp Suite documentation.

We now switch to the Burp Proxy and search for the first request to the application. This request should have the form GET / HTTP/1.1.

We now send the request to Burp Repeater and add it to the ‘RC-3’ tab group. To do this, we move the mouse over the request and press the right mouse button, in the context menu we select the option ‘Send to Repeater’.

In Burp Repeater, move the mouse over the tab name and click the right mouse button.

In the context menu, select the option "Add to tab group".

In this example, we add the request to the tab group ‘RC-3’.

The request to the application must be the first request within the tab group. To do this, simply click on the tab, hold down the mouse button and drag it to the beginning. The tab group should now look like this.

We now click the ‘Send group (single connection)’ button. If we now look at the times that our responses took, we can see that the first response took the longest. The following screenshots show the times of the three responses:

The first request therefore ‘warmed up’ the connection so that the other two requests could be completed more quickly. It can be deduced from this that this delay is caused by the backend network architecture and not by the respective processing time of the individual endpoints.

In Burp Repeater, we now remove the first request from our tab group. The request has the first line GET / HTTP/2. We move the mouse over the tab and click the right mouse button, in the context menu we select the option ‘Remove tab from group’.

We then check our shopping basket to see if there is still a gift card in it. If this is not the case, we need to add a gift card to the shopping basket. To do this, we click ‘Home’ > ‘View details’ (for the ‘Gift card’ product) > ‘Add to cart’. We then switch to the Burp Repeater and open the request POST /cart HTTP/2 in our tab group. There we change the productId in the body of the request to 1. This Id belongs to the product Lightweight ‘l33t’ Leather Jacket. We send these requests again by clicking on the ‘Send group (single connection)’ button. We receive an HTTP/2 303 See Other in response. If we look at the value of the Location header, we see the following value /cart?err=INSUFFICIENT_FUNDS. Our balance is therefore not sufficient to purchase the jacket.

Prove the concept

We now switch to our shopping basket and remove the jacket and add a gift card. Our shopping basket should now look like this:

In Burp Repeater we change the way the requests are sent to the application, from sequentially over a connection to in parallel.

The button now looks like this.

You can find more information about parallel sending in the Burp Suite documentation. Now we click on the button ‘Send group (parallel)’ and check the response to the request POST /cart/checkout HTTP/2. If we receive an HTTP/2 200 OK response and we have bought the jacket, the exercise is solved. However, this may take a few tries. If you receive the response /cart?err=INSUFFICIENT_FUNDS, then the attempt was not successful. Remove the jacket from the shopping basket, add a gift card to the basket and try again.

This concludes the exercise.

Video solution

Last updated