Common stuff for all my devices' web server pages: css, login, log, ipv4, ipv6, firmware update, clock, reset info etc.

Dependents:   oldheating gps motorhome heating

Security

A password has to be set whenever there has been a software reset. Resets following faults or power on do not require a new password as the hash is restored from the RTC GPREG register.

The password is not saved on the device; instead a 32 bit hash of the password is saved. It would take 2^31 attempts to brute force the password: this could be done in under a month if an attempt were possible every millisecond. To prevent this a 200 ms delay is introduced in the reply to the login form, that gives a more reasonable 13 years to brute force the password.

Once the password is accepted a random session id is created. This is 36 bit to give six base 64 characters but without an extra delay. If an attempt could be made every ms then this would still take over a year to brute force.

The most likely attack would to use a dictionary with, say, 10 million entries against the password which would still take 20 days to do.

Committer:
andrewboyson
Date:
Mon Feb 01 13:24:09 2021 +0000
Revision:
157:57bd76aa5e97
Parent:
156:005785e4740e
Child:
158:80441390de93
Updated firmware page to align bytes sent.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 50:edd44fe9320f 1 'use strict';
andrewboyson 50:edd44fe9320f 2
andrewboyson 48:4e678727c4c9 3 var file;
andrewboyson 46:1822fdbe6c0c 4 var xhr;
andrewboyson 48:4e678727c4c9 5
andrewboyson 55:3d1e52e3e9b7 6 function logUpload(text)
andrewboyson 50:edd44fe9320f 7 {
andrewboyson 55:3d1e52e3e9b7 8 document.getElementById('uploadresult').textContent = text;
andrewboyson 50:edd44fe9320f 9 }
andrewboyson 55:3d1e52e3e9b7 10 function xhrUploadResponse()
andrewboyson 51:c605b2794b44 11 {
andrewboyson 51:c605b2794b44 12 var topics = xhr.responseText.split('\f');
andrewboyson 55:3d1e52e3e9b7 13 logUpload(topics[0]);
andrewboyson 51:c605b2794b44 14 if (topics.length > 1) document.getElementById('list').textContent = topics[1];
andrewboyson 51:c605b2794b44 15 }
andrewboyson 55:3d1e52e3e9b7 16 function xhrUploadOnLoad()
andrewboyson 46:1822fdbe6c0c 17 {
andrewboyson 55:3d1e52e3e9b7 18 if (xhr.status == 200) xhrUploadResponse();
andrewboyson 55:3d1e52e3e9b7 19 else logUpload('Upload failed');
andrewboyson 46:1822fdbe6c0c 20 }
andrewboyson 55:3d1e52e3e9b7 21 function xhrUploadOnError()
andrewboyson 46:1822fdbe6c0c 22 {
andrewboyson 55:3d1e52e3e9b7 23 logUpload('Upload error');
andrewboyson 46:1822fdbe6c0c 24 }
andrewboyson 149:24365666d28d 25 function xhrUploadProgress(e)
andrewboyson 149:24365666d28d 26 {
andrewboyson 152:edbf676b08ca 27 logUpload('Uploading...\r\n' +
andrewboyson 157:57bd76aa5e97 28 'Total ' + e.total + ' bytes\r\n' +
andrewboyson 157:57bd76aa5e97 29 'Sent ' + e.loaded.toString().padStart(e.total.toString().length, ' ') + ' bytes');
andrewboyson 149:24365666d28d 30 }
andrewboyson 156:005785e4740e 31 function xhrUploadComplete(e)
andrewboyson 156:005785e4740e 32 {
andrewboyson 156:005785e4740e 33 logUpload('Saving ' + e.loaded + ' bytes...');
andrewboyson 156:005785e4740e 34 }
andrewboyson 55:3d1e52e3e9b7 35 function xhrUploadStart()
andrewboyson 48:4e678727c4c9 36 {
andrewboyson 149:24365666d28d 37 logUpload('Upload starting...');
andrewboyson 48:4e678727c4c9 38
andrewboyson 48:4e678727c4c9 39 xhr = new XMLHttpRequest();
andrewboyson 48:4e678727c4c9 40
andrewboyson 55:3d1e52e3e9b7 41 xhr.onload = xhrUploadOnLoad;
andrewboyson 55:3d1e52e3e9b7 42 xhr.onerror = xhrUploadOnError;
andrewboyson 149:24365666d28d 43 xhr.upload.onprogress = xhrUploadProgress;
andrewboyson 156:005785e4740e 44 xhr.upload.onload = xhrUploadComplete;
andrewboyson 48:4e678727c4c9 45
andrewboyson 53:27d56a22a450 46 xhr.open('POST', '/firmware-ajax'); //Defaults to async=true
andrewboyson 48:4e678727c4c9 47 xhr.send(file);
andrewboyson 48:4e678727c4c9 48 }
andrewboyson 46:1822fdbe6c0c 49 function startUpload()
andrewboyson 46:1822fdbe6c0c 50 {
andrewboyson 46:1822fdbe6c0c 51 var fileInput = document.getElementById('fileInput');
andrewboyson 46:1822fdbe6c0c 52
andrewboyson 46:1822fdbe6c0c 53 if (fileInput.files.length == 0)
andrewboyson 46:1822fdbe6c0c 54 {
andrewboyson 55:3d1e52e3e9b7 55 logUpload('Please choose a file');
andrewboyson 46:1822fdbe6c0c 56 return;
andrewboyson 46:1822fdbe6c0c 57 }
andrewboyson 46:1822fdbe6c0c 58
andrewboyson 46:1822fdbe6c0c 59 if (fileInput.files.length > 1)
andrewboyson 46:1822fdbe6c0c 60 {
andrewboyson 55:3d1e52e3e9b7 61 logUpload('Please choose just one file');
andrewboyson 46:1822fdbe6c0c 62 return;
andrewboyson 46:1822fdbe6c0c 63 }
andrewboyson 48:4e678727c4c9 64
andrewboyson 48:4e678727c4c9 65 file = fileInput.files[0];
andrewboyson 47:cf7d4c34158e 66
andrewboyson 55:3d1e52e3e9b7 67 xhrUploadStart();
andrewboyson 55:3d1e52e3e9b7 68 }
andrewboyson 55:3d1e52e3e9b7 69 function logRestart(text)
andrewboyson 55:3d1e52e3e9b7 70 {
andrewboyson 55:3d1e52e3e9b7 71 document.getElementById('restartresult').textContent = text;
andrewboyson 55:3d1e52e3e9b7 72 }
andrewboyson 55:3d1e52e3e9b7 73 function redirect()
andrewboyson 55:3d1e52e3e9b7 74 {
andrewboyson 55:3d1e52e3e9b7 75 location.href = '/firmware';
andrewboyson 55:3d1e52e3e9b7 76 }
andrewboyson 55:3d1e52e3e9b7 77 function xhrRestartOnLoad()
andrewboyson 55:3d1e52e3e9b7 78 {
andrewboyson 55:3d1e52e3e9b7 79 if (xhr.status == 200) logRestart('Restart should never have returned');
andrewboyson 55:3d1e52e3e9b7 80 else logRestart('Restart failed');
andrewboyson 48:4e678727c4c9 81 }
andrewboyson 55:3d1e52e3e9b7 82 function xhrRestartStart()
andrewboyson 55:3d1e52e3e9b7 83 {
andrewboyson 55:3d1e52e3e9b7 84 logRestart('Restarting...');
andrewboyson 55:3d1e52e3e9b7 85
andrewboyson 55:3d1e52e3e9b7 86 xhr = new XMLHttpRequest();
andrewboyson 55:3d1e52e3e9b7 87
andrewboyson 55:3d1e52e3e9b7 88 xhr.onload = xhrRestartOnLoad;
andrewboyson 55:3d1e52e3e9b7 89
andrewboyson 55:3d1e52e3e9b7 90 xhr.open('GET', '/firmware-ajax?restart='); //Defaults to async=true
andrewboyson 55:3d1e52e3e9b7 91 xhr.send();
andrewboyson 55:3d1e52e3e9b7 92
andrewboyson 55:3d1e52e3e9b7 93 setTimeout(redirect, 2000);
andrewboyson 55:3d1e52e3e9b7 94 }
andrewboyson 55:3d1e52e3e9b7 95 function restart()
andrewboyson 55:3d1e52e3e9b7 96 {
andrewboyson 55:3d1e52e3e9b7 97 xhrRestartStart();
andrewboyson 55:3d1e52e3e9b7 98 }
andrewboyson 114:900e33dfa460 99