Quels sont les risques / vulnérabilités de sécurité dont chaque programmeur C doit être conscient? [fermé]

13

Il existe de nombreux risques de sécurité liés à un contact étroit avec le matériel, par opposition à l'utilisation d'API bien testées et éprouvées à partir de langages de programmation de haut niveau. Il est beaucoup plus facile de provoquer un débordement de tampon en C que dans un langage tel que Java.

Quels sont les risques ou vulnérabilités (par exemple, les dépassements de tampon) que chaque programmeur C devrait connaître (vulnérabilités IE pertinentes pour les programmeurs C)? À quels problèmes cela pourrait-il conduire? Comment les éviter et quelles sont les erreurs courantes qui provoquent ces erreurs dans les programmes?

Anto
la source
Qu'en est-il de cette liste: owasp.org/index.php/Category:OWASP_Top_Ten_Project Que faut- il de plus que cela?
S.Lott
2
@ S.Lott: Cela semble concerner beaucoup les problèmes de sécurité dans le développement Web. Il semble y avoir plus de ressources à ce sujet en général que ce que je demande réellement, semble-t-il.
Anto
@Anto: Veuillez mettre à jour la question pour faire la distinction entre toutes les ressources sur la sécurité et la sécurité dont vous parlez.
S.Lott
@ S.Lott: Je ne sais pas trop ce que tu veux dire. Je demande une sécurité qui est importante pour la plupart des programmeurs C, c'est-à-dire des choses comme les débordements de tampon et d'autres choses qui sont possibles en C.
Anto
@Anto: "Il semble y avoir plus de ressources sur cette [sécurité Web?] En général que ce que je demande réellement" On dirait que vous posez des questions sur une sécurité qui n'est pas la sécurité Web. Vrai? Si oui, veuillez mettre à jour la question pour expliquer ce que vous recherchez. Faux? Ensuite , vous êtes interrogez sur la sécurité web, dans ce cas, pourquoi ne pas la liste de OWASP mentionné dans votre question?
S.Lott

Réponses:

13

Les débordements de tampon sont importants. Rien en C n'est vérifié par plage par défaut, il est donc très facile d'écraser un tampon. Il existe une fonction de bibliothèque standard gets(), qui ne peut pas être empêchée de déborder du tampon, et ne devrait presque jamais être utilisée.

Il existe certaines techniques au niveau de l'implémentation pour entraver l'exploitation, telles que le brouillage des blocs de tas, mais cela n'arrêtera pas les débordements de tampon dans les tampons locaux, ce qui peut souvent faire des choses intéressantes comme changer l'adresse à laquelle une fonction retournera.

Il n'y a pas de bonne solution générale en C. De nombreuses fonctions de bibliothèque ont des versions qui limiteront la quantité à écrire. bien que le calcul puisse être maladroit. Il existe des logiciels qui peuvent détecter les débordements de tampon de tas dans le test, tant que le test approprié est exécuté, et le débordement de pile apparaîtra souvent comme un crash lors des tests. À part cela, c'est une question de codage et de révision du code.

Un problème connexe est le problème de l'écriture dans un tampon trop petit d'un caractère, oubliant qu'une chaîne C de n caractères nécessite n + 1 caractères en mémoire, à cause du '\0'terminateur. Si l'attaquant parvient à stocker une chaîne sans le terminateur, toute fonction C s'attendant à ce qu'une chaîne continue son traitement jusqu'à ce qu'elle atteigne un octet zéro, ce qui pourrait entraîner la copie ou la sortie de plus d'informations que souhaité (ou la suppression de la mémoire protégée pour une attaque DOS ). La solution, encore une fois, est la sensibilisation, le soin et les revues de code.

Il y a un autre risque avec la printf()famille. Si vous écrivez char * str; ... printf(str);, vous vous installez pour des problèmes si strcontient un «%» lors de l'impression. La %ndirective format permet printf()d'écrire en mémoire. La solution est printf("%s", str);ou puts(str);. (Utilisez également le C99 snprintf()au lieu de sprintf().)

L'utilisation d'entiers non signés, en particulier comme index de boucle, peut entraîner des problèmes. Si vous attribuez une petite valeur négative à un non signé, vous obtenez une grande valeur positive. Cela peut compromettre des choses comme le traitement uniquement de N instances de quelque chose, ou dans des fonctions limitées comme strncpy(). Examinez tous les entiers non signés. Vous voudrez peut-être éviter unsigned short, car une grande valeur dans l'un d'eux se convertira en une grande valeur positive dans un int.

N'oubliez pas qu'une constante de caractère, en C, est en fait un int. Écrire quelque chose comme char c; while((c = getchar()) != EOF) ...peut facilement échouer, car EOFil ne sera pas représentable dans un fichier char.

Il y a beaucoup plus d'erreurs C caractéristiques auxquelles je peux penser, mais cela pourrait causer des problèmes de sécurité.

