Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

La sérialisation en Java, une « horrible erreur » ? Oracle prévoit de la supprimer,
Car elle serait la source de bon nombre de problèmes de sécurité

Le , par Michael Guilloux

488PARTAGES

23  0 
Oracle prévoit de supprimer la prise en charge de la fonctionnalité de sérialisation / désérialisation des données du langage Java. C'est ce qu'a révélé Mark Reinhold, l'architecte en chef de la plateforme Java chez Oracle.

Pour information, la sérialisation est un mécanisme introduit dans les tout débuts de Java (JDK 1.1), en 1997. Ce mécanisme permet d’écrire des données présentes en mémoire (un objet par exemple) dans un format de données binaires, permettant alors de rendre persistant l’élément via un stockage disque, une transmission réseau ou autre. La désérialisation est l'activité réciproque qui permet d'utiliser l'objet sous sa forme originale. Java fournit donc un certain nombre d’outils permettant de sérialiser ou désérialiser de manière transparente et indépendante du système.

En raison de sa commodité, un grand nombre de langages de programmation prennent en charge cette fonctionnalité, mais pour Java, elle a été ces dernières années impliquée dans de nombreuses failles de sécurité. C'est ce qui motive d'ailleurs Oracle à vouloir la supprimer maintenant. L'ajout du support de la sérialisation à Java en 1997 était une « horrible erreur », affirme Mark Reinhold, alors qu'il explique qu'au moins un tiers - peut-être même la moitié - des vulnérabilités Java impliquent la sérialisation.

Pour comprendre les propos de l'architecte en chef du JDK chez Oracle, revenons d'abord au problème de sécurité de la sérialisation en Java. Notons avant d'aller plus loin que les attaques via des opérations de sérialisation sont connues depuis des années, sous une forme ou une autre. Elles sont toutefois devenues un problème sérieux après des découvertes faites par des chercheurs en 2015. D'abord à la conférence AppSec Californie en janvier 2015, deux chercheurs - Chris Frohoff et Gabriel Lawrence - ont présenté leurs travaux et des outils pour exploiter des mécanismes de sérialisation et les utiliser à des fins malveillantes.

En novembre 2015, des chercheurs de FoxGlove Security vont plus loin et révèlent qu'un certain nombre de bibliothèques Java chargées par défaut par les serveurs applicatifs (WebSphere, Jboss, WebLogic, etc.) sont vulnérables à des attaques par désérialisation. Et parmi ces bibliothèques se trouve Apache Commons Collections, un module Java très populaire.

Pour information, Apache Commons est un projet de la fondation Apache, dont le but est de fournir un ensemble de bibliothèques réutilisables et open source pour Java. Elles sont de ce fait, largement employées dans bon nombre de projets open source en Java. Apache Commons se décompose en un nombre important de modules, dont les utilisés sont Commons Collections, Commons DBCP, Commons IO, Commons Lang, Commons Logging et Commons Pool.

Fin 2015, en dehors d'Apache Commons Collections, plusieurs dizaines d'autres bibliothèques ont été déclarées vulnérables, ce qui a nécessité la mobilisation des organisations telles qu'Apache, Oracle, Cisco, Red Hat, Jenkins, VMWare et IBM, entre autres, qui ont publié des correctifs de sécurité pour leurs produits. Malgré cela, la sérialisation continue d'être une source importante de problèmes de sécurité pour la plateforme. Ce qui conduit Mark Reinhold aujourd'hui à penser que c'était une « horrible erreur ».


L'équipe Java d'Oracle travaille donc actuellement sur la suppression de la prise en charge de la sérialisation. Toutefois, il ne s'agit pas de la supprimer complètement puisqu'il sera fourni aux développeurs un système de plug-in pour prendre en charge les opérations de sérialisation via un nouveau framework. Précisons aussi que la suppression de cette fonctionnalité est un objectif à long terme, donc la date de sa finalisation n'est pas encore définie. Mais jusqu'à ce qu'Oracle la supprime, les entreprises et les chefs de projet qui ne veulent pas qu'un développeur ou module appelle des fonctions de sérialisation ou désérialisation peuvent empêcher cela via un "filtre de sérialisation" qui a été ajouté dans Java en 2016 pour bloquer toutes ces opérations.

