ldleman / yana-server

Interface PHP de domotique Y.A.N.A (You Are Not Alone)
http://projet.idleman.fr/yana
107 stars 59 forks source link

Méga faille de sécurité: vie privée #248

Open valentin8709 opened 8 years ago

valentin8709 commented 8 years ago

Salut salut! Je viens juste de m'apercevoir d'un détail assez dérangeant: on a comme tout serveur web accès aux ressources qui y sont déposées, comme les images et les vidéos (plugin camera entre autre), du coup, on peut "by passer" l'authentification de Yana simplement en rentrant le nom du fichier distant dans l'URL... et on récupère ce qui s'affiche dans le plugin camera... pas terrible terrible =/

J'ai essayé de bidouiller avec un .htaccess, mais du coup l'image n'est plus dispo dans Yana...

Bref une idée?

maditnerd commented 8 years ago

Quelques pistes (vite fait aucun code n'a été testé)

camera.plugin.disabled.php

Nom aléatoire

Donner un nom généré aléatoirement au fichier system('raspistill -hf -w 400 -h 400 -o '.$absolute_path.uniqid().'.jpg');

L'URL pour accéder à l'image changera à chaque refresh.

il faut que Yana sache quel est son nom après (sauvegarder le nom dans la BD par ex ?) Il faut aussi gérer le faite que cela va créer un fichier à chaque fois qu'une image est crée (supprimer ou laisser le précédent lors d'un camera_refresh ?)

Lecture du fichier brute

Un peu plus tordu, sauvegarder le fichier dans un dossier bloqué par des règles .htaccess et avec php lire le fichier brute et le convertir en base64 , ce qui nous permet de mettre dans src l'image comme un gros bourrin, l'image est directement dans le code HTML et ne sera pas accessible même en connaissant son emplacement

PHP

<?php
$image_raw = file_get_contents($image_link);  # On récupère le contenu du fichier
$image_base64 = base64_encode($image_raw); #On converti le fichier binaire en base64
?>

<img class="img-polaroid img-rounded" id="cameraPI" src="data:image/png;base64,<?php echo $image_base64 ?>" >

Sauvegarder l'image dans la BD

Même principe que précédemment mais on met le fichier en base64 dans la base de données, après je sais pas si c'est vraiment une bonne idée ^^

valentin8709 commented 8 years ago

Ok merci pour toutes ces indications! J'aime pas trop le stockage en BD ou le fichier aléatoire, je trouve pas ça hyper propre, par contre l'idée du fichier en base64 me plaît =) Je vais essayer d'intégrer ça, et je proposerai la modif à Idleman si ça marche et que ça l'intéresse.

Merci en tout cas =)

ldleman commented 8 years ago

Mea culpa :D, d'habitude je verouille via htaccess et j'utilise une de mes classes de protections d'images pour retransferer le flux avec un header contente type au mime de l'image. pas besoin d'encodage en base 64 si le flux image est direct transfert avec le bon header.

Le code ressemble à ça :

case 'open_file':

      if(!$myUser->can('camera','r')) return;

      header('Content-type: image/jpeg');
      header('Content-Transfer-Encoding: binary');
      header('Expires: 0');
      header('Cache-Control: must-revalidate');
      header('Pragma: public');
      ob_clean();
      flush();
      echo file_get_contents('image.jpg');

break;

Ensuite il suffit de mettre dans le src de l'image l'adresse de l'action. Je m'en occuperais dès que j'aurais une minute.

AF340 commented 8 years ago

Cool, reste plus qu'a faire un plugin qui utilise motion pour une détection avancée...;)

http://www.lavrsen.dk/foswiki/bin/view/Motion/WebHome

Le 27 mai 2016 à 07:55, Idleman notifications@github.com a écrit :

Mea culpa :D, d'habitude je verouille via htaccess et j'utilise une de mes classes de protections d'images pour retransferer le flux avec un header contente type au mime de l'image. pas besoin d'encodage en base 64 si le flux image est direct transfert avec le bon header.

Le code ressemble à ça :

case 'open_file':

  if(!$myUser->can('camera','r')) return;

  header('Content-type: image/jpeg');
  header('Content-Transfer-Encoding: binary');
  header('Expires: 0');
  header('Cache-Control: must-revalidate');
  header('Pragma: public');
  ob_clean();
  flush();
  echo file_get_contents('image.jpg');

break;

Ensuite il suffit de mettre dans le src de l'image l'adresse de l'action. Je m'en occuperais dès que j'aurais une minute.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ldleman/yana-server/issues/248#issuecomment-222066376, or mute the thread https://github.com/notifications/unsubscribe/ASWheFIgqKmPo2hglVmqEeXVO0zAa48Zks5qFodUgaJpZM4Inuw8 .

ldleman commented 8 years ago

@AF340 pour la version motion ça sera sans moi : le plugin camera est un simple example de l'utilisation de la cam je ne veux pas passer trop de temps dessus je préfere bosser sur les clients et le core yana :p, mais si tu veux te lancer sur un fork du plugin camera n’hésite pas a le proposer sur le market.

@valentin8709 j'ai mis à jour le plugin, ça devrais le faire mainant :p

AF340 commented 8 years ago