David Thornley
la source
Il n'est pas nécessaire d'utiliser printf("%s", str)pour une chaîne nue quand puts(str)fera le même travail.
Blrfl
@Blrfl mais putsajoute un caractère de nouvelle ligne alors printfque non.
droite
Pourrait aussi faire fputs(str, stdout), ce qui n'est pas le cas.
Blrfl
Quant au débordement d'entier: utiliser des entrées signées n'est pas une solution, car les déborder entraînera UB. La seule solution (douloureuse) consiste soit à prouver formellement que vous ne déborderez jamais, soit à vérifier lors de l'exécution (mais vérifiez correctement, ce qui est également délicat sans déborder dans la vérification).
sleske
@DavidThornley: La fonction C11 et C ++ 14 supprimée obtient () de la bibliothèque standard en raison de sa dangerosité.
Destructor
5

Certains des risques spécifiques à C incluent: les débordements de tampon , les attaques de formatage de chaînes et les débordements d'entiers .

Nemanja Trifunovic
la source
1
Il n'y a rien de spécifique à C sur les débordements de tampon - tout langage avec des pointeurs peut avoir cela. Les débordements d'entier s'appliquent à n'importe quel langage et peuvent également se produire facilement dans le code managé.
Steve
1
@Steve, ce ne sont pas vraiment des pointeurs qui causent ce problème mais comment le langage n'applique pas les limites du tableau.
Doug T.
2
@Steve, la question ne portait pas sur des choses qui ne concernent que C, mais quelque chose que les programmeurs C devraient savoir.
AttackingHobo
1
@Steve: C est inhabituellement sensible aux débordements de tampon, en partie à cause du manque de prise en charge de la vérification de plage et du nombre de fonctions de bibliothèque qui satureront volontiers les tampons pour vous.
David Thornley
Je comprends que la question se pose sur C en particulier, mais je pense qu'il vaut la peine de clarifier si la réponse est lue hors contexte que ces risques sont plus généraux. En particulier, les développeurs de code managé sont (à mon humble avis) beaucoup trop complaisants en matière de sécurité, et les débordements d'entiers en particulier affectent la plupart des langues.
Steve
4

Voici un risque facile à manquer qui peut causer des problèmes dont la résolution prendra des heures.

Considérez le code suivant, qui se compilera sans problème.

if(lpstr_current_state = CONST_EMERGENCY_STATE_HOLY_CRAP)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

Lorsque vous vérifiez pour voir si lpstr_current_stateest en fait, CONST_EMERGENCY_STATE_HOLY_CRAPvous attribuez. Il est préférable de toujours mettre la variable constante à gauche. Lorsque vous placez la constante à gauche, le compilateur échoue car vous ne pouvez pas attribuer de valeur à une variable.

if(CONST_EMERGENCY_STATE_HOLY_CRAP = lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}

Ensuite, vous pouvez facilement vous dire: "Putain de merde, ça aurait pu être mauvais", tout en fixant le code à lire ...

if(CONST_EMERGENCY_STATE_HOLY_CRAP == lpstr_current_state)
{
    do_warn_joint_chiefs_of_staff_of_nuclear_attack();
}
Kristofer Hoch
la source
7
C'est facile pour un compilateur d'attraper et de signaler comme avertissement, contrairement à d'autres problèmes. Malheureusement, tous les compilateurs ne facilitent pas la tâche.
David Thornley
2
Cela peut arriver dans des langages autres que C, n'importe quel langage qui utilise =et ==.
FrustratedWithFormsDesigner
3
Ce n'est pas non plus vraiment une vulnérabilité de sécurité, c'est un bug.
Chris Pitman
1
Ce sont les conditions de Yoda.
2
@Kristofer Hoch: Si nous appelons un bogue C probable un risque et le considérons ici, nous aurons besoin d'un forum beaucoup plus grand.
David Thornley
0

Il n'y a qu'un seul risque de sécurité: le fait qu'il y ait des gens à l'extérieur qui feront de leur mieux pour détecter toute vulnérabilité dans votre logiciel et l'exploiter à leur propre avantage. Tout le reste en découle.

Donc, quand vous pensez que "personne dans son bon sens ne le ferait ...", alors vous devez penser immédiatement "sauf que quelqu'un qui veut pirater les ordinateurs des autres ferait exactement cela".

La plus grande conséquence est que chaque fois que vous réagissez à des événements extérieurs (par exemple, en traitant des données transmises de l'extérieur), vous devez supposer que ces données étaient sous le contrôle de votre pire ennemi.

gnasher729
la source
Bien que je sois d'accord avec les paragraphes deux et trois, mettre tout le blâme sur l'attaquant est un peu épais à mes yeux. Il en faut toujours deux pour une attaque réussie: un programmeur qui bousille et un attaquant qui attrape le programmeur dans l'acte. Cependant, la vulnérabilité de sécurité est là avant que l'attaquant ne puisse l'exploiter. Et pour cela, le programmeur est à blâmer.
cmaster - réintègre monica