insecure webapp example: by changing uid in url, user logged in can view others' profile.
log in as bob
logged in
bob can view his profile @ http://localhost:8080/profile/1
change url to http://localhost:8080/profile/2
bob can't get other's profile
log bob out, and log in as tom
tom can view his profile @ http://localhost:8080/profile/2
send put request with bob's credential to view tom's profile using postman
denied by server
//app.js
const jwtFunc = require('./jwt')
const express = require('express')
const app = express()
const port = 8080
const path = require('path');
var bodyParser = require('body-parser')
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
// serve your css as static
app.use(express.static(__dirname + '/public'));
var mysql = require('mysql')
var connection = mysql.createConnection({
host: '127.0.0.1',
user: 'dvwa',
password: 'p@ssw0rd',
database: 'sqlinjection'
})
connection.connect()
//render html
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.get('/', function (req, res) {
res.render('index');
});
app.post('/', function (req, res) {
var name = req.body.name;
var password = req.body.password;
connection.query('SELECT * from login where name = ? and password = ?', [name, password], function (err, rows, fields) {
if (err) throw err
if (rows.length > 0) {
jwtFunc.createToken(req, res)
}
if (rows.length > 1) {
throw 'find duplicate users in database'
}
res.render('index', { data: rows, token: req.token });
})
});
app.post('/profile/:id', function (req, res) {
jwtFunc.verifyToken(req, res)
if (req.message == 'success') {
connection.query('SELECT * from login where name = ? and id = ?', [req.name, req.params.id], function (err, rows, fields) {
if (err) throw err
if (rows.length == 0) {
return res.render('profile', { message: 'not authorized to view other\'s profile' });
}
if (rows.length > 1) {
throw 'find duplicate users in database'
}
return res.render('profile', { data: rows[0] });
})
}
else {
return res.render('profile', { message: req.message });
}
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
------------------------
//jwt.js
const jwtFunc = require('./jwt.js')
var jwt = require('jsonwebtoken');
var secret = 'secret'
function verifyToken(req, res) {
var token = req.body.tokenInput;
if (!token) {
req.message = 'No token provided.';
return
}
jwt.verify(token, secret, function (err, decoded) {
if (err) {
req.message = err.toString();
return
}
// if everything good, save to request for use in other routes
req.name = decoded.name
req.message = 'success'
return
});
}
function createToken(req, res) {
var name = req.body.name;
var token = jwt.sign({ name: name }, secret, {
expiresIn: 300 // expires in 5 min
});
req.token = token
}
module.exports = { verifyToken, createToken };
-----------------------------------
//index.ejs
<html>
<head>
<%- include('partials/header'); %>
</head>
<body>
<div style="margin:100px;">
<%- include('partials/nav'); %>
<div class="jumbotron" style="padding:40px;">
<form action="\" method="get" id='logoutForm'>
<div id='loginName'></div>
<input type="submit" value="log out" onclick="localStorage.removeItem('token');
localStorage.removeItem('user');" />
</form>
<form method="post" onsubmit="getProfile(event)" id='profileForm'>
<input type="hidden" id='tokenInput' name='tokenInput'>
<input type="submit" value="view profile" />
</form>
<form action="\" method="post" id='loginForm'>
<table>
<tr>
<td><label>Name</label></td>
<td><input type="text" name="name" /></td>
</tr>
<tr>
<td><label>Password</label></td>
<td><input type="password" name="password" /></td>
</tr>
</table><br />
<input type="submit" value="log in" />
</form>
<% if (locals.data) { %>
<% if (data.length==0) {%>
<div>login failed</div>
<% }else{ %>
<script>
var token = '<%= token %>';
var user = '<%= data[0].name %>'
var id = '<%= data[0].id %>'
localStorage.setItem('token', token);
localStorage.setItem('user', user)
localStorage.setItem('id', id)
</script>
<% } %>
<% } %>
<script>
var token = localStorage.getItem('token');
if (token) {
document.getElementById('loginForm').style.display = 'none';
document.getElementById('logoutForm').style.display = 'block';
document.getElementById('profileForm').style.display = 'block';
document.getElementById('loginName').innerHTML = 'welcome ' + localStorage.getItem('user');
}
else {
document.getElementById('loginForm').style.display = 'block';
document.getElementById('logoutForm').style.display = 'none';
document.getElementById('profileForm').style.display = 'none';
}
function getProfile(e) {
var id = localStorage.getItem('id');
var url = 'http://localhost:8080/profile/' + id;
document.getElementById('profileForm').action = url;
document.getElementById('tokenInput').value = token;
}
</script>
</div>
</div>
</body>
</html>
---------------------------
//profile.ejs
<html>
<head>
<%- include('partials/header'); %>
</head>
<body>
<div style="margin:100px;">
<%- include('partials/nav'); %>
<div class="jumbotron" style="padding:40px;">
<h3>profile</h3>
<% if (locals.message) { %>
message: <%= message %>
<% } %>
<% if (locals.data) { %>
<ul>
<li>id: <%= data.id %>
</li>
<li>name: <%= data.name %>
</li>
<li>password: <%= data.password %>
</li>
</ul>
<% } %>
<form action="\" method="get">
<input type="submit" value="home" />
</form>
</div>
</div>
</body>
</html>
reference:
No comments:
Post a Comment