Dec 11

Retour sur Google Native Code: Une explication en profondeur et des propositions d’amélioration

Tag: mobilité, news, rechercheArrouan @ 4:51 pm

Après avoir lu plusieurs blogs et news sur Google Native Client, j’ai voulu en savoir plus. Mais n’ayant pas le courage de me plonger tout de suite dans le code, j’ai préféré d’abord lire le papier de recherche fourni par Google. Au passage, si quelqu’un trouve que ce papier a été publié et où ca m’intéresse mais ca n’a pas l’air d’être le cas.

Les auteurs commencent par rappeller que pour faire des calculs ayant des grosses demandent de ressource comme les scenes 3D ou tout ce qui est physique des objets solide et liquides, les langages comme JavaScript ne sont pas adapté. Que même si ActiveX ou NPAPI permet de faire tourner du code natif, c’est au détriment de la sécurité ou en repoussant la sécurité entre le clavier et la chaise ce qui pose souvent de grave problème. Pour eux, l’idée d’utiliser les ressources allouées au navigateur pour faire tourner du code natif d’applications webs est une mauvaise idée.

Alors comment fonctionne leur idée. Tout d’abord, il faut installer un plugin Native Client qui est en faite une sandbox ayant un accés total au système. Ce plug-in tourne dans un processus propre et n’est donc pas liée au navigateur. Les applications webs tourneront dans le plug-in qui intéragit lui-même via des API avec la navigateur et le système. Il est donc possible de concevoir des interfaces en JavaScript qui utiliseront du code natif dans Native Client pour accélerer certains traitements. Par exemple, ajouter des fonctions avancées de traitement d’image dans picassa.

Au final, Native Client ressemble très fortement à un microkernel. Native Client étant la base et l’interface et qui accepte des nouvelles extensions de confiance étendant ses possibilités. Par exemple, il est possible de créer des extensions de confiance qui permettront après à des applications webs d’utiliser le stockage sur le disque. Ce n’est pas l’application qui le fait directement, tout passe par des API.

Mais tout ça ne me rassure que partiellement sur la sécurité de leur architecture. Dans la suite du papier, ils introduisent la notion de double sandbox (une sandbox dans une sandbox). La première sécurité (la sandbox interne) est une première chose qui a l’air vraiment intéressante car elle utilise de l’analyse statique de code (x86 ici) pour détecter et interdire des instructions non sur. En pratique, ils vérifient que les executables inclues uniquement des instructions qu’ils ont qualifié de legales. La seconde sandbox se trouve à l’extérieur et vérifie que l’ensemble des syscalls de Native Client vers le système sont autorisées en les comparant à une courte liste de syscalls (46 dans leur tests). En résumé, l’architecture est donc composé d’une première sandbox qui vérifié la qualité du code et qui appelle une API interne. Puis une seconde sandbox qui vérifie que ce qui sort de l’API vers le système est également valide. Ils utilisent une double analyse dynamique et statique bien que les 2 soient relativement limité car utilisant uniquement des whitelists.

Après ce premier point, il en ressortque la surface d’attaque est assez vaste: la sandbox interne qui fait de la validation de binaire, la sandbox externe qui joue comme un wrapper et intercepte les appels systèmes envoyés à l’OS, les bibliothéques, les interfaces de communications avec les autres modules, le système et le navigateur.

La sandbox interne a été testé via des outils de fuzzing et grâce à un code de seulement quelques milliers de lignes, ils ont réussi une implémentation rapide et sécurisé. La sandbox externe fonctionne en utilisant ptrace et en interceptant chaque syscalls et en le vérifiant contre une whiteliste. Pour certains syscalls comme open, ils vérifient également les arguements pour vérifier que ceux-ci sont aussi autoriser (par exemple ouverture de la lib ld.so).

Avec ces systèmes de sandboxing + des API, il y a forcement un overhead. Ce dernier est tout de même relativement faible entre 12 et 5% ce qui est tout à fait acceptable. Pour tester les performances, ils se sont amusées à porter en Native Code un ensemble de logiciel comme Quake.

Alors? Au final, je trouve que l’idée est plutôt bonne même si l’utilitée est vraiment à prouver. En effet, pour contourner les problèmes des applications webs, on en fait des applications ce qui est un peu un retour au début de la boucle. Mais pourquoi pas ce principe peut être intéressant pour développer les possibilités des applications et leurs puissances sans en complexifier l’utilisation pour l’utilisateur final.

Après je trouve leur idée allant dans le bon sens mais je ne comprends pas pourquoi ils ne les ont pas pousser un peu plus. Sans être un spécialiste du domaine, je suis sur que des travaux beaucoup plus avancés sur l’analyse de code ont été faite que la comparaison avec une whiteliste. De plus, pourquoi comparer les binaires quand la comparaison de code source est tellement plus efficace. Bref, pourquoi ne pas utiliser des logiciels comme FramaC ou d’autres alternatives pour vérifier la qualité du code. Le temps d’analyse sera surement plus long mais de meilleurs qualités et il est toujours possible de l’externaliser (sur un nuage par exemple).

