Le C++ moderne « ne nous sauvera pas », car il est moins sécurisé que les nouveaux langages,
Selon Alex Gaynor

Le , par Bill Fassinou

45PARTAGES

29  2 
Le monde informatique et plus particulièrement le domaine de la programmation n’a pas l’habitude de délaisser les technologies qu’il a vues naître notamment les langages de programmation. Le Cobol a traversé pas mal de décennies déjà et a fêté, il y a peu, ses soixante ans, le C est toujours en activité et répond présent lorsqu’il s’agit de développer ou de construire des systèmes d’exploitation et, même si le Fortran et le Pascal ou encore le langage Haskell ne couvrent plus une grande partie de la communauté, ils existent toujours et sont utilisés par quelques développeurs. Pourtant les nouveaux langages sont là. Ces derniers que plusieurs appellent les jeunes langages, promettent la robustesse, moins ou l’absence de vulnérabilités, la sécurité par défaut ainsi que de la rapidité.

Ces nouveaux langages sont-ils plus utiles que les anciens ? Si oui, faudrait-il que les développeurs pensent à faire le saut vers ces langages ? Selon Alex Gaynor, un ingénieur, qui a souligné quelques défauts du C et du C++ dans un billet de blog, il est plus que temps pour que les développeurs pensent à migrer vers d’autres langages plus modernes comme Rust, le langage développé par Mozilla Research ou Swift, car, dit-il, ces langages sont sécurisés par défaut. Cependant, dans la plupart du temps, la conception de ces nouveaux langages de programmation a été fortement influencée par l'expérience acquise avec les langages précédents, qu’il s’agisse de la syntaxe ou encore d’autre chose. Le langage Rust par exemple est lui fortement influencé par le C et le C++.

Même si c’est le cas, Alex considère néanmoins ces langages plus sécurisés que leurs prédécesseurs, le C vieux d’un peu moins de 50 ans et le C++ apparu courant 1983. D’après les tests présentés et les explications d’Alex Gaynor, le C et C++ induisent un nombre très considérable de failles de sécurité au sein des applications dont ils sont l’outil de conception. « Ma conclusion basée sur l'examen des preuves de nombreux projets logiciels de grande envergure utilisant C et C ++, est qu'il est nécessaire de migrer notre secteur vers des langages sécurisés par défaut tels que Rust et Swift », propose-t-il comme solution aux nombreux problèmes qu’il a soulignés.

Il estime que, même si le C++, dans sa forme moderne, a apporté quelques fonctionnalités remarquables comme les pointeurs intelligents pour résoudre un certain nombre de ces problèmes, il n’en demeure pas moins qu’il « ne nous sauvera pas ». Alex assure que tous les soucis de vulnérabilité que présente le C++ ne peuvent pas être résolus par les idiomes ou les syntaxes modernes qui lui sont apportées. Ainsi, dans son billet, il met en évidence un certain nombre d'idiomes C++ complètement modernes qui génèrent des vulnérabilités. Il a noté des vulnérabilités permettant de masquer la référence use-after-free et une de ses variantes qui consiste à utiliser le support lambda de C++ pour masquer également une référence, ainsi que d’autres vulnérabilités au sein de la bibliothèque standard du C++, la STL, notamment au niveau des structures de données.


Alex Gaynor

Il affirme que comme toutes les structures de données STL, la méthode operator[] de span n'effectue aucune vérification des limites. Ceci, dit-il, est regrettable, car l’opérateur[] est la façon la plus ergonomique et la plus simple d’utiliser les structures de données. Il continue en disant que std::vector et std::array peuvent théoriquement au moins être utilisés en toute sécurité, car ils offrent une méthode at() vérifiée (« en pratique, je ne l'ai jamais vue faire, mais vous pouvez imaginer un projet utilisant un outil d'analyse statique. qui a simplement interdit les appels à std::vector<T>::operator[] »). span n'offre pas de méthode at(), ni aucune autre méthode qui effectue une recherche contrôlée par les bornes, a-t-il déclaré.