Je comprends bien idleman, ton core est vraiment bien foutu, beau travail! pour motion, je vais me pencher sur le sujet... ;) Le 31 mai 2016 07:51, "Idleman" notifications@github.com a écrit :

@AF340 https://github.com/AF340 pour la version motion ça sera sans moi : le plugin camera est un simple example de l'utilisation de la cam je ne veux pas passer trop de temps dessus je préfere bosser sur les clients et le core yana :p, mais si tu veux te lancer sur un fork du plugin camera n’hésite pas a le proposer sur le market.

@valentin8709 https://github.com/valentin8709 j'ai mis à jour le plugin, ça devrais le faire mainant :p

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ldleman/yana-server/issues/248#issuecomment-222598086, or mute the thread https://github.com/notifications/unsubscribe/ASWheE8-3DJEVo0AHZU6HAVYFf0YSWkvks5qG8xggaJpZM4Inuw8 .

valentin8709 commented 8 years ago

Je viens de pull, je n'ai pas testé directement vu que je n'utilise pas le plugin Camera mais un fork fais maison où je peux à la fois prendre des vidéos, les archiver et prendre des photos. J'ai donc adapté ton code, et ça marche du tonnerre! Je ne peux plus accéder à mes ressources si je ne suis plus connecté, et si je me connecte tout fonctionne comme avant =D Juste deux petites questions au passage:

Merci mille fois encore pour ton travail =D

ldleman commented 8 years ago

le fait de passer par la fonction js permet le rafraichissement de l'image sans avoir a rafraichir la page tout simplement. Ca permet aussi a ceux qui souhaitent bidouiller ça en fausse video image par image d'avoir juste à faire un setInterval sur le camera_refresh pour passer en mode video.

Le forbidden est un message d'erreur serveur il n'est pas géré par php, si tu veux le modifier il faut modifier les configurations de ton serveur http (apache, lighttpd...) tu peux customiser ça notamment avec les clauses "ErrorDocument" dans un htaccess sur apache (cf.http://httpd.apache.org/docs/2.4/fr/custom-error.html).

Cela dit ça ne changera rien coté sécurité serveur car bien que tu ne le vois pas directement tous les serveurs envoient par défaut toutes leurs signatures sur toutes les pages d'un site web.

Si tu utilise firebug tu verra ce genre de réponse quelle que soit ta requête 2016-05-31 13_52_52-firebug -

Si c'est juste désactiver la signature serveur sur toutes les pages/sites qui t’intéresse, tu peux la changer en installant le mod security d'apache, perso je trouve ce besoin de sécurité un peu disproportionné sachant que ce n'est pas l'absence de signature d'un serveur qui vas beaucoup gêner un éventuel pirate mais si tu souhaite faire du zèle en matière de sécurité http tu peux installer par mal de mods pour apache et de paquets pour ubuntu afin de blninder ton serveur.

Attention tout de même, la sécurité est diamétralement opposée à l'accessibilité, ça risque de te jouer des tours :)

valentin8709 commented 8 years ago

Ok merci pour ce rappel qui me fait pas de mal du tout! Pour la sécurité je ne cherche pas à blinder le bidule, juste à faire le minimum, Yana c'est quand même un accès à pas mal de chose chez moi! (Bien qu'il n'y ait rien de critique genre verrou de porte ou vanne pour le gaz). Bref du coup oui c'est inutile de cache le machin si la signature est dans les headers quoi qu'il arrive!

Sinon j'en profite également pour te poser une question en terme d'accessibilité: le JS sur les dashboards ne se charge pas hyper vite (6 secondes chez moi pour 12 widgets sur la dashboard la plus complète). N'y a-t-il pas moyen d'accélérer un peu le tout? J'imagine que si c'était facile tu l'aurais déjà fait, mais du coup ça m'intrigue un peu sachant que tout le reste est super réactif.

ldleman commented 8 years ago

Chaque widget exécutant un code différent des autres provenant de plusieurs plugins officiels ou pas ça m'est impossible de mutualiser le code de chaque widget.

Chez moi ça met environ 3s a charger le tout sachant que j'ai les 12 widgets par défaut et qu'ils se chargent tous de manière asynchrone (aucun widget n'attend la fin du chargement des autres pour se charger).

Il faudrait détecter chez toi quel widget est le plus long et voir si on peux optimiser le code mais il y a de grandes chance que la lenteur soit surtout due a ton réseau ou à ton rpi (config ou hardware)

Pour voir les temps de chargements par widget tu peux utiliser firebug ou la console par défaut de ton navigateur :
2016-05-31 15_31_16-firebug - yana server 3 0 6

Tu peux désactiver ou essayer d’optimiser les plus longs.

valentin8709 commented 8 years ago

Ok merci pour l'info, mais je doute que je puisse faire qqch pour optimiser les widgets. Sinon juste comme ça tu tournes sous quelle version de RPi?

ldleman commented 8 years ago

Ça dépends des essais j'ai un peu de toutes les versions a la maison, le screenshoot c'est du local donc c'est forcement plus rapide mais c'est justement ce qui appuis la thèse des lenteurs réseau ou d'une config serveur qui peut être boostée.

Faudra que je refasse les tests sur mon pi2, je n'ai jamais constaté de lenteurs gênantes mais c'est peut être une question de subjectivité :p