Deuxième point, le contrôle via ptrace des syscalls, alors la pour le coup, c’est vraiment mon domaine et la whiteliste même si elle est intéressante et très limiter. De plus, leur approche ne peut pas résisté à des attaques d’intégrité et/ou de confidentialité complexes incluant des séquences de syscalls. En effet, ils analysent syscall par syscall sans avoir une vue d’ensemble. Mon idée serait d’étendre leur implémentation de ptrace pour le support de label de sécurité à la SELinux (ou d’autres systèmes comme ceux de RSBAC ou GRSecurity) et de mettre en place un système de contrôle d’accés mandataire complet implémentant des fonctions un peu avancée comme le type enforcement. Pour réussir à contrôler les séquences, il faudra des logiciels de prévention des intrusions comme ce qui est développé dans le cadre de l’ANR SEC&SI pour les bureaux graphiques permettant l’accés à Internet.

Biensur, cela va forcément augmenter l’overhead du à l’utilisation de Native Client mais cela peut être minimiser avec une borne achitecture de pre-calcul de la sécurité du code et des droits d’accés de celui

Finalement, en étendant la structure actuelle de Native Code pour remplacer leur analyse statique par des fonctions plus avancés (pouvant très bien être décentraliser sur une grille ou autres nuages) et en appliquant un contrôle d’accés stricte via des propriétés de sécurité (par exemple, tel module ne doit pas pouvoir modifier l’intégrité de tel fichiers ou la confidentialité de tel autres ou l’intégrité d’un autres processus, etc), il serait possible d’avoir un système beaucoup plus résistant aux attaques surement nombreuses et très avancées qui ne manqueront pas d’être développer si cette plateforme à un jour un succés (regarder flash, le pdf, etc).

3 Responses to “Retour sur Google Native Code: Une explication en profondeur et des propositions d’amélioration”

  1. dan says:

    > je suis sur que des travaux beaucoup plus avancés sur l’analyse de code ont été faite que la comparaison avec une whiteliste

    ils vérifient que chaque présente dans le binaire est légale, ce qui est une bonne chose, mais l’analyse ne s’arrête pas là. Ils vérifient également que les sauts directs ont des cibles valides, et que les sauts indirects respectent certaines propriétés. Les contraintes qu’ils imposent sur le code sont censées permettre un désassemblage correct, et donc s’assurer qu’on n’a que des instructions valides. Si ensuite on ne peut sauter que sur des instructions valides, en principe on ne peut pas sortir de la sandbox.

    Il y aura forcément des failles dans l’implémentation (le premier exploit est déjà sorti), mais le principe a l’air correct.

    > De plus, pourquoi comparer les binaires quand la comparaison de code source est tellement plus efficace

    l’idée est *d’accélérer* les applications web. Si on demande à chaque fois de distribuer le code source, analyser et recompiler 12.000 lignes de C on n’est pas rendus. En plus, ça oblige à intégrer le compilateur dans la trusted computing base, ce qui n’est pas une bonne chose.

    L’analyse de binaire “suffit” pour ce qu’ils souhaitent faire, à savoir garantir que le binaire ne sort pas de la sandbox et ne fait pas de syscalls directement. Il n’y a pas besoin de faire d’analyse très poussée pour ça.

    > leur approche ne peut pas résisté à des attaques d’intégrité et/ou de confidentialité complexes incluant des séquences de syscalls.

    comme par exemple ?

  2. Yoric says:

    Bref, pourquoi ne pas utiliser des logiciels comme FramaC ou d’autres alternatives pour vérifier la qualité du code.

    Parce que Frama-C est tout sauf automatique. Et dès que Frama-C tombe sur quelque chose qu’il ne sait pas faire tout seul (c’est-à-dire à peu près 99% du temps), il faut un utilisateur “plutôt calé”. Genre une formation double en logique/informatique théorique et C. Pas tout à fait le cas de l’utilisateur lambda d’un navigateur :)

    Maintenant, il y a des approches de type Code Porteur de Preuves (PCC), qui servent exactement à ce genre de choses et qui existent depuis une dizaine d’années mais pour l’instant, l’industrie n’en a pas entendu parler.

  3. SecFault.Org » Browser Security: Les leçons apprises par Google Chrome says:

    [...] Les développeurs de Google Chrome ont voulu prendre en compte des aspects de sécurité dès le début pour éviter d’ajouter des couches bancales par la suite. Pour cela, ils ont mise en place une architecture de sécurité relativement élaborée permettant de limiter l’impact des nombreux problèmes de sécurité que peut recontrer un browser lors de ses passages sur des pages web malicieuses. La description de cette architecture est disponible sur le site de chronium (la version libre de Google Chrome). Une partie se base sur des autres travaux de recherche de Google dont j’avais parler ici. [...]

Leave a Reply