Gestion Sécurisée des Entrées
Cadre Complet de Sécurité des Entrées
Flux de Traitement Sécurisé des Entrées
graph TD
A[Entrée reçue] --> B[Valider la longueur]
B --> C[Désinfecter le contenu]
C --> D[Vérification de type]
D --> E[Validation des limites]
E --> F[Traitement sécurisé]
F --> G[Gestion de la mémoire]
Techniques Avancées de Gestion des Entrées
Technique |
Description |
Impact sur la sécurité |
Validation d'entrée |
Vérifier l'entrée par rapport à des règles prédéfinies |
Prévenir les entrées malveillantes |
Désinfection |
Supprimer/échapper les caractères dangereux |
Réduire les risques d'injection |
Application de type |
S'assurer que l'entrée correspond au type attendu |
Prévenir les vulnérabilités liées aux types |
Protection mémoire |
Gérer les limites de tampon |
Prévenir les dépassements de tampon |
Exemple de Mise en œuvre Sécurisée des Entrées
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_INPUT_LENGTH 100
#define MAX_NAME_LENGTH 50
typedef struct {
char name[MAX_NAME_LENGTH];
int age;
} User;
int sanitize_input(char *input) {
// Supprimer les caractères non alphanumériques
size_t j = 0;
for (size_t i = 0; input[i] != '\0'; i++) {
if (isalnum(input[i]) || input[i] == ' ') {
input[j++] = input[i];
}
}
input[j] = '\0';
return j;
}
User* create_user() {
User *new_user = malloc(sizeof(User));
if (!new_user) {
fprintf(stderr, "Échec de l'allocation mémoire\n");
return NULL;
}
// Entrée sécurisée du nom
char name_buffer[MAX_INPUT_LENGTH];
printf("Entrez le nom : ");
if (fgets(name_buffer, sizeof(name_buffer), stdin) == NULL) {
free(new_user);
return NULL;
}
// Suppression de la nouvelle ligne
name_buffer[strcspn(name_buffer, "\n")] = 0;
// Désinfection et validation du nom
if (sanitize_input(name_buffer) == 0 ||
strlen(name_buffer) >= MAX_NAME_LENGTH) {
free(new_user);
return NULL;
}
// Copie sécurisée du nom
strncpy(new_user->name, name_buffer, MAX_NAME_LENGTH - 1);
new_user->name[MAX_NAME_LENGTH - 1] = '\0';
// Entrée sécurisée de l'âge
printf("Entrez l'âge : ");
if (scanf("%d", &new_user->age) != 1 ||
new_user->age < 0 || new_user->age > 120) {
free(new_user);
return NULL;
}
// Vider le tampon d'entrée
while (getchar() != '\n');
return new_user;
}
int main() {
User *user = create_user();
if (user) {
printf("Utilisateur créé : %s, Âge : %d\n", user->name, user->age);
free(user);
} else {
printf("Échec de la création de l'utilisateur\n");
}
return 0;
}
Stratégies de Sécurité des Entrées
-
Validation Exhaustive
- Vérifier la longueur de l'entrée
- Valider le type de l'entrée
- Appliquer des règles de contenu
-
Techniques de Désinfection
- Supprimer les caractères spéciaux
- Échapper les caractères potentiellement dangereux
- Normaliser le format de l'entrée
Recommandations de Sécurité LabEx
Chez LabEx, nous insistons sur :
- Implémenter une validation d'entrée multicouche
- Utiliser une désinfection spécifique au contexte
- Employer des techniques de programmation défensive
Mécanismes de Protection Avancés
graph LR
A[Entrée] --> B{Vérification de longueur}
B --> C{Désinfection}
C --> D{Validation de type}
D --> E{Vérification de limites}
E --> F[Traitement sécurisé]
Considérations de Sécurité Mémoire
- Allouer toujours dynamiquement la mémoire
- Utiliser
strncpy()
au lieu de strcpy()
- Implémenter des vérifications de limites strictes
- Libérer immédiatement la mémoire allouée après utilisation
Meilleures Pratiques de Gestion des Erreurs
- Fournir des messages d'erreur clairs
- Enregistrer les événements liés à la sécurité
- Implémenter des mécanismes de défaillance en douceur
- Ne jamais exposer les détails du système dans les sorties d'erreur
En adoptant ces techniques de gestion sécurisée des entrées, les développeurs peuvent créer des programmes C robustes et résilients qui atténuent efficacement les risques de sécurité potentiels.