Pour finir, Alex affirme que les idiomes modernes en C++ introduisent de nombreux changements susceptibles d’améliorer sa sécurité. Les pointeurs intelligents expriment mieux les durées de vie attendues, std::span vous permet d’avoir toujours une longueur correcte, std::variant fournit une abstraction plus sûre pour les unions. Cependant, continue-t-il, le C ++ moderne introduit également d'incroyables nouvelles sources de vulnérabilités en plus de ceux qu’il a hérités du C. À ce propos, rappelons que le mois passé, WhiteSource a présenté un index selon lequel le langage C serait le langage de programmation le plus vulnérable aux failles de sécurité les plus connues dans la communauté open source.

WhiteSource a indiqué qu’en dix ans, C a montré un nombre de vulnérabilités très important. Il a été donc placé en tête de la liste des langages les plus vulnérables avec une faiblesse reconnue à 47 % de toutes les vulnérabilités signalées. Pour former le trio des langages présentant le nombre de vulnérabilités le plus élevé, le PHP et le Java suivent respectivement avec 17 % et 12 % des vulnérabilités connues. Le JavaScript vient en quatrième place avec 11 %, le Python et le C++ restent en cinquième place avec 6 % chacun et le Ruby ferme le podium avec un nombre de vulnérabilités open source connu de 5 %. Il a été présenté comme le langage le moins vulnérable parmi les sept langages de l’étude.

Cela dit, Alex a-t-il raison d’affirmer que les langages Rust ou Swift sont plus sécurisés que le C et le C++ ? Non pour certains adeptes de ces deux langages de programmation. Ils ne sont pas du tout d’accord avec l’index de WhiteSource et encore moins avec ce qu’affirme Alex. Pour eux, le problème n'est pas les langages C/C ++ eux-mêmes, mais que ce sont les développeurs qui implémentent des systèmes sans trop penser à bien les sécuriser comme cela se doit. D’autres expliquent que le C++ se retrouve être un langage de programmation très sécurisé lorsqu’on ne fait pas usage des fonctionnalités qu’il a héritées du C. Le C serait-il le langage en tort ?

Dans le même temps, certaines donnent raison à Alex Gaynor. « Un problème important que j'ai eu avec C++ est que, même si votre base de code est du pur C++ 17, la bibliothèque standard est un monstre de Frankenstein hérité du C++ moderne qui nécessite de nombreux compromis. Une bibliothèque standard qui présente les capacités du C++ 17 de manière propre devrait supprimer une bonne partie de la compatibilité ascendante dans les environnements C++ modernes », affirme l’un d’entre eux. Pour éviter ce problème, d’autres préfèrent utiliser leurs propres bibliothèques.

« C++ étant mon langage principal, pour travailler sur mes bases de code, j'ai abandonné la bibliothèque standard et mis en œuvre mon propre remplacement. Je suis sûr que ce n'est pas du tout pratique, mais cela me permet de faire évoluer la bibliothèque avec de nouvelles révisions du standard C++ sans être absolument fixé sur la compatibilité ascendante », a ajouté un autre. De son côté, Alex a continué d’insister sur le fait qu'il serait plus judicieux d’utiliser des langages sécurisés par défaut. « Mon expérience professionnelle avec le C++ relativement moderne et de l’audit du code Rust (y compris du code Rust qui fait un usage important de l’insécurité) est que la sécurité du C++ moderne n’est tout simplement pas la même que celle des langages sûrs comme Rust et Swift », a-t-il déclaré.

Source : Billet de blog

Et vous ?

Êtes-vous du même avis qu'Alex Gaynor ? Pourquoi ?
Avez-vous aussi été confronté à ces problèmes avec votre code ou dans du code legacy ?
Faut-il abandonner le C et le C++ pour d'autres langages comme Rust ou Swift comme il le propose ? Pourquoi, selon vous ?

Voir aussi

Le langage de programmation Cobol fête ses 60 ans, peut-il encore tenir longtemps face à la concurrence des nouveaux langages ?

Quel langage de programmation comporte le plus de vulnérabilités en matière de sécurité ? Une étude de WhiteSource

Quelle est la plateforme de développement ou le langage le plus exposé aux vulnérabilités ? Une étude de Veracode donne des éléments de réponse

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

Avatar de Spleeen
Membre régulier https://www.developpez.com
Le 24/04/2019 à 0:33
Je déplore tout de même le faible nombre de commentaires sur des articles très bien rédigés, sans faute de français et bien sourcé qui méritent la lecture.

