• Stars
    star
    485
  • Rank 90,698 (Top 2 %)
  • Language
    JavaScript
  • License
    Apache License 2.0
  • Created almost 9 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Super vulnerable todo list application

Goof - Snyk's vulnerable demo app

Known Vulnerabilities

A vulnerable Node.js demo application, based on the Dreamers Lab tutorial.

Features

This vulnerable app includes the following capabilities to experiment with:

Running

mongod &

git clone https://github.com/snyk-labs/nodejs-goof
npm install
npm start

This will run Goof locally, using a local mongo on the default port and listening on port 3001 (http://localhost:3001)

Note: You have to use an old version of MongoDB version due to some of these old libraries' database server APIs. MongoDB 3 is known to work ok.

You can also run the MongoDB server individually via Docker, such as:

docker run --rm -p 27017:27017 mongo:3

Running with docker-compose

docker-compose up --build
docker-compose down

Heroku usage

Goof requires attaching a MongoLab service to be deployed as a Heroku app. That sets up the MONGOLAB_URI env var so everything after should just work.

CloudFoundry usage

Goof requires attaching a MongoLab service and naming it "goof-mongo" to be deployed on CloudFoundry. The code explicitly looks for credentials to that service.

Cleanup

To bulk delete the current list of TODO items from the DB run:

npm run cleanup

Exploiting the vulnerabilities

This app uses npm dependencies holding known vulnerabilities, as well as insecure code that introduces code-level vulnerabilities.

The exploits/ directory includes a series of steps to demonstrate each one.

Vulnerabilities in open source dependencies

Here are the exploitable vulnerable packages:

Vulnerabilities in code

  • Open Redirect
  • NoSQL Injection
  • Code Injection
  • Command execution
  • Cross-site Scripting (XSS)
  • Information exposure via Hardcoded values in code
  • Security misconfiguration exposes server information
  • Insecure protocol (HTTP) communication

Code injection

The page at /account_details is rendered as an Handlebars view.

The same view is used for both the GET request which shows the account details, as well as the form itself for a POST request which updates the account details. A so-called Server-side Rendering.

The form is completely functional. The way it works is, it receives the profile information from the req.body and passes it, as-is to the template. This however means, that the attacker is able to control a variable that flows directly from the request into the view template library.

You'd think that what's the worst that can happen because we use a validation to confirm the expected input, however the validation doesn't take into account a new field that can be added to the object, such as layout, which when passed to a template language, could lead to Local File Inclusion (Path Traversal) vulnerabilities. Here is a proof-of-concept showing it:

curl -X 'POST' --cookie c.txt --cookie-jar c.txt -H 'Content-Type: application/json' --data-binary '{"username": "[email protected]", "password": "SuperSecretPassword"}' 'http://localhost:3001/login'
curl -X 'POST' --cookie c.txt --cookie-jar c.txt -H 'Content-Type: application/json' --data-binary '{"email": "[email protected]", "firstname": "admin", "lastname": "admin", "country": "IL", "phone": "+972551234123",  "layout": "./../package.json"}' 'http://localhost:3001/account_details'

Actually, there's even another vulnerability in this code. The validator library that we use has several known regular expression denial of service vulnerabilities. One of them, is associated with the email regex, which if validated with the {allow_display_name: true} option then we can trigger a denial of service for this route:

curl -X 'POST' -H 'Content-Type: application/json' --data-binary "{\"email\": \"`seq -s "" -f "<" 100000`\"}" 'http://localhost:3001/account_details'

The validator.rtrim() sanitizer is also vulnerable, and we can use this to create a similar denial of service attack:

curl -X 'POST' -H 'Content-Type: application/json' --data-binary "{\"email\": \"[email protected]\", \"country\": \"nop\", \"phone\": \"0501234123\", \"lastname\": \"nop\", \"firstname\": \"`node -e 'console.log(" ".repeat(100000) + "!")'`\"}" 'http://localhost:3001/account_details'

NoSQL injection

A POST request to /login will allow for authentication and signing-in to the system as an administrator user. It works by exposing loginHandler as a controller in routes/index.js and uses a MongoDB database and the User.find() query to look up the user's details (email as a username and password). One issue is that it indeed stores passwords in plaintext and not hashing them. However, there are other issues in play here.

We can send a request with an incorrect password to see that we get a failed attempt

echo '{"username":"[email protected]", "password":"WrongPassword"}' | http --json $GOOF_HOST/login -v

And another request, as denoted with the following JSON request to sign-in as the admin user works as expected:

echo '{"username":"[email protected]", "password":"SuperSecretPassword"}' | http --json $GOOF_HOST/login -v

However, what if the password wasn't a string? what if it was an object? Why would an object be harmful or even considered an issue? Consider the following request:

echo '{"username": "[email protected]", "password": {"$gt": ""}}' | http --json $GOOF_HOST/login -v

We know the username, and we pass on what seems to be an object of some sort. That object structure is passed as-is to the password property and has a specific meaning to MongoDB - it uses the $gt operation which stands for greater than. So, we in essence tell MongoDB to match that username with any record that has a password that is greater than empty string which is bound to hit a record. This introduces the NoSQL Injection vector.

Open redirect

The /admin view introduces a redirectPage query path, as follows in the admin view:

<input type="hidden" name="redirectPage" value="<%- redirectPage %>" />

One fault here is that the redirectPage is rendered as raw HTML and not properly escaped, because it uses <%- > instead of <%= >. That itself, introduces a Cross-site Scripting (XSS) vulnerability via:

http://localhost:3001/login?redirectPage="><script>alert(1)</script>

To exploit the open redirect, simply provide a URL such as redirectPage=https://google.com which exploits the fact that the code doesn't enforce local URLs in index.js:72.

Hardcoded values - session information

The application initializes a cookie-based session on app.js:40 as follows:

app.use(session({
  secret: 'keyboard cat',
  name: 'connect.sid',
  cookie: { secure: true }
}))

As you can see, the session secret used to sign the session is a hardcoded sensitive information inside the code.

First attempt to fix it, can be to move it out to a config file such as:

module.exports = {
    cookieSecret: `keyboard cat`
}

And then require the configuration file and use it to initialize the session. However, that still maintains the secret information inside another file, and Snyk Code will warn you about it.

Another case we can discuss here in session management, is that the cookie setting is initialized with secure: true which means it will only be transmitted over HTTPS connections. However, there's no httpOnly flag set to true, which means that the default false value of it makes the cookie accessible via JavaScript. Snyk Code highlights this potential security misconfiguration so we can fix it. We can note that Snyk Code shows this as a quality information, and not as a security error.

Snyk Code will also find hardcoded secrets in source code that isn't part of the application logic, such as tests/ or examples/ folders. We have a case of that in this application with the tests/authentication.component.spec.js file. In the finding, Snyk Code will tag it as InTest, Tests, or Mock, which help us easily triage it and indeed ignore this finding as it isn't actually a case of information exposure.

Docker Image Scanning

The Dockerfile makes use of a base image (node:6-stretch) that is known to have system libraries with vulnerabilities.

To scan the image for vulnerabilities, run:

snyk test --docker node:6-stretch --file=Dockerfile

To monitor this image and receive alerts with Snyk:

snyk monitor --docker node:6-stretch

Runtime Alerts

Snyk provides the ability to monitor application runtime behavior and detect an invocation of a function is known to be vulnerable and used within open source dependencies that the application makes use of.

The agent is installed and initialized in app.js.

For the agent to report back to your snyk account on the vulnerabilities it detected it needs to know which project on Snyk to associate with the monitoring. Due to that, we need to provide it with the project id through an environment variable SNYK_PROJECT_ID

To run the Node.js app with runtime monitoring:

SNYK_PROJECT_ID=<PROJECT_ID> npm start

** The app will continue to work normally even if it's not provided a project id

Fixing the issues

To find these flaws in this application (and in your own apps), run:

npm install -g snyk
snyk wizard

In this application, the default snyk wizard answers will fix all the issues. When the wizard is done, restart the application and run the exploits again to confirm they are fixed.

More Repositories

1

awesome-log4shell

An Awesome List of Log4Shell resources to help you stay informed and secure! ๐Ÿ”’
222
star
2

exploit-workshop

A step by step workshop to exploit various vulnerabilities in Node.js and Java applications
156
star
3

java-goof

Java
89
star
4

pysnyk

A Python client for the Snyk API.
Python
87
star
5

snyk-cicd-integration-examples

Examples of integrating the Snyk CLI into a CI/CD system
Groovy
78
star
6

eslint-config-react-security

A ESLint configuration package for React developers who want to avoid security mistakes.
JavaScript
72
star
7

nodejs-docker-best-practices

Best practices to containerize Node.js web applications with Docker
JavaScript
64
star
8

kubernetes-goof

Kubernetes Stranger Danger
Shell
57
star
9

helm-snyk

Check images in your charts for vulnerabilities
TypeScript
41
star
10

snync

Mitigate security concerns of Dependency Confusion supply chain security risks
JavaScript
39
star
11

github-actions-scanner

Scans your Github Actions for security issues
JavaScript
34
star
12

modern-npm-package

An npm package for demonstration purposes using TypeScript to build for both the ECMAScript Module format (i.e. ESM or ES Module) and CommonJS Module format. It can be used in Node.js and browser applications.
TypeScript
32
star
13

docker-goof

A demo repo showcasing Snyk's Docker offering
Shell
27
star
14

nopp

Tiny helper to protect against Prototype Pollution vulnerabilities in your application regardless if they introduced in your own code or in 3rd-party code
JavaScript
25
star
15

snyk-scm-refresh

Keeps Snyk projects in sync with their associated Github repos
Python
24
star
16

php-goof

Snyk PHP Goof - A vulnerable PHP demo application
PHP
22
star
17

eslint-plugin-react-security

ESLint plugin with rules for finding security issues in React projects.
JavaScript
18
star
18

snyk-filter

Snyk filtering for SNYK CLI
JavaScript
15
star
19

snyk-tags-tool

CLI tool designed to manage tags and attributes at scale
Python
13
star
20

infrastructure-as-code-goof

HCL
12
star
21

snyk-deps-to-csv

retrieve all dependencies for all orgs in a group
JavaScript
10
star
22

snyk-bulk

Collection of docker entrypoints that facilitate snyk '--all-projects'-style bulk scanning
Java
9
star
23

snyk-chat-goof

Java
8
star
24

snyk-cloud-aws-importer

Tool to automate the importing of an AWS Organization in to Snyk Cloud
Python
7
star
25

netlify-plugin-snyk

A Snyk's netlify build plugin
JavaScript
7
star
26

rules_snyk

bazel (starlark) rules to test and monitor targets for vulnerabilities in external open source dependencies
Starlark
7
star
27

container-breaking-in-goof

Docker goof version of breaking into a container
JavaScript
6
star
28

snyk-user-sync-tool

sync user org memberships from an external source into Snyk
TypeScript
6
star
29

serverless-gcf-goof

A vulnerable Serverless application deployed on GCF
JavaScript
6
star
30

frontend-security-bingo

Frontend Security Bingo
Vue
6
star
31

snyk-api-client

A Node.js client for the Snyk API
TypeScript
6
star
32

pdfjs-vuln-demo

This project is intended to serve as a proof of concept to demonstrate exploiting the vulnerability in the PDF.js (pdfjs-dist) library reported in CVE-2024-4367
Astro
6
star
33

npq

safely install packages with npm or yarn by auditing them as part of your install process
JavaScript
4
star
34

serverless-spring-goof

Java
4
star
35

iac-scan-examples

Some basic Infrastructure-as-Code examples to accompany blogs
HCL
4
star
36

snyk-cr-monitor

monitor your on-premise Artifactory container images for vulnerabilities in Snyk
JavaScript
4
star
37

VSCode-Instant-markdown-vuln

This repo is to demonstrate the file traversal hack which uses a vulnerability in the Instant Markdown VSCode extension
Hack
4
star
38

snyk-request-manager

Queue based request manager to throttle and retry interaction with Snyk API endpoints
TypeScript
3
star
39

ctf-101

Python
3
star
40

snyk-repo-diff

Simple tool to generate a list of repositories that aren't in Snyk
Python
3
star
41

snyk-api-ts-client

Snyk API Typescript client generated from API Blueprints
TypeScript
3
star
42

snyk-issues-to-html

Export Snyk report issues to HTML
HTML
3
star
43

snyk-issues-to-csv

Python
3
star
44

node-ipc-goof

JavaScript
3
star
45

azure-repos-contributors-count

Count the number of contributing developers to an Azure Repos organization in the last 90 days
Python
3
star
46

CVE-2023-50164-POC

Java
3
star
47

snyk-scm-mapper

A way to ensure your GitHub Repos are monitored by Snyk
Python
3
star
48

terraform-goof

A demo repo showcasing Snyk's IAC offering for terraform
HCL
3
star
49

snyk-threadfix

Show open source vulnerabilities from Snyk in ThreadFix
Python
2
star
50

snyk-repo-issue-tracker

Python
2
star
51

bazel2snyk

test and monitor bazel targets for vulnerabilities in external open source dependencies, uses bazel query output
Python
2
star
52

snyk-bulk-action-scripts

Python scripts for bulk modification of Organization settings
Python
2
star
53

snyk-transitive-ignore

For Snyk CLI, ignore all issues introduced through a given set of dependencies
JavaScript
2
star
54

heroku-goof

CSS
2
star
55

iac-to-cloud-example-custom-rules

Snyk IaC to Cloud Custom Rules is in beta. This repository contains example custom rules to help you get started.
Open Policy Agent
2
star
56

sbom-to-snyk-depgraph

convert cyclone dx sbom to snyk depgraph and test or monitor it for open source issues
Python
1
star
57

snyk-scan.sh

monorepo utility wrapper for Snyk CLI
Shell
1
star
58

event-app-node-grpc

A demonstration application for building a secure API using gRPC in Node.js
JavaScript
1
star
59

cypress-security-vulnerability-test

1
star
60

actions

A set of custom GitHub actions providing additional functionality when integrating Snyk into your Actions CI/CD pipeline.
1
star
61

snyk-java-jar-test

Test Java JARs using Snyk
Python
1
star
62

apply-custom-role

Apply Custom Role to a list of users in each Org of a Group
JavaScript
1
star
63

ksnyk

An experimental tool for working with Snyk and Kubernetes
Python
1
star
64

snyk-migrate-to-github-app

Python
1
star
65

snyk-container-remediation

Go
1
star