Browse Source

Added basic authetication and CSRF check to websocket requests

fastled
Xose Pérez 8 years ago
parent
commit
4de83916d1
3 changed files with 58 additions and 10 deletions
  1. +10
    -4
      code/html/custom.js
  2. +12
    -3
      code/src/defaults.h
  3. +36
    -3
      code/src/web.ino

+ 10
- 4
code/html/custom.js View File

@ -1,8 +1,9 @@
var websock;
var csrf;
function doUpdate() {
var data = $("#formSave").serializeArray();
websock.send(JSON.stringify({'config': data}));
websock.send(JSON.stringify({'csrf': csrf, 'config': data}));
$(".powExpected").val(0);
return false;
}
@ -10,19 +11,19 @@ function doUpdate() {
function doReset() {
var response = window.confirm("Are you sure you want to reset the device?");
if (response == false) return false;
websock.send(JSON.stringify({'action': 'reset'}));
websock.send(JSON.stringify({'csrf': csrf, 'action': 'reset'}));
return false;
}
function doReconnect() {
var response = window.confirm("Are you sure you want to disconnect from the current WIFI network?");
if (response == false) return false;
websock.send(JSON.stringify({'action': 'reconnect'}));
websock.send(JSON.stringify({'csrf': csrf, 'action': 'reconnect'}));
return false;
}
function doToggle(element, value) {
websock.send(JSON.stringify({'action': value ? 'on' : 'off'}));
websock.send(JSON.stringify({'csrf': csrf, 'action': value ? 'on' : 'off'}));
return false;
}
@ -40,6 +41,11 @@ function toggleMenu() {
function processData(data) {
// CSRF
if ("csrf" in data) {
csrf = data.csrf;
}
// messages
if ("message" in data) {
window.alert(data.message);


+ 12
- 3
code/src/defaults.h View File

@ -68,13 +68,22 @@
// -----------------------------------------------------------------------------
// WIFI
// WIFI & WEB
// -----------------------------------------------------------------------------
#define WIFI_RECONNECT_INTERVAL 300000
#define WIFI_MAX_NETWORKS 3
#define AP_PASS "fibonacci"
#define OTA_PASS "fibonacci"
#define ADMIN_PASS "fibonacci"
#define AP_PASS ADMIN_PASS
#define HTTP_USERNAME "admin"
#define HTTP_PASSWORD ADMIN_PASS
#define CSRF_BUFFER_SIZE 5
// -----------------------------------------------------------------------------
// OTA & NOFUSS
// -----------------------------------------------------------------------------
#define OTA_PASS ADMIN_PASS
#define OTA_PORT 8266
#define NOFUSS_SERVER "http://192.168.1.100"
#define NOFUSS_INTERVAL 3600000


+ 36
- 3
code/src/web.ino View File

@ -10,14 +10,16 @@ Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ESP8266mDNS.h>
#include "FS.h"
#include <FS.h>
#include <Hash.h>
#include "AsyncJson.h"
#include <AsyncJson.h>
#include <ArduinoJson.h>
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
unsigned long _csrf[CSRF_BUFFER_SIZE];
// -----------------------------------------------------------------------------
// WEBSOCKETS
// -----------------------------------------------------------------------------
@ -43,6 +45,16 @@ void webSocketParse(uint32_t client_id, uint8_t * payload, size_t length) {
return;
}
// CSRF
unsigned long csrf = 0;
if (root.containsKey("csrf")) csrf = root["csrf"];
if (csrf != _csrf[client_id % CSRF_BUFFER_SIZE]) {
DEBUG_MSG("[WEBSOCKET] CSRF check failed\n");
ws.text(client_id, "{\"message\": \"Session expired, please reload page...\"}");
return;
}
// Check actions
if (root.containsKey("action")) {
@ -144,6 +156,12 @@ void webSocketStart(uint32_t client_id) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
// CSRF
if (client_id < CSRF_BUFFER_SIZE) {
_csrf[client_id] = random(0x7fffffff);
}
root["csrf"] = _csrf[client_id % CSRF_BUFFER_SIZE];
root["app"] = app;
root["manufacturer"] = String(MANUFACTURER);
root["chipid"] = chipid;
@ -222,14 +240,29 @@ void webSocketEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsE
// WEBSERVER
// -----------------------------------------------------------------------------
void onHome(AsyncWebServerRequest *request){
String password = getSetting("httpPassword", HTTP_PASSWORD);
char httpPassword[password.length() + 1];
password.toCharArray(httpPassword, password.length() + 1);
Serial.println(httpPassword);
if (!request->authenticate(HTTP_USERNAME, httpPassword)) {
return request->requestAuthentication();
}
request->send(SPIFFS, "/index.html");
}
void webSetup() {
// Setup websocket plugin
ws.onEvent(webSocketEvent);
server.addHandler(&ws);
// Serve home
server.on("/", HTTP_GET, onHome);
server.on("/index.html", HTTP_GET, onHome);
// Serve static files
server.serveStatic("/", SPIFFS, "/").setDefaultFile("/index.html");
server.serveStatic("/", SPIFFS, "/");
// 404
server.onNotFound([](AsyncWebServerRequest *request){


Loading…
Cancel
Save