Skip to content

Commit 280735c

Browse files
author
kberg
committed
search api route
some signal handling for docker
1 parent 47dfa96 commit 280735c

11 files changed

+133
-12
lines changed

.dockerignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

Dockerfile

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM node:12.8-stretch
2+
3+
WORKDIR /app
4+
COPY . .
5+
RUN npm install --production
6+
ENV DEBUG=myapp:*
7+
EXPOSE 3000
8+
CMD ["node", "/app/bin/www"]
9+
#CMD ["npm", "run", "start"]

README.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Node Express Vulny
2+
3+
Hi I'm Vulny a modern web stack using the latest in Node/Express framework technology.
4+
I'm both sophisticated and naive all while using a best in class in web framework.
5+
6+
You should probably scan me with a web app vulnerability scanner.
7+
8+
### NPM
9+
```shell script
10+
npm install
11+
```
12+
13+
### Run
14+
```shell script
15+
DEBUG=myapp:* npm start
16+
```
17+
18+
### Build
19+
```shell script
20+
docker build -t stackhawk/nodeexpressvulny .
21+
```
22+
23+
### Run docker
24+
```shell script
25+
docker run --rm -p 9000:9000 --name nodeexpressvulny stackhawk/nodeexpressvulny
26+
```
27+
28+
### Do bad stuff
29+
* SQL Injection via search box. - `a%'; insert into items values (default, 'hacker item name','bad bad description'); select * from ITEMS where name like '%banan`
30+
* Cross Site Scripting via search box. - `<script>alert('hey guy');</script>`

app.js

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ var logger = require('morgan');
66

77
var indexRouter = require('./routes/index');
88
var searchRouter = require('./routes/search');
9+
var apiRouter = require('./routes/api');
910

1011
var app = express();
1112

@@ -21,6 +22,7 @@ app.use(express.static(path.join(__dirname, 'public')));
2122

2223
app.use('/', indexRouter);
2324
app.use('/search', searchRouter);
25+
app.use('/api', apiRouter);
2426

2527
// catch 404 and forward to error handler
2628
app.use(function(req, res, next) {

bin/www

+24
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,27 @@ function onListening() {
8888
: 'port ' + addr.port;
8989
debug('Listening on ' + bind);
9090
}
91+
92+
// Borrowed from https://medium.com/@becintec/building-graceful-node-applications-in-docker-4d2cd4d5d392
93+
// The signals we want to handle
94+
// NOTE: although it is tempting, the SIGKILL signal (9) cannot be intercepted and handled
95+
var signals = {
96+
'SIGHUP': 1,
97+
'SIGINT': 2,
98+
'SIGTERM': 15
99+
};
100+
// Do any necessary shutdown logic for our application here
101+
const shutdown = (signal, value) => {
102+
console.log("shutdown!");
103+
server.close(() => {
104+
console.log(`server stopped by ${signal} with value ${value}`);
105+
process.exit(128 + value);
106+
});
107+
};
108+
// Create a listener for each of the signals that we want to handle
109+
Object.keys(signals).forEach((signal) => {
110+
process.on(signal, () => {
111+
console.log(`process received a ${signal} signal`);
112+
shutdown(signal, signals[signal]);
113+
});
114+
});

package-lock.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"cookie-parser": "~1.4.4",
1010
"debug": "~2.6.9",
1111
"express": "~4.16.1",
12+
"express-list-endpoints": "^4.0.1",
1213
"http-errors": "~1.6.3",
1314
"morgan": "~1.9.1",
1415
"pug": "2.0.0-beta11",

routes/api.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const express = require('express');
2+
const router = express.Router();
3+
const searchService = require('../service/search');
4+
5+
router.get('/search', function (req, res, next) {
6+
7+
const searchText = req.query.searchText !== undefined ? req.query.searchText : '';
8+
console.log(req.query);
9+
console.log('search text: ' + searchText);
10+
searchService.searchByName(searchText, function (err, ret) {
11+
if (err) {
12+
res.json(err);
13+
} else {
14+
delete ret.searchText;
15+
res.json(ret);
16+
}
17+
});
18+
19+
});
20+
21+
module.exports = router;

routes/search.js

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
const express = require('express');
22
const router = express.Router();
3-
const sqlite3 = require('sqlite3').verbose();
4-
const db = new sqlite3.Database('./db/vulny.db');
3+
const searchService = require('../service/search');
54

65
/* GET search listing. */
76
router.get('/', function (req, res, next) {
@@ -10,21 +9,14 @@ router.get('/', function (req, res, next) {
109

1110
router.post('/', function (req, res, next) {
1211
const searchText = req.body.searchText;
13-
db.all("select id,name,description from item where name like '%" + searchText + "%'", [], function (err, rows) {
12+
13+
searchService.searchByName(searchText, function (err, ret) {
1414
if (err) {
15-
console.log('error ' + err);
1615
res.redirect('/search')
1716
} else {
18-
console.log(req.body);
19-
console.log('rows? ' + rows);
20-
console.log('got ' + rows.length + ' rows');
21-
const ret = {
22-
searchText: searchText,
23-
rows: rows
24-
};
2517
res.render('searchResult', ret)
2618
}
27-
})
19+
});
2820
});
2921

3022
module.exports = router;

service/search.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const sqlite3 = require('sqlite3').verbose();
2+
const db = new sqlite3.Database('./db/vulny.db');
3+
4+
const searchByName = function (searchText, cb) {
5+
6+
db.all("select id,name,description from item where name like '%" + searchText + "%'", [], function (err, rows) {
7+
//db.all("select id,name,description from item where name like '%?%'", [searchText], function (err, rows) {
8+
if (err) {
9+
console.log('error ' + err);
10+
cb(err);
11+
//res.redirect('/search')
12+
} else {
13+
//console.log(req.body);
14+
console.log('rows? ' + rows);
15+
console.log('got ' + rows.length + ' rows');
16+
const ret = {
17+
searchText: searchText,
18+
rows: rows
19+
};
20+
cb(null, ret);
21+
//res.render('searchResult', ret)
22+
}
23+
});
24+
25+
};
26+
27+
module.exports = {
28+
searchByName: searchByName
29+
};

stackhawk.yml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
app:
2+
host: ${APP_HOST:http://localhost:3000}
3+
scanType: ${SCAN_TYPE:api-scan}
4+
scanLevelConf: ${SCAN_LEVEL_CONF:}
5+
basePath: /api
6+
routes:
7+
- path: GET /search?searchText=string

0 commit comments

Comments
 (0)