Leek

Prompt

Our favorite grocery store allegedly has a vulnerability, can you replicate it?

Walk-Through

This challenge requires you to identify a vulnerability in the web application that leaks (pun intended) some sensitive information from the server.

To start, let’s inspect the web server for any interesting files or behavior. Generally, we recommend trying to access /robots.txt to see if there are any files that the web developer does not want search engines to index, which is usually a good sign of something interesting to probe. However, /robots.txt returns a 404 on this web server so there is nothing for us to look at there.

Now let’s try to probe the server’s normal functionality to see how it’s communicating information between the browser and the remote web server. To do this, open the browser developer tools, usually the F12 key, or right click and choose Inspect Element, and switch to the network tab to monitor the network connections.

We can try to add an item to the grocery list, let’s say we add an item called “Banana” and observe the HTTP request that’s made to the server.

Once you’ve made the request, it’ll show up in the developer tools “Network” tab, click on the “add” request to view details and switch to the “Payload” tab to view the request body.

Website after sending a request for “Banana”
Website after sending a request for “Banana”

So here we see that our request to add a “Banana” to the grocery list was encoded using JSON as { content: "Banana" }. Now let’s also inspect the response body by switching to the “Preview” tab.

The initial request was sent out as a
The initial request was sent out as a String type, but the response type is a Buffer

Now this response is peculiar. We can assume this buffer response is potentially a node.js Buffer type (this can be validated by inspecting the “Headers” tab to identify that the remote server is using a node.js runtime as it is powered by Express.js which is a node.js library).

On the documentation page for Buffer, we find that there are a lot of deprecated methods which could be potential attack vectors for us.

Deprecated constructors for Buffer in the node.js documentations
Deprecated constructors for Buffer in the node.js documentations

We can try to send some data to the server to see if we can generate some unexpected behavior. From the documentation here, we know that Buffers accept at least 5 different kinds of types:

  • Array - standard JavaScript array object
  • ArrayBuffer - more modern array object used to store a “byte array”
  • Buffer - same type as itself
  • Number - as indicated by the size constructor
  • String - which is what we see with the request we just made above

The intuition here would be to try to craft requests using these different types to see how the server responds and if it responds with unexpected data. You can craft the request using your favorite HTTP request tool like BurpSuite, ZAP, or curl.

This walkthrough will demonstrate with using curl as the example as we can actually have the browser developer tools duplicate the request and construct the curl command for us by using the “Copy as cURL” menu option.

image

Once copied, you can paste it into a bash/zsh terminal and tweak the JSON payload.

curl 'https://[hostname]/add' \
  -H 'Accept: */*' \
  -H 'Content-Type: application/json'
  --data-raw '{"content":"chicken"}' 
Some headers were removed to maintain simplicity for the example. Don’t forget that your payload needs to include the web URL for this challenge.

You may eventually try a numeric payload like the following:

curl 'https://[hostname]/add' \
  -H 'Accept: */*' \
  -H 'Content-Type: application/json' \
  --data-raw '{"content":"10"}' 
Some headers were removed to maintain simplicity for the example. Don’t forget that your payload needs to include the web URL for this challenge.

Try removing the double quotes around the content you want to send in the request.

Before

  --data-raw '{"content":"10"}'
Double quotes persist. This is read by Node.js Buffer as a string containing the number ten (10).

After

--data-raw '{"content": 10}'
Double quotes are removed. This is read by Node.js Buffer as 10 bytes.

Once you make this request and refresh the page, you’ll see a partial flag which indicates that you’re somehow leaking sensitive server-side information with the numeric request. Notice how only ten characters of the fourteen character flag are shown:

Partial flag being leaked
Partial flag being leaked

This happens because the numeric request instantiates a new Buffer and the web developer in this case may be using an unsafe constructor to instantiate the Buffer which leads to discarded server-side memory being unintentionally incorporated into the new Buffer. This is known as a type confusion vulnerability. Instead of seeing the number “10” needing to be displayed, the server sees a request to allocate 10 bytes of raw memory and returns whatever is in heap space. This is why we only see ten characters of the flag.

As we only got a partial flag, we can increase the Buffer size to perhaps 100 to see if we can leak a full flag out.

💡
Pro-tip for software developers: always sanitize/zero out any buffers you send to the client-side as will contain uninitialized/discarded memory which may contain secret keys or other sensitive data!

Useful resources for this challenge:

Questions

What is the flag?

©️ 2026 Cyber Skyline. All Rights Reserved. Unauthorized reproduction or distribution of this copyrighted work is illegal.