En savoir plus sur la vulnérabilité de sérialisation en Java

Source : Mark Reihnold, architecte en Chef du JDK chez Oracle

Et vous ?

Que pensez-vous de la décision d'Oracle ?
Utilisez-vous souvent la sérialisation en Java ? Est-ce une horrible erreur ?
Les plateformes telles que .NET, Ruby et autres sont-elles déjà protégées contre ces attaques ?

Voir aussi :

JavaFX SDK Early Access disponible pour le JDK 11 et un miroir GitHub du projet OpenJFX mis en place
Java SE 8 : les mises à jour publiques seront disponibles jusqu'à décembre 2020 minimum pour les fonctionnalités non commerciales
Java : proposition en open source pour Mission Control, l'outil de profilage et d'analyse des performances d'Oracle
JDK 11 : trois nouveautés sont prévues ainsi que la suppression de JAVA EE, JavaFX et CORBA, dans le cadre des mises à jour semestrielles
Tutoriel : La sérialisation binaire en Java

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de thelvin
Modérateur https://www.developpez.com
Le 28/05/2018 à 17:14
Citation Envoyé par emixam16 Voir le message
Par ailleurs, puisque énormément de code utilise la sérialisation, supprimer son support c'est rendre tous ces codes incompatibles avec les futures versions de JAVA
Ah bah oui mais y'a pas de magie, hein. C'est une faille de sécurité ambulante, parce que ça fonctionne comme ça au lieu de fonctionner autrement. Du coup, ben, si tu casses pas la fonctionnalité existante, tu gardes les failles de sécurité comme elles sont. Logique.

