Securité : changement de politique sur l'accès aux fichiers

Bonjour,

Comme certain ont pu le voir dans la dernière version bêta et encore plus dans la dernière version alpha, il y a eu un changement majeur sur l’accès aux fichiers par le serveur web.

Avant le .htaccess n’interdisait l’accès qu’à certain type de fichier, maintenant c’est l’inverse nous n’autorisons l’accès qu’à certain type de fichier :(css|js|jpeg|jpg|png|php|html|svg|woff|woff2|ttf|m3u8|ts|ico).
De plus nous interdisons l’accès aux fichiers de type : class.php, com.php, config.php, sample.php. Attention je parle d’accès direct par le navigateur, les chargements au travers d’autres fichiers php sont bien sur possible.

Pour l’alpha on va même encore plus loin, nous autorisons l’accès à certain fichier qu’en fonction de leur répertoire : https://github.com/jeedom/core/blob/alpha/.htaccess#L54

Par exemple dans un répertoire css nous n’autorisons que les fichiers CSS. Vous avez dans le lien précèdent toutes les règles, qui sont loin d’être parfaites et vont demander encore énormément de travail.

Dans 99% des cas pas d’impact pour vos plugins si vous avez des chargements directs de fichier (type json) en javascript par exemple ou des téléchargements depuis l’interface de certain fichier.

Pour le premier cas je vous invite à passer par une requête ajax, cela permet au passage de vérifier que la demande vient bien d’un utilisateur connecté avec les bons droits (admin par exemple).

Pour le 2eme cas vous avez un fichier downloadFile.php dans le core qui permet de gérer les téléchargements de fichiers, même multiple avec gestion des droits (admin obligatoire) et vérifie que le fichier se trouve bien dans le répertoire racine de Jeedom (et pas n’importe où sur le file système).

Voici un exemple d’utilisation :

$('#bt_dockerDownloadBackup').on('click', function() {

  window.open('core/php/downloadFile.php?pathfile=/var/www/html/plugins/docker2/data/backup/' + $('.eqLogicAttr[data-l1key=id]').value()+'.tar.gz', "_blank", null)

})

Vous pouvez bien sur l’utiliser en mode relatif.

Enfin dernier cas, si vous voulez accéder à un type de fichier qui ne devrait pas être dans le répertoire en question, dans ce cas il faut le mettre dans le répertoire prévu pour.

Le système de vérification des fichiers dans un répertoire est encore très perfectible et va nous demander de nombreuses heures de correction encore mais nous pensons que c’est un mal nécessaire.

7 « J'aime »

Bonjour,

Merci pour l’info, c’est clair pour moi.

En beta (je n’ai pas regardé l’alpha), il me semble qu’on pourrait rajouter les GIF dans la liste autorisée:

<FilesMatch ".*\.(css|js|jpeg|jpg|png|php|html|svg|woff|woff2|ttf)$">
    Order Allow,Deny
    Allow from all
</FilesMatch>

devient

<FilesMatch ".*\.(css|js|jpeg|jpg|png|gif|php|html|svg|woff|woff2|ttf)$">
    Order Allow,Deny
    Allow from all
</FilesMatch>

Dans le cas contraire, ce fichier n’est plus accessible par exemple: core\img\no_image.gif

Effectivement je me le note, je le rajoute des que j’ai un pc, merci pour le retour

Peut-on également rajouter les fichiers mp3 ?

Bonjour
Peux tu me détailler pourquoi ? Les fichiers en question contiennent quoi ? Du tts ?

Tout à fait du TTS. J’ai un plugin perso connecté sur Amazon Polly qui me génére du TTS en mp3. Ensuite ce mp3 est joué par une tablette utilisant JPI et doit donc être accessible « de l’exterieur ».
Tout cela se fait dans le dossier plugins/voxtts. Depuis le passage en beta 4.2.4 cela ne marche plus.

Tu dois adapter dans ton plug-in et mettre un fichier.htaccess dans le dossier dans lequel tu génères le mp3 avec la config adequate alors

Non même le htaccess suffira j’ai mis une sécurité au dessus juste pour ce genre de cas qui sont risqué.

Ton fichier rien n’empêche de le trouver (même si le nom est complexe) et donc de connaitre toute tes demandes de TTS ce qui représente un risque pour la sécurité de ton jeedom, je ne suis donc pas favorable a autoriser les mp3 pour ce genre de cas que je juge risqué.

La pour moi tu devrais soit :

  • passer par l’appel d’un fichier php qui va charger le mp3, dans le php tu pourras verifier les droits de l’utilisateur
  • utiliser le systeme de tts de jeedom qui fait deja tout ca pour toi et qui autorise les plugins a ajouter des types de moteur tts

Ok
J’ai opté pour le php, je n’ai pas compris comment m’interfacer avec le tts de jeedom.

Dommage car après ça permet d’être compatible avec plein de plugin type gcast, sonos… Pour l’interfacage c’est juste une fonction dans la classe, le plugin songs le fait en beta de mémoire

