You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A vulnerable Node.js demo application, based on the [Dreamers Lab tutorial](http://dreamerslab.com/blog/en/write-a-todo-list-with-express-and-mongodb/)
5
6
6
7
## Features
7
8
8
-
This vulnerable app includes the following capabilities to experiment with:
9
-
*[Exploitable packages](#exploiting-the-vulnerabilities) with known vulnerabilities
10
-
*[Docker Image Scanning](#docker-image-scanning) for base images with known vulnerabilities in system libraries
11
-
*[Runtime alerts](#runtime-alerts) for detecting an invocation of vulnerable functions in open source dependencies
9
+
This vulnerable apassa includes the following capabilities to experiment with:
10
+
11
+
-[Exploitable packages](#exploiting-the-vulnerabilities) with known vulnerabilities
12
+
-[Docker Image Scanning](#docker-image-scanning) for base images with known vulnerabilities in system libraries
13
+
-[Runtime alerts](#runtime-alerts) for detecting an invocation of vulnerable functions in open source dependencies
This will run Goof locally, using a local mongo on the default port and listening on port 3001 (http://localhost:3001)
22
26
23
-
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.
27
+
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.
24
28
25
29
You can also run the MongoDB server individually via Docker, such as:
26
30
@@ -29,21 +33,26 @@ docker run --rm -p 27017:27017 mongo:3
29
33
```
30
34
31
35
## Running with docker-compose
36
+
32
37
```bash
33
38
docker-compose up --build
34
39
docker-compose down
35
40
```
36
41
37
42
### Heroku usage
38
-
Goof requires attaching a MongoLab service to be deployed as a Heroku app.
39
-
That sets up the MONGOLAB_URI env var so everything after should just work.
43
+
44
+
Goof requires attaching a MongoLab service to be deployed as a Heroku app.
45
+
That sets up the MONGOLAB_URI env var so everything after should just work.
40
46
41
47
### CloudFoundry usage
42
-
Goof requires attaching a MongoLab service and naming it "goof-mongo" to be deployed on CloudFoundry.
43
-
The code explicitly looks for credentials to that service.
48
+
49
+
Goof requires attaching a MongoLab service and naming it "goof-mongo" to be deployed on CloudFoundry.
50
+
The code explicitly looks for credentials to that service.
44
51
45
52
### Cleanup
53
+
46
54
To bulk delete the current list of TODO items from the DB run:
55
+
47
56
```bash
48
57
npm run cleanup
49
58
```
@@ -58,21 +67,22 @@ The `exploits/` directory includes a series of steps to demonstrate each one.
58
67
### Vulnerabilities in open source dependencies
59
68
60
69
Here are the exploitable vulnerable packages:
70
+
61
71
-[Mongoose - Buffer Memory Exposure](https://snyk.io/vuln/npm:mongoose:20160116) - requires a version <= Node.js 8. For the exploit demo purposes, one can update the Dockerfile `node` base image to use `FROM node:6-stretch`.
A POST request to `/login` will allow for authentication and signing-in to the system as an administrator user.
111
121
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.
112
122
113
-
114
123
We can send a request with an incorrect password to see that we get a failed attempt
@@ -151,20 +163,23 @@ To exploit the open redirect, simply provide a URL such as `redirectPage=https:/
151
163
The application initializes a cookie-based session on `app.js:40` as follows:
152
164
153
165
```js
154
-
app.use(session({
155
-
secret:'keyboard cat',
156
-
name:'connect.sid',
157
-
cookie: { secure:true }
158
-
}))
166
+
app.use(
167
+
session({
168
+
secret:"keyboard cat",
169
+
name:"connect.sid",
170
+
cookie: { secure:true },
171
+
})
172
+
);
159
173
```
160
174
161
175
As you can see, the session `secret` used to sign the session is a hardcoded sensitive information inside the code.
162
176
163
177
First attempt to fix it, can be to move it out to a config file such as:
178
+
164
179
```js
165
180
module.exports= {
166
-
cookieSecret:`keyboard cat`
167
-
}
181
+
cookieSecret:`keyboard cat`,
182
+
};
168
183
```
169
184
170
185
And then require the configuration file and use it to initialize the session.
@@ -179,11 +194,13 @@ Snyk Code will also find hardcoded secrets in source code that isn't part of the
179
194
The `Dockerfile` makes use of a base image (`node:6-stretch`) that is known to have system libraries with vulnerabilities.
180
195
181
196
To scan the image for vulnerabilities, run:
197
+
182
198
```bash
183
199
snyk test --docker node:6-stretch --file=Dockerfile
184
200
```
185
201
186
202
To monitor this image and receive alerts with Snyk:
203
+
187
204
```bash
188
205
snyk monitor --docker node:6-stretch
189
206
```
@@ -197,14 +214,17 @@ The agent is installed and initialized in [app.js](./app.js#L5).
197
214
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`
198
215
199
216
To run the Node.js app with runtime monitoring:
217
+
200
218
```bash
201
219
SNYK_PROJECT_ID=<PROJECT_ID> npm start
202
220
```
203
221
204
-
** The app will continue to work normally even if it's not provided a project id
222
+
\*\* The app will continue to work normally even if it's not provided a project id
205
223
206
224
## Fixing the issues
225
+
207
226
To find these flaws in this application (and in your own apps), run:
0 commit comments