Citation Envoyé par AoCannaille Voir le message
J'ai l'impression de vivre dans un autre monde... Sérialiser en mode texte? sérieusement? à quoi ça peut servir un truc aussi gourmand?
Même chose que la science, ça sert à marcher, b****** ! (Euh, je crois que c'est, "brelan de dames".)

Citation Envoyé par AoCannaille Voir le message
On utilise surtout google protocol buffer pour ça. ça marche plutôt bien.
Honnêtement, dès que je veux faire de la communication un peu lourde, j'utilise protocol buffer, oui. Les quelques pourcents économisés ont de la valeur à mes yeux.

Mais la différence fondamentale c'est que protocol buffer il faut lui configurer un modèle, le compiler, vérifier sa validité, le lier aux classes, etc. Il ne marche pas tout seul, il demande du travail.

XML et JSON marchent tout seul pour une utilisation simpliste, et ne demandent pas beaucoup de boulot quand on les connaît bien pour une utilisation plus universelle. Sensiblement moins de boulot que protocol buffer en tout cas.

C'est à ça que ça sert un protocole texte, lourdingue et universel. Ça marche, b******. Rien de plus ni de moins. Même raison pour laquelle le web est ce qu'il est. En principe ça devrait paraître tout autant ridicule tout ce texte dans le protocole le plus Universel de la planète. Et c'est lui qui c'est imposé. Parce que lui, il marche.
6  0 
Avatar de AoCannaille
Membre émérite https://www.developpez.com
Le 28/05/2018 à 16:49
Citation Envoyé par supergeoffrey Voir le message
Oui ça sert à rien, il existe des format tierce (JSON, XML) pour sérialiser des objets
J'ai l'impression de vivre dans un autre monde... Sérialiser en mode texte? sérieusement? à quoi ça peut servir un truc aussi gourmand?
Je ne suis pas dans le web, donc je ne sais pas l'utilité que vous avez de la sérialisation, mais personnellement on l'utilise soit entre applications sur la même machine, soit sur le réseau en radio.
En local, sur les petits objets pourquoi pas, mais dès que ça part sur du réseau, faire passer du texte est horriblement inefficient...

On utilise surtout google protocol buffer pour ça. ça marche plutôt bien.

Le binaire il n'y a que ça d'efficace!
4  1 
Avatar de thelvin
Modérateur https://www.developpez.com
Le 28/05/2018 à 23:41
Citation Envoyé par _champy_ Voir le message
Cela fait longtemps que je n'ai pas fait de Java mais si le problème est l’origine de la source de données pourquoi supprimer la sérialisation ?
Parce que l'écosystème Java foisonne de bibliothèques tierces qui nous aident à faire du travail qu'elles savent faire à notre place. Et certaines utilisent la sérialisation. D'autres offrent des outils pour s'en servir.

À cause de cela, si tu fais un projet un tant soit peu sérieux et sur lequel tu n'as pas pris à cœur de tout implémenter toi-même, alors tu as très certainement de nombreuses parties de ton code qui utilisent la sérialisation/désérialisation de manière plus ou moins prévisible ou évidente.

Et tu as aussi plusieurs classes dans ton classpath, venant de bibliothèques tierces dont tu te sers ou récupère en dépendance transitive, qui sont sérialisables, donc désérialisables, et qui permettent de décrire un comportement complexe et exécutable, comportement qui bien sûr va être exécuté à un moment ou à un autre, soit parce que cette classe définit qu'à la désérialisation elle exécute le comportement qu'elle représente, soit parce qu'une bibliothèque, quelque part, va reconnaître cette classe et se dire que si on a récupéré un comportement, c'est bien sûr pour l'exécuter. Les erreurs de sécurité ne manquent pas.

Bref un petit malin n'a plus qu'à envoyer une requête à ton site web, avec dedans un cookie qui contient la sérialisation d'un objet qui représente le fait d'effacer la base de données, et ta base de données est effacée. Merci la sérialisation !

En général, les systèmes de sérialisation/désérialisation qui n'ont pas ce problème, c'est ceux qui disent à la désérialisation, quelle classe on veut désérialiser. Il n'y a donc pas de classe qui représente un comportement qui tienne, ou s'il y en a une, c'est seulement de manière attendue et encadrée par le développeur qui la demande.
3  0 
Avatar de Gugelhupf
Modérateur https://www.developpez.com
Le 28/05/2018 à 16:10
Bonjour,

La sérialisation Java n'est certe par parfaite:
  • Incompatibilité de sérialisation/désérialisation des objets entre les différentes versions de la JVM
  • Interopérabilité avec les autres langages quasi inexistante (ex: Sérialiser un objet Java, puis le récupérer dans un programme C#)
  • Vitesse de sérialisation/désérialisation plus lente et poids des objets plus élevés que ceux des technos plus récentes (gRPC ou Thrift Compact)


Par contre il y a tellement de librairies qui reposent sur la sérialisation Java qu'il sera difficile de s'en passer, RMI en fait parti.

A+
2  0 
Avatar de emixam16
Membre expérimenté https://www.developpez.com
Le 28/05/2018 à 14:46
Ça serait une bonne chose que Java modifie la manière dont est gérée la sérialisation car c'est effectivement une passoire d'un point de vue sécurité.

Mais aller jusqu'à supprimer une fonctionnalité si basique, cela me semble une très mauvaise idée.

Si les gens doivent sérialiser leurs objets manuellement ou utiliser des bibliothèques tierces (plus ou moins supportées), ça pourrait faire fuir beaucoup de gens de Java. La sérialisation c'est très simple à faire manuellement mais cela ne signifie pas que tout le monde soit près à le faire.

Par ailleurs, puisque énormément de code utilise la sérialisation, supprimer son support c'est rendre tous ces codes incompatibles avec les futures versions de JAVA

Bref, ce serait vraiment aller contre le sens du progrès.

[TROLL] Mais cela ne m'étonne pas d'Oracle, qui à l'habitude de changer l'or en plomb... [/TROLL]
3  2 
Avatar de epsilon68
Membre éprouvé https://www.developpez.com
Le 28/05/2018 à 15:53
je pense que la serialisation dans Java ne servait a rien. Mieux vaut serialiser en XML ou json ou meme dans sqlite, c'est bien mieux. Je pense que leur decision de le mettre dans une librairie est la meilleure chose à faire

EDIT: +1 pour supergeoffrey
2  1 
Avatar de kedare
Membre expérimenté https://www.developpez.com
Le 28/05/2018 à 20:51
C'est la même chose dans tout les languages, il faut pas "deserializer" des données qui ne sont pas sûre (Never Trust User Input).

Exemple avec Python: https://docs.python.org/3.6/library/pickle.html

Warning The pickle module is not secure against erroneous or maliciously constructed data. Never unpickle data received from an untrusted or unauthenticated source.
Le principe même de la serialization n'est pas sûr car on peut potentiellement bypasser les vérifications qui sont normalement faite a la construction et l'objet pour y passer tout ce qu'on veut.
1  0 
Avatar de vdaburon
Membre à l'essai https://www.developpez.com
Le 30/05/2018 à 18:30
Bonjour,

Les problèmes de sécurité lors de la sérialisation proviennent de la librairie de Apache commons-collections qui en fait "trop" et qui est vulnérable à certains objets sérialisé piégés.
https://foxglovesecurity.com/2015/11...-vulnerability

La sérialisation/désérialisation est une façon en java de passer les paramètres en RMI comme le protocole encore plus ancien Remote Procedure Call (RPC) et aussi CORBA.

Le protocole RMI ou EJB permet de passer efficacement les valeurs des attributs de la classe en binaire.
La taille des échanges est faible à comparer à XML ou JSON.

Le principal problème est que :
- c'est du Java vers du Java et pas pour d'autre langage
- c'est assez difficile à débugger
- difficile à simuler pour des tests de performances
- difficile à répartir la charge entre plusieurs instances

Il faut aussi considérer les objets sérialisés comme des objets à faible durée de vie (un échange réseau) et pas pour du stockage.

Je pense que le protocole RMI/EJB est à utiliser entre 2 applications locales et de confiance.
Il n'est pas adapté pour les échanges entre des applications distantes et ne doit pas être utiliser si on passe par Internet.

Effectivement, RMI est plutôt du passé (comme CORBA).

Un protocole binaire qui peut remplacer efficacement RMI et qui est plus ouvert est le gRPC de Google
https://grpc.io/

Sinon, on utilise aussi JSON pour les échanges entre applications surtout avec des langages différents.

Cordialement
Vincent DAB.
1  0 
Avatar de Grogro
Membre extrêmement actif https://www.developpez.com
Le 01/06/2018 à 15:10
Citation Envoyé par AoCannaille Voir le message
J'ai l'impression de vivre dans un autre monde... Sérialiser en mode texte? sérieusement? à quoi ça peut servir un truc aussi gourmand?
Je ne suis pas dans le web, donc je ne sais pas l'utilité que vous avez de la sérialisation, mais personnellement on l'utilise soit entre applications sur la même machine, soit sur le réseau en radio.
En local, sur les petits objets pourquoi pas, mais dès que ça part sur du réseau, faire passer du texte est horriblement inefficient...

On utilise surtout google protocol buffer pour ça. ça marche plutôt bien.

Le binaire il n'y a que ça d'efficace!
Et moi de vivre dans un tout autre monde que toi, parce que je n'imaginerais pas sérialiser autrement qu'en json ou en xml, sans doute parce que j'ai trop l'habitude de REST et de SOAP. Il y a sans doute une histoire de "golden hammer" dans nos perceptions respectives.

Ce que tu dis est intéressant en tout cas et j'irai découvrir Protocol Buffers dès que j'aurais un peu de temps libre. Je me demandais justement à la lecture de l'article qui sérialise réellement en binaire. Dans quels contextes tu utilises cela ? Comment tu fais pour débuguer ensuite ? Le gain de performance parait indiscutable, mais quelle est la lourdeur du développement ? Comment tu fais pour communiquer tes DTO sérialisés en binaire à d'autres langages ?
1  0 
Avatar de supergeoffrey
Membre expérimenté https://www.developpez.com
Le 28/05/2018 à 15:06
Que pensez-vous de la décision d'Oracle ?
Oui ça sert à rien, il existe des format tierce (JSON, XML) pour sérialiser des objets, et aussi des SGBD (et son équivalent pour le NoSql).
Utilisez-vous souvent la sérialisation en Java ? Est-ce une horrible erreur ?
Non. C'est pas très compliqué à écrire. Mais c'est plus dur à maintenir.
Les plateformes telles que .NET, Ruby et autres sont-elles déjà protégées contre ces attaques ?
J'en sais rien. Mais utiliser des standards permet de migrer plus facilment d'une plateforme à une autre.
2  2