Salut Loic,

On a remarqué ce commit download file is only allow for connected user not api · jeedom/core@986dbdb · GitHub qui retire l’accès API via downloadfile.

Peut-on savoir si c’est un test ou si cela va rester avec certitude et quelle est l’idée derrière cette restriction?
Je ne vois pas comment un accès via clé api est plus dangereux qu’une session interactive.

Autre point, même avec un utilisateur interactif, comment est-ce qu’on doit gérer le download de fichier coté frontend pour un utilisateur qui n’est pas admin car le downloadfile impose (et imposait déjà) cette limitation; hors tout le monde ne travaille pas en admin sur son jeedom;
une solution c’est justement que tout le monde passe admin mais alors on perd en sécurité en fait…

Bonjour
J’ai fait ça en urgence je ne sais pas gérer les accès en fonction des droits ça représenté trop de risques j’ai préféré bloqué au maximum.

Si certains savent faire qu’ils n’hésitent pas à faire un pr moi j’arrive pas à un truc fiable et sur

Je veux bien tenter d’aider et réfléchir (comme surement d’autres devs ici) à une solution mais quel serait le « cahier des charges » ?
Quelle logique business voudrait-on dans le meilleur des cas / si possible et qu’est-ce qu’on (vous) n’êtes pas prêt à autoriser?
Ça c’est à vous de le définir même si tu (ou jeedom) n’as pas (encore) de solution à tout, ce que je comprend bien.

Pour le moment, le risque que je vois c’est que les plugins qui ont ce besoin vont développer leur propre solution en (re)introduisant potentiellement une faille que tu as voulu fermer dans le core.
Alors évidement c’est la responsabilité du plugin mais au final tout le monde a perdu.

1 « J'aime »

Mon soucis c’est comment savoir si le fichier en question est autorisé en accès non admin et je sais pas comment faire… Ya des fichiers critique que les non admin ne doivent pas pouvoir recuperer sous peine de pouvoir faire une elevation de privilege. J’ai aucune idée de comment gerer cela ca depend de chaque plugin…

Est ce chaque plugin ne pourrait pas definir dans un parametrage les zones « tout public » (ie dossier d images par exemple!) de son perimetre (ie : sous (/plugins/<pluginId>/.... ) dans lequel les telechargements seraient possible par « tous »
Les autres endroits seront de facto considérés comme privés/confidentiels et donc uniquement accessible par un profil admin ?

Ca demande a tous les dev de faire une adaptation mais ca m’irai oui on pourrait définir un dossier ou tous les utilisateurs pourrait recuperer des fichiers dedans. Ca me semble secure ce genre de chose.

Un dossier public dans le plugin pour ce genre de choses. Autres que images etc habituels. Pas bête et ça gênerai pas en 4.1

quoiqu’il arrive certains dev vont réaliser des choses de leur côté pour continuer à pouvoir accéder à certaines ressources !
Du coup, je rejoins @Mips => autant essayer d’imaginer une solution « standard » au niveau du core que tout le monde peut utiliser (downloadFile!), plutôt que chacun (re)développe un truc dans son coin (ce qui n’empêchera pas certain de le faire… ) et qu’au final toute la partie sécurité que vous avez mis en place sur la 4.2 soit moins « efficace » que prévue à cause de certains plugins.

pas forcément :slight_smile:
ceux qui ne font rien, on(/ils) pourra rien récupérer chez eux : donc pas forcément pire qu’actuellement !?

ce à quoi je pensais (sur un coin de table, donc surement à creuser), c’est simplement d’avoir une fonction au niveau du core

function definePublicFolder(string $_pluginId, array $_pathInsidePlugin, array $_extension = "*")

qui permette d’enregistrer l’ensemble des path à l’intérieur plugin lui-meme qui sont « autorisés pour tous ».

donc côté « adaptation » pour le développeur d’un plugin n’aurait uniquement à ajouter une ligne de code (lors de l’install/update !?)

definePublicFolder('monPluginId', array('/mon/super/path/a/linterieur/de/mon/plugin'), array('png', 'jpg') )

côté core, revoir le downloadFile :

  • si ya une apiKey => on check si le fichier demandé appartient aux « dossiers public »
  • si connecté =>
    • admin => unlimited (.htaccess)
    • not admin => uniquement si le fichier demandé appartient aux « dossiers public »

là tu redemandes par contre potentiellement ++ de modif à réaliser pour tous les développeurs

Le dossier public va arriver c’est sur mais pas pour ça, ça sera pour tout ce qui doit être accessible et sur laquelle il n’est pas possible de mettre une authentification, ça sera un dossier sans aucune restriction par le core mais il sera vraiment public il ne faudra donc rien mettre de critique dedans.

Après un autre dossier download oui ça peut se faire ça sera le dossier download pour tous ce qui est téléchargeable par un utilisateur restreint ou admin.