Pour eux, le problème n'est pas les langages C/C ++ eux-mêmes, mais que ce sont les développeurs qui implémentent des systèmes sans trop penser à bien les sécuriser comme cela se doit
Tout est dit selon moi. Il a beau dire, ces exemples sont très TRÈS circonstanciels :
- Avez-vous déjà trouvé, d'autant plus dans une section critique en production (sachant que certains ne sont disponible qu'en C++17), un std::variant

Une bibliothèque standard qui présente les capacités du C++ 17 de manière propre devrait supprimer une bonne partie de la compatibilité ascendante dans les environnements C++ modernes
Faire comme D dès le début, table rase du passé. On sort enfin les ranges, on trouve mieux que ces maudits itérateurs, on vire ces machines à états cin/cout/cerr, on blinde la SL/STL parce que mis à part les conteneurs simples c'est vide en algo…
Avatar de Mingolito
Membre extrêmement actif https://www.developpez.com
Le 24/04/2019 à 1:34
Citation Envoyé par Spleeen Voir le message
Je déplore tout de même le faible nombre de commentaires sur des articles très bien rédigés, sans faute de français et bien sourcé qui méritent la lecture.
C'est en ce moment les "vacances" en RP... donc la ou sont basés la majorité des développeurs...

Sinon à part ça : Il n'y a rien de mieux que le langage de programmation C pour le développement de systèmes d'exploitation d'après Linus Torvalds
Avatar de lsbkf
Membre régulier https://www.developpez.com
Le 24/04/2019 à 2:35
C'est qui lui ? Oh un ingénieur. Si c'est un ingénieur, c'est qu'il a forcément raison !!
Blague à part, c'est écrit où que C++ recherchait la sécurité ? operator[] ne vérifie pas les dépassements, pauvre petit chou. Et alors, si t'en veux pas tu l'utilises pas, mais après c'est qui qui doit se plaindre de ces applications qui bouffent tout le CPU comme s'ils étaient seuls à s'exécuter.
Avatar de darklinux
Membre actif https://www.developpez.com
Le 24/04/2019 à 3:18
Bref , un langage sécurisé " par nature " , cela n existe pas , on la vu avec les deux premières versions de Java . C 'est le travail du développeur ça , à la limite du framework , mais c 'est tout
Avatar de Bousk
Rédacteur/Modérateur https://www.developpez.com
Le 24/04/2019 à 3:40
Citation Envoyé par lsbkf Voir le message
operator[] ne vérifie pas les dépassements
Ce qui est voulu mais en plus non toujours vrai.
Sur vs2017 l'implémentation est la suivante
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
_NODISCARD _Ty& operator[](const size_type _Pos)
		{	// subscript mutable sequence
 #if _ITERATOR_DEBUG_LEVEL == 2
		if (size() <= _Pos)
			{	// report error
			_DEBUG_ERROR("vector subscript out of range");
			}
 #elif _ITERATOR_DEBUG_LEVEL == 1
		_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
 #endif /* _ITERATOR_DEBUG_LEVEL */
 
		return (this->_Myfirst()[_Pos]);
		}
Donc oui il y a vérification en debug, et aucune en release, comme tout bon code devrait logiquement faire.
Avatar de lsbkf
Membre régulier https://www.developpez.com
Le 24/04/2019 à 3:48
Citation Envoyé par Bousk Voir le message
Donc oui il y a vérification en debug, et aucune en release, comme tout bon code devrait logiquement faire.
C'est aussi le cas dans GCC (à voir dans quels cas la macro _GLIBCXX_ASSERTIONS est définie), et il y a des chances pour que LLVM soit aussi dans le coup. Mais évidemment c'est plus facile de taper sur C++ dans un billet de blog !
Avatar de jo_link_noir
Membre émérite https://www.developpez.com
Le 24/04/2019 à 4:03
Citation Envoyé par darklinux Voir le message
Bref , un langage sécurisé " par nature " , cela n existe pas
Peut-être, mais certains se le veulent plus que d'autres. Le coup des références invalident est très facile à faire en C++, et à contrario, difficile à diagnostiquer. Un exemple tout bête:

Code : Sélectionner tout
1
2
3
 
char const* cstr = to_string(x).c_str();
foo(cstr); // oups to_string retourne un temporaire et cstr pointeur sur un pointeur désalloué.
Ok, c_str() sert principalement pour les vieux code ou les bibliothèques C, mais il existe des problèmes similaires avec une lambda qui capture une référence pour lesquels le compilateur ne dira absolument rien. Ce n'est pas pour rien qu'il y a une option -Wlifetime en cours de développement dans clang, même si cela ne pourra pas tout détecter.

Alors que les langages comme Rust intègre au cœur même du langage une vérification sur le partage et le propriétaire d'une valeur. Le code du genre au-dessus ne compilera simplement pas. Les nouveaux langages essayent aussi d'avoir comportement plus sûr par défaut comme l'immutabilité, pas de conversion implicite, etc et une syntaxe qui laisse moins de place aux erreurs.

Donc, un langage entièrement sécurisé n'existe probablement pas, mais les langages plus sûrs, si.

EDIT: Pour libc++ il y a _LIBCPP_DEBUG=1, mais j'ai déjà eu des bugs avec :/. Pour libstdc++, il y _GLIBCXX_DEBUG, plus violent que _GLIBCXX_ASSERTIONS, mais qui change l'abi.
Avatar de ShigruM
Nouveau Candidat au Club https://www.developpez.com
Le 24/04/2019 à 8:06
Citation Envoyé par Spleeen Voir le message
Je déplore tout de même le faible nombre de commentaires sur des articles très bien rédigés, sans faute de français et bien sourcé qui méritent la lecture.
peut etre parcequ'il n'ya rien a commenter...
L'article parle juste d'un haineux qui n'aime pas le C++... on vas pas pour autant abandonner le c++ suite a cela... sont article de blog je l'ai déja oublié.
ce genre d'article de "ouain ouains le langage X est pourrie" tu en as pour tous les langages.

Aucun langage n'est parfait, donc tous les langage sont critiquitable donc les gens cherche a les critiquer mais nous somme sau dessus de cela et le mieu c'est d'ignorer ce genre d'article comme je le fait.
voila pouruqoi personne ne commente cela, car cela n'en vaut pas la peine.
Avatar de sergio_is_back
Membre chevronné https://www.developpez.com
Le 24/04/2019 à 8:19
Si on cherche la sécurité à tout prix alors il faut éviter d'écrire une seule de code.... Même dans un langage très cadré un développeur peut induire des biais qui seront acceptés par le compilateur et mèneront à la catastrophe...
Avatar de wolinn
Membre éprouvé https://www.developpez.com
Le 24/04/2019 à 8:36
On peut toujours construire des exemples pour mettre en évidence la faible sécurisation du langage, mais en pratique, c'est un problème surtout pour les débutants ou les programmeurs peu rigoureux, ou peut-être dans des contextes où on demande aux gens de produire du code au kilomètre le plus vite possible et sans grande contrainte pour les performances du produit final.
Dans ces situations, en effet, il peut y avoir mieux que le C++.
Pour ce qui est des 'lambda', c'est une construction nouvelle (bien que ça ait déjà 8 ans), je considère que je n'en maitrise pas encore toutes les subtilités, et donc j'évite simplement les constructions trop audacieuses pour l'instant. Après tout, j'écrivais en C++ presque 20 ans avant que ça existe. Et puis il faut aussi un peu de temps pour avoir confiance dans les compilateurs eux-mêmes.

Je ne connais pas Rust ou Swift, mais j'ai joué un peu avec Julia ces derniers mois. C'est un langage récent, et il y a en effet quelques caractéristiques qui paraissent contribuer à la sécurité (objets immutables par défaut justement), mais la sécurité du langage est très loin dans l'ordre des priorités pour ce que j'ai à faire, j'ai commencé par contrôler les performances en vitesse d'exécution et la gestion de la mémoire.
Attention, je ne dis pas que la fiabilité des logiciels est sans importance, bien au contraire, mais on peut écrire des logiciels robustes dans n'importe quel langage, même en C.
Contacter le responsable de la rubrique C++

Partenaire : Hébergement Web