added time drift slider

This commit is contained in:
Walter Oggioni
2024-02-15 11:08:45 +08:00
parent 32464094a3
commit 745b3135b3
3 changed files with 76 additions and 36 deletions

View File

@@ -177,20 +177,20 @@ def main():
prog='session-security-poc', prog='session-security-poc',
description='Program to demostrate improved user session security') description='Program to demostrate improved user session security')
parser.add_argument('--host', default='127.0.0.1') parser.add_argument('--host', default='127.0.0.1')
parser.add_argument('--port', default='8080') parser.add_argument('--port', default='1443')
parser.add_argument('--key-file') parser.add_argument('--key-file')
parser.add_argument('--cert-file') parser.add_argument('--cert-file')
parser.add_argument('--tls-self-signed', action='store_true') parser.add_argument('--disable-tls', action='store_true')
args = parser.parse_args(sys.argv[1:]) args = parser.parse_args(sys.argv[1:])
if args.tls_self_signed: if args.key_file and args.cert_file:
ssl_context = 'adhoc'
elif args.key_file and args.cert_file:
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain(certfile=args.cert_file, keyfile=args.key_file) ssl_context.load_cert_chain(certfile=args.cert_file, keyfile=args.key_file)
else: elif args.disable_tls:
ssl_context = None ssl_context = None
else:
ssl_context = 'adhoc'
app.run(host=args.host, port=args.port, ssl_context=ssl_context) app.run(host=args.host, port=args.port, ssl_context=ssl_context)

View File

@@ -4,12 +4,47 @@
<script src="js/sspoc.js" defer></script> <script src="js/sspoc.js" defer></script>
</head> </head>
<body> <body>
<div>
<table>
<thead>
<tr>
<td>Username</td>
<td>Password</td>
</tr>
</thead>
<tbody>
<tr>
<td>user1</td>
<td>password</td>
</tr>
<tr>
<td>user2</td>
<td>password</td>
</tr>
<tr>
<td>user3</td>
<td>password</td>
</tr>
<tr>
<td>user4</td>
<td>password</td>
</tr>
</tbody>
</table>
</div>
<form id="login-form"> <form id="login-form">
<label for="username">Username</label> <label for="username">Username</label>
<input id="username" type="text"> <input id="username" type="text"/>
<label for="password">Password</label> <label for="password">Password</label>
<input id="password" type="password"> <input id="password" type="password"/>
<button id="login-button" type="button">Login</button> <button id="login-button" type="button">Login</button>
</form> </form>
<div>
<form id="whoami-form">
<input id="time-drift-slider" type="range" min="-9000" max="+9000" step="100" value="0"/>
<label for="time-drift-slider">Time drift: <em>0 s</em></label>
<input id="whoami-button" type="button" value="whoami"/>
</form>
</div>
</body> </body>
</html> </html>

View File

@@ -71,6 +71,7 @@ loginButton.addEventListener('click', async evt => {
let paragraph = document.createElement('p'); let paragraph = document.createElement('p');
paragraph.textContent = await response.text(); paragraph.textContent = await response.text();
document.body.appendChild(paragraph); document.body.appendChild(paragraph);
setTimeout(() => document.body.removeChild(paragraph), 10000);
} }
const nonceHeader = response.headers.get('nonce'); const nonceHeader = response.headers.get('nonce');
const encryptedNonce = atob(nonceHeader); const encryptedNonce = atob(nonceHeader);
@@ -82,10 +83,10 @@ loginButton.addEventListener('click', async evt => {
}); });
}); });
async function computeToken() { async function computeToken(instant) {
if(nonce != null) { if(nonce != null) {
const crypto = window.crypto.subtle; const crypto = window.crypto.subtle;
const epochTick = Math.floor(new Date().getTime() / 3000); const epochTick = Math.floor(instant / 3000);
const data = concatenateUInt8Arrays(nonce, integerToBytes(epochTick, 8)); const data = concatenateUInt8Arrays(nonce, integerToBytes(epochTick, 8));
const hash = new Uint8Array(await crypto.digest("SHA-256", data)); const hash = new Uint8Array(await crypto.digest("SHA-256", data));
const token = btoa(Array.from(hash, byte => String.fromCharCode(byte)).join('')); const token = btoa(Array.from(hash, byte => String.fromCharCode(byte)).join(''));
@@ -95,15 +96,19 @@ async function computeToken() {
} }
} }
let div = document.createElement('div');
document.body.appendChild(div);
let whoamiButton = document.createElement('button'); const whoamiButton = document.getElementById('whoami-button');
whoamiButton.textContent = 'whoami' const whoamiForm = document.getElementById('whoami-form');
div.appendChild(whoamiButton); const timeDriftLabel = whoamiForm.querySelector("label em");
const timeDriftSlider = whoamiForm['time-drift-slider'];
timeDriftSlider.addEventListener('input', evt => {
timeDriftLabel.textContent = parseInt(evt.target.value) / 1000 + ' s';
});
whoamiButton.addEventListener('click', async evt => { whoamiButton.addEventListener('click', async evt => {
const token = await computeToken(); const drift = parseInt(timeDriftSlider.value);
const instant = new Date().getTime() + drift;
const token = await computeToken(instant);
let headers = {}; let headers = {};
if (token != null) { if (token != null) {
headers = { headers = {
@@ -117,27 +122,27 @@ whoamiButton.addEventListener('click', async evt => {
let paragraph = document.createElement('p'); let paragraph = document.createElement('p');
paragraph.textContent = text; paragraph.textContent = text;
document.body.appendChild(paragraph); document.body.appendChild(paragraph);
setTimeout(() => document.body.removeChild(paragraph), 10000);
}); });
}); });
let helloButton = document.createElement('button'); // const helloButton = document.createElement('button');
helloButton.textContent = 'hello' // helloButton.textContent = 'hello'
div.appendChild(helloButton);
helloButton.addEventListener('click', async evt => { // helloButton.addEventListener('click', async evt => {
const token = await computeToken(); // const token = await computeToken();
let headers = {}; // let headers = {};
if (token != null) { // if (token != null) {
headers = { // headers = {
'x-token': token // 'x-token': token
}; // };
} // }
fetch('api/hello', { // fetch('api/hello', {
method: 'GET', // method: 'GET',
headers // headers
}).then(response => response.text()).then(text => { // }).then(response => response.text()).then(text => {
let paragraph = document.createElement('p'); // let paragraph = document.createElement('p');
paragraph.textContent = text; // paragraph.textContent = text;
document.body.appendChild(paragraph); // document.body.appendChild(paragraph);
}); // });
}); // });