ich will mal wieder das lästige Thema Sicherheit in der Haustechnik, hier speziell in IPS, aufgreifen.
Grundsätzlich kommt mir IPS mittlerweile sehr sicher vor; alle wichtigen Bereiche sind professionell zumindest mit einer Benutzer/Passwort-Authentifizierung geschützt und/oder verschlüsselt.
Bei Authentifizierung und Verschlüsselung geht es aber primär immer „nur“ darum, dass niemand Fremder volle Benutzerrechte erlangen kann oder sinnvolle Informationen aus der digitalen Kommunikation auslesen kann.
Mir ist in der Haustechnik aber wichtiger, dass niemand Fremder meine Türen und Garagentore öffnen kann
Auch möchte ich nicht, dass jemand meine Heizkörper voll aufdreht oder meine Klimaanlagen abschaltet.
Hier sehe ich das Problem der Replay-Attacken. Sobald jemand meine Kommunikation zu IPS mitschneiden kann, reicht es ihm, quasi empirisch zu ermitteln, dass das Kommando „&57zg!lfk6;“ die Türe öffnet. Es ist also völlig egal, nach welchem Algorithmus der vorgenannte String verschlüsselt wurde; er braucht nur „&57zg!lfk6;“ senden.
Kann mich hierzu mal jemand aufklären?
Bedienung übers WebFront: sollte SSL-verschlüsselt sein, das hilft. Ich weiß nicht, ob und wie hierbei Replay-Attacken ausgeschlossen sind
Webhook: hier sehe ich das größte Problem!
jegliche Form von (TCP-/UDP-)Sockets: sofern kein Challenge-/Response-Verfahren im IPS-Skript hinterlegt ist, ist auch hier die Gefahr groß?!
JSON, SOAP, Konsole?
Sollten eine oder mehrere der o.g. Punkte also anfällig für Replay-Attacken sein, muss ich mich darauf verlassen, dass niemand in der Netzwerk-Kommunikation auch nur mitschneiden kann. Das schließt Fernzugriffe ohne VPN völlig aus und auch die Sicherheit des internen LANs/WLANs muss dann „totsicher“ sein.
Das Thema Sicherheit ist durchaus sehr wichtig. Aber imho finde es wird manchmal auch ein wenig übertrieben alles Mögliche durch zudenken. Eine 100% Sicherheit gibt es nirgends im Leben das einzige was sicher ist der Tod früher oder später. Was betreibst Du denn im Alltag für einen Aufwand das Dir z.B. der Autoschlüssel nicht entwendet wird? Wie hoch hältst Du denn die Wahrscheinlichkeit das sich jemand vor die Tür stellt und versucht irgendwas mitzuschneiden?
1+2+4: Wenn du all das über HTTPS (=SSL) nutzt, bist du sicher. Wenn du den Connect Dienst verwendest, hast du auch ein „echtes“ und sicheres Zertifikat dabei. Ohne Aufwand. Ansonsten musst in IP-Symcon eine WebServer Instanz erstellen, ein Zertifikat für deine Domain kaufen, SSL aktivieren und alles korrekt einrichten (SSL), sodass das Schloss im Browser auch grün wird.
3: Diese Instanzen hängen nicht im Internet. Sollten Sie defintiv nicht! Das passiert im internen LAN. Und dort musst du alleine für Sicherheit sorgen. Oder falls es unsicher ist dafür sorgen, dass die „sicheren“ Geräte in einem VLAN sind, dass nur der IP-Symcon Server im Zugriff hat. Das ist Netzwerktechnik, an der wir nichts „rütteln“ können. Falls dieser Punkt übrigens ein Problem darstellt, hast du wahrscheinlich ein Budget für einen Netzwerk-Spezialisten. Im normalen zu Hause habe ich nur Leute im Netzwerk denen ich traue. Alle anderen haben nur Gast-Zugang zum Internet. Übrigens: Langsam aber sicher kommen Geräte auf den Markt die direkte Verschlüsselung bis zum Gateway und im Bus unterstützt. Siehe dazu KNX Secure. Aber die Preisklasse ist mehr als was jeder von uns ausgeben will
parey, danke für deine Ausführungen.
Ich habe mir das so ja schon fast gedacht, aber schön es bestätigt zu lesen
eigenes SSL-Zertifikat für meine Domain ist vorausgesetzt. Ist dabei der Webhook jedoch tatsächlich sicher? Hier laufen die „relevanten“ Dinge ja meist schon über den Request - also imho doch noch, bevor die SSL-Verbindung tatsächlich etabliert wurde?
Nein. Wenn in deinem Hook in der App ein HTTPS vor der URL steht, dann wird immer erst die Verschlüsselung aufgebaut bevor irgendwelche Daten durch die Leitung gehen. Lies dir mal ein paar Basics zu SSL Verschlüsselung an. Dann siehst du wann der echte Payload gesendet wird.
Webhooks auch andere Verzeichnisse im IPS Webfront ordner sind ja nicht wirklich gegen code injection etc. geschützt.
deshalb kommt in die PHP Files immer folgender Include rein bei mir, die von außen erreichbar sind:
include „hack_prevent.inc.php“
das je nach Verwendung angepasst werden kann:
Zeichen die erlaubt sind in variablen
maximale länge von variableninhalten
namen von post / get variablen die erlaubt sind
anzahl der aufrufe des scriptes / Ip adresse also zb. maximal 3 aurufe innerh. von 10 sekunden
passt irgend etwas nicht gib’s einenen fehler und das script bricht ab.
passt was nicht wird ein ERROR ausgegeben.
inhalt:
<?php
/* Hacking prevention Script version 1.0 by STELE -----------------------------------
This script protects your PHP Script regarding attacks
It checks all submitted variables (POST, GET, FILE) if there is suspicious
content.
You can customize the checks
As well you can define how much calls per IP in a specified period of time
are allowed.
(c) 2013
*/
//Activate or deactivate this Hacking prevention Script
$CONF["ACTIVE"] = true;
//Maximum allowed size for transmitted variable values
$CONF["MAXVARSIZE"] = 150;
//Allowed characters for variable values
$CONF["ALLOWEDCHARS"] = "" ;//ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜäöü1234567890.,-:"; // UNicode äöü auch in klein, da to upper nicht funktioniert
// Variables which are allowed for post and get and file trnasfers
$CONF["ALLOWEDVARS"] = Array("device",
"address",
"entry",
"id",
"latitude",
"name",
"longitude",
"date",
"test",
"minor",
"major",
"beaconUUID",
"radius");
// Check Post Variables
$CONF["CHECK_POST"] = true;
// Check GET Variables
$CONF["CHECK_GET"] = true;
// Check File Transfers
$CONF["CHECK_FILES"] = true;
// Period for IP Count attepts in seconds
$CONF["IP_REQUEST_PERIOD"] = 10;
// Number of attempts which are okay in above period.
$CONF["IP_REQUEST_COUNT"] = 3;
/*****************************************************************************/
$CONF["ALLOWEDCHARS"] = strtoupper($CONF["ALLOWEDCHARS"]);
$CONF["ALLOWEDCHARS"] = mbStringToArray($CONF["ALLOWEDCHARS"]);
if ($CONF["ACTIVE"]) {
// Check IP Timeouts ---------------------------------------------------
if($CONF["IP_REQUEST_PERIOD"] > 0){
$dir = "./hack_check_IPs";
if(!is_dir($dir))mkdir($dir);
$clientIP = $_SERVER["REMOTE_ADDR"];
$fileIP = $dir."/$clientIP.txt";
// counter hochsetzen und prüfen
if((time() - @filemtime("$dir/$clientIP.txt")) < $CONF["IP_REQUEST_PERIOD"]){
touch($fileIP);
$count = intval(file_get_contents($fileIP));
$count = $count + 1;
if($count >= $CONF["IP_REQUEST_COUNT"]){
touch($fileIP);
denied("TOO MANY ATTEMPTS");
}
file_put_contents($fileIP, $count);
} else {
file_put_contents($fileIP, 0);
}
touch($fileIP);
} // IP Counter AKtiv
//Filter Checks for POST; GET; FILES begin here -------------------------
// POST and GET VARIABLE LENGTH
if($CONF["CHECK_GET"])
foreach($_GET as $key => $value){
checkVar($key, $value);
}
if($CONF["CHECK_POST"])
foreach($_POST as $key => $value){
checkVar($key, $value);
}
if($CONF["CHECK_FILES"])
foreach($_FILES as $key => $value){
checkVar($key, $value);
}
} // active
// Function to check variables in submitted variables
function CheckVar($key, $value){
global $CONF;
if(!(mb_detect_encoding($value) == "UTF-8")) $value = utf8_encode($value);
if(strlen($value) > $CONF["MAXVARSIZE"]) denied();
if(count($CONF["ALLOWEDVARS"] > 0 )){
if(!in_array($key,$CONF["ALLOWEDVARS"])) denied("PARAMETER NOT ALLOWED");
}
// Content Check
// Now we have to check the content of the variables
if(!empty($CONF["ALLOWEDCHARS"])){
$value = mb_strtoupper($value);
$value = mbStringToArray($value);
foreach($value as $char){
if(!in_array($char, $CONF["ALLOWEDCHARS"])) denied("NOT ALLOWED CHARACTERS!");
}
}
}
function denied($txt = "Not a valid Request"){
header('HTTP/1.0 403 Forbidden');
die("<h1>$txt</h1>");
}
function mbStringToArray ($string) {
$strlen = mb_strlen($string);
while ($strlen) {
$array[] = mb_substr($string,0,1,"UTF-8");
$string = mb_substr($string,1,$strlen,"UTF-8");
$strlen = mb_strlen($string);
}
if(!empty($string))return $array;
}
?>
@stele:
gemäß paresy’s Ausführungen (welche mir einleuchtend erscheinen und auch meine weiteren Recherchen zum Thema SSL bestätigten dies), sollte deine Vorgehensweise nicht notwendig sein, wenn ich HTTPS/SSL benutze?! Oder übersehe ich etwas?
Ja. Die beschriebenen Verschlüsselungsverfahren verhindern ja nur dass sich jemand von außen in die Kommunikation einklinkt. Eine Code-Injection läuft ja über eine rein äußerlich vertrauenswürdige Verbindung ab, mit einem vermeintlich vertrauenswürdigen Partner. Dieser Partner schiebt Dir über die verschlüsselte Verbindung eine Schad-Code unter.
Um hier sinnvoll vorzubeugen musst Du tatsächlich eine inhaltliche Prüfung machen (ist natürlich nur in Grenzen möglich). Dafür ist das Script von stele99.