From e7ae934445d4a043374037f9c9278b301bb266d8 Mon Sep 17 00:00:00 2001 From: Baptiste Buvron Date: Wed, 21 Jun 2023 23:24:43 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Fix:=20-=20affichage=20des=20offres=20admin?= =?UTF-8?q?=20(oragnisation=20et=20salaire)=20-=20Enlever=20des=20logs=20-?= =?UTF-8?q?=20Fix=20menu=20d=C3=A9roulant=20-=20Affichage=20des=20d=C3=A9t?= =?UTF-8?q?ails=20d'une=20offre?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/AdminController.ts | 11 -- app/controllers/CandidatureController.ts | 3 +- app/controllers/OfferController.ts | 15 +++ app/repository/OfferRepository.ts | 2 +- app/repository/UserRepository.ts | 8 -- app/routes/OfferRouter.ts | 3 +- app/views/admin/offres.ejs | 10 +- app/views/admin/utilisateurs.ejs | 13 --- app/views/candidatures.ejs | 2 +- app/views/demandeRecruteur.ejs | 6 +- app/views/fiche/creation.ejs | 13 --- app/views/index.ejs | 1 + app/views/offre/creation.ejs | 14 +-- app/views/offre/offre.ejs | 126 +++++++++++++++++++++++ app/views/recruteur/offres.ejs | 3 +- 15 files changed, 158 insertions(+), 72 deletions(-) create mode 100644 app/views/offre/offre.ejs diff --git a/app/controllers/AdminController.ts b/app/controllers/AdminController.ts index 715e1ce..7a8f86f 100644 --- a/app/controllers/AdminController.ts +++ b/app/controllers/AdminController.ts @@ -22,7 +22,6 @@ export class AdminController { static utilisateurs(req: express.Request, res: express.Response) { UserRepository.getAll().then((users: User[]) => { OrganisationRepository.getAll().then((organisations : Organisation[]) => { - console.log(users); res.render("admin/utilisateurs", { title: "Utilisateurs", organisations: organisations, users, userLogged: loggedInNoRedirection(req, res)}); }); }); @@ -31,7 +30,6 @@ export class AdminController { static utilisateur(req: express.Request, res: express.Response) { let email = req.params.email; UserRepository.getById(email).then((user: User) => { - console.log(user); res.render("admin/utilisateur", {title: "Utilisateur", user: user, userLogged: loggedInNoRedirection(req, res)}); }) } @@ -63,13 +61,11 @@ export class AdminController { console.log(err); }); UserRepository.getById(req.body.email).then((user: User) => { - console.log(user); res.render("admin/utilisateur", {title: "Utilisateur", user: user, alerts: alerts, userLogged: loggedInNoRedirection(req, res)}); }) }else{ let email = req.params.email; UserRepository.getById(email).then((user: User) => { - console.log(user); res.render("admin/modifierUtilisateur", { title: "Modifier un utilisateur", user: user, @@ -111,7 +107,6 @@ export class AdminController { static demande(req: express.Request, res: express.Response) { let email = req.params.email; UserRepository.getById(email).then((user: User) => { - console.log(user); res.render("admin/demande", {title: "Demande", user: user, userLogged: loggedInNoRedirection(req, res)}); }) } @@ -119,7 +114,6 @@ export class AdminController { static async accepterDemande(req: express.Request, res: express.Response) { let email = req.params.email; await UserRepository.setDemandAccepted(email).then((email) => { - console.log(email); }); res.redirect("/admin/demandes"); } @@ -127,7 +121,6 @@ export class AdminController { static async refuserDemande(req: express.Request, res: express.Response) { let email = req.params.email; await UserRepository.setDemandRefused(email).then((email) => { - console.log(email); }); res.redirect("/admin/demandes"); } @@ -143,7 +136,6 @@ export class AdminController { static offre(req: express.Request, res: express.Response) { let numero = req.params.numero; OfferRepository.getById(Number.parseInt(numero)).then((offer: OffreDePoste) => { - console.log(offer); res.render("admin/offre", {title: "Offre", offer: offer, userLogged: loggedInNoRedirection(req, res)}); }) } @@ -204,7 +196,6 @@ export class AdminController { }); OfferRepository.getById(Number.parseInt(idOffre)).then((offer: OffreDePoste) => { - console.log(offer); res.render("admin/offre", {title: "Offre", offer: offer, alerts: alerts, userLogged: loggedInNoRedirection(req, res)}); }) }else{ @@ -219,7 +210,6 @@ export class AdminController { const alerts: Alert[] = []; let numero = req.params.numero; await OfferRepository.supprimer(Number.parseInt(numero)).then((suppression: boolean) => { - console.log(suppression); let alert = new Alert("success", "L'offre a été supprimée"); alerts.push(alert); }).catch((err) => { @@ -228,7 +218,6 @@ export class AdminController { alerts.push(alert); }); OfferRepository.getAll().then((offers: OffreDePoste[]) => { - console.log(offers); res.render("admin/offres", {title: "Offres", alerts: alerts, offers: offers, userLogged: loggedInNoRedirection(req, res)}); }); } diff --git a/app/controllers/CandidatureController.ts b/app/controllers/CandidatureController.ts index ef62253..b44399b 100644 --- a/app/controllers/CandidatureController.ts +++ b/app/controllers/CandidatureController.ts @@ -14,7 +14,6 @@ export class CandidatureController { static candidater(req: express.Request, res: express.Response) { //TODO Vérifier que l'utilisateur est bien un candidat - let user: User = new User('tsoudar21@gmail.com', 'Tillai', 'Soudarsane', '0652645299', new Date('2020-10-10'), false, 'mdp', 'Candidat', "", null); let alerts: Alert[] = []; let numero: number = Number.parseInt(req.params.numero); @@ -26,7 +25,7 @@ export class CandidatureController { let alert = new Alert("danger", "La motivation doit faire plus de 20 caractères."); alerts.push(alert); } else { - let user: User = new User('candidat1@example.com', 'Doe', 'John', '123456789', new Date(), true, 'password123', 'Candidat', 'En attente', null); + let user: User = req.user as User; let candidature: Candidature = new Candidature(new Date(), user, offer, StatutCandidatureEnum.EN_ATTENTE, req.body.motivation); await CandidatureRepository.create(candidature).then(async (candidature) => { //upload file: diff --git a/app/controllers/OfferController.ts b/app/controllers/OfferController.ts index 53d4612..f0a235f 100644 --- a/app/controllers/OfferController.ts +++ b/app/controllers/OfferController.ts @@ -79,4 +79,19 @@ export class OfferController { csrfToken: req.session.csrfSecret }); } + + public static offre(req: express.Request, res: express.Response) { + let id: number = parseInt(req.params.numero); + OfferRepository.getById(id).then((offer: OffreDePoste) => { + return res.render("offre/offre", { + title: "Offre", + offer: offer, + userLogged: loggedInNoRedirection(req, res), + csrfToken: req.session.csrfSecret + }); + }).catch((err) => { + console.log(err); + return res.redirect("/offre/liste"); + }) + } } diff --git a/app/repository/OfferRepository.ts b/app/repository/OfferRepository.ts index 387c40f..9416da3 100644 --- a/app/repository/OfferRepository.ts +++ b/app/repository/OfferRepository.ts @@ -47,7 +47,7 @@ export class OfferRepository { let ficheDePoste; let organisation; for (let i = 0; i < result.length; i++) { - organisation = new Organisation(result[0].siren, result[0].nom, result[0].type, result[0].siege); + organisation = new Organisation(result[i].siren, result[i].nom, result[i].type, result[i].siege); ficheDePoste = new FicheDePoste(result[i].fiche_numero, result[i].status, result[i].responsable, result[i].type_metier, result[i].lieu, result[i].teletravail, result[i].nb_heures, result[i].salaire, result[i].description, result[i].siren, organisation); result[i] = new OffreDePoste(result[i].offre_numero, result[i].etat, result[i].date_validite, result[i].nb_piece, result[i].liste_piece, ficheDePoste); } diff --git a/app/repository/UserRepository.ts b/app/repository/UserRepository.ts index 1cd1629..faef7f4 100644 --- a/app/repository/UserRepository.ts +++ b/app/repository/UserRepository.ts @@ -18,7 +18,6 @@ export class UserRepository { if (err) { return reject(err); } - console.log(result); let organisation = new Organisation( result[0].siren, result[0].organisation, @@ -39,7 +38,6 @@ export class UserRepository { undefined ); - console.log(user); return resolve(user); } ) @@ -59,7 +57,6 @@ export class UserRepository { let organisation; let user; - console.log(result) for (let i = 0; i < result.length; i++) { organisation = new Organisation( result[i].siren, @@ -82,7 +79,6 @@ export class UserRepository { ); result[i] = user; } - console.log(result) return resolve(result); } @@ -151,10 +147,8 @@ export class UserRepository { return reject(err); } if(result[0]){ - console.log(result[0]); let organisation = new Organisation(result[0].siren, result[0].organisation, result[0].type, result[0].siege); result[0].organisation = organisation; - console.log(result); } return resolve(result); } @@ -175,10 +169,8 @@ export class UserRepository { return reject(err); } if(result[0]){ - console.log(result[0]); let organisation = new Organisation(result[0].siren, result[0].organisation, result[0].type, result[0].siege); result[0].organisation = organisation; - console.log(result); } return resolve(result); } diff --git a/app/routes/OfferRouter.ts b/app/routes/OfferRouter.ts index 1fe99e0..13b339e 100644 --- a/app/routes/OfferRouter.ts +++ b/app/routes/OfferRouter.ts @@ -1,6 +1,6 @@ import express from "express"; import {OfferController} from "../controllers/OfferController"; -import {defaultRouter} from "./MainRouter"; + const { passport, loggedIn, checkRole } = require("../passport/passportFunctions"); export const offerRouter = express.Router(); @@ -8,3 +8,4 @@ offerRouter.use(passport.initialize()); offerRouter.use(passport.session()); offerRouter.get("/creation", checkRole("Recruteur"), OfferController.creation); offerRouter.post("/creation", checkRole("Recruteur"), OfferController.creation); +offerRouter.get("/:numero", OfferController.offre); diff --git a/app/views/admin/offres.ejs b/app/views/admin/offres.ejs index 7d0fbd2..d2bbd5f 100644 --- a/app/views/admin/offres.ejs +++ b/app/views/admin/offres.ejs @@ -18,14 +18,16 @@ <% }) %> - +

Offres d'emploi

- <% offers.forEach((offer) => {%> + <% offers.forEach((offer) => { %>
-

<%= offer.ficheDePoste.typeMetier %> 45000 €

+

<%= offer.ficheDePoste.typeMetier %> <%= offer.ficheDePoste.salaire %> € +

<%= offer.ficheDePoste.description %>

-

Organisation : <%= offer.ficheDePoste.siren %>

+

Organisation : <%= offer.ficheDePoste.organisation.nom %>

Détail
<% }) %> diff --git a/app/views/admin/utilisateurs.ejs b/app/views/admin/utilisateurs.ejs index cf60056..a760c34 100644 --- a/app/views/admin/utilisateurs.ejs +++ b/app/views/admin/utilisateurs.ejs @@ -1,16 +1,3 @@ - - - - - Utilisateurs - - - - - <%- include('../partials/adminHeader.ejs') %>.
diff --git a/app/views/candidatures.ejs b/app/views/candidatures.ejs index 3cdfdca..87bac5e 100644 --- a/app/views/candidatures.ejs +++ b/app/views/candidatures.ejs @@ -9,7 +9,7 @@ class="badge text-bg-secondary float-end"><%= candidature.offre.ficheDePoste.salaire %> €

<%= candidature.offre.ficheDePoste.description %>

-

Organisation : Nom de l'<%= candidature.offre.ficheDePoste.siren %>

+

Organisation : <%= candidature.offre.ficheDePoste.organisation.nom %>

Status : <%= candidature.statut %> €

Voir la diff --git a/app/views/demandeRecruteur.ejs b/app/views/demandeRecruteur.ejs index f2889e8..2a2e66c 100644 --- a/app/views/demandeRecruteur.ejs +++ b/app/views/demandeRecruteur.ejs @@ -1,4 +1,5 @@ -<%- include('partials/header.ejs') %>. +<%- include('partials/header.ejs') %> +
- - - diff --git a/app/views/fiche/creation.ejs b/app/views/fiche/creation.ejs index fdad785..5a47e57 100644 --- a/app/views/fiche/creation.ejs +++ b/app/views/fiche/creation.ejs @@ -1,16 +1,3 @@ - - - - - <%= title %> - - - - - <%- include('../partials/recruteurHeader.ejs') %> <% }) %>
diff --git a/app/views/offre/creation.ejs b/app/views/offre/creation.ejs index 1d5bdc6..d06b45b 100644 --- a/app/views/offre/creation.ejs +++ b/app/views/offre/creation.ejs @@ -1,17 +1,5 @@ - - - - - <%= title %> - - - - - <%- include('../partials/recruteurHeader.ejs') %> +<%- include('../partials/recruteurHeader.ejs') %>
diff --git a/app/views/offre/offre.ejs b/app/views/offre/offre.ejs new file mode 100644 index 0000000..86488df --- /dev/null +++ b/app/views/offre/offre.ejs @@ -0,0 +1,126 @@ +<% if (user) { %> + <% if (user.role === 'Recruteur') { %> + <%- include('../partials/recruteurheader.ejs') %> + <% } else { %> + <%- include('../partials/header.ejs') %> + <% } %> +<% } %> + +
+
+
+ + Image création d'entreprise + + + +
+

Offre : <%= offer.ficheDePoste.typeMetier %>

+
+
+
+

Description

+

<%= offer.ficheDePoste.description %>

+
+
+

Offre

+
+ + +
+
+ + +
+ +
+

Organisation

+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+
+

Pièces à déposer

+ + <% var list = offer.listePiece.split(',') %> + <% list.forEach((element) => { %> +

•<%= element %>

+ <% }) %> + +
+
+ +
+ +

Fiche de poste

+ + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+
+ + diff --git a/app/views/recruteur/offres.ejs b/app/views/recruteur/offres.ejs index 2d828c7..c3fb95e 100644 --- a/app/views/recruteur/offres.ejs +++ b/app/views/recruteur/offres.ejs @@ -6,10 +6,11 @@ <% offers.forEach((offer) => { %>

<%= offer.ficheDePoste.typeMetier %> 45000 € + class="badge text-bg-secondary float-end"><%= offer.ficheDePoste.salaire %> €

<%= offer.ficheDePoste.description %>

Organisation : <%= offer.ficheDePoste.organisation.nom %>

+ Voir l'offre
<% }) %>
From 0fd0fd29d23f235a5ebfac2a4b10faf16ed53a98 Mon Sep 17 00:00:00 2001 From: Baptiste Buvron Date: Wed, 21 Jun 2023 23:45:01 +0200 Subject: [PATCH 2/2] Fix + securite.md --- app/views/admin/index.ejs | 14 +------ securite.md | 87 ++++++++++++++++++++++++++++++--------- 2 files changed, 68 insertions(+), 33 deletions(-) diff --git a/app/views/admin/index.ejs b/app/views/admin/index.ejs index 4bbe308..47257e6 100644 --- a/app/views/admin/index.ejs +++ b/app/views/admin/index.ejs @@ -1,16 +1,3 @@ - - - - - Accueil - - - - - <%- include('../partials/adminHeader.ejs') %>.
@@ -50,6 +37,7 @@

<%= offer.ficheDePoste.description %>

Organisation : <%= offer.ficheDePoste.organisation.nom %>

+ Voir l'offre
<% }) %>
diff --git a/securite.md b/securite.md index 5a4bb9d..f45adcf 100644 --- a/securite.md +++ b/securite.md @@ -2,11 +2,16 @@ ## Introduction -Ce rapport vise à expliquer comment notre application Express.js se protège contre les attaques d'injections SQL lors des requêtes à la base de données. L'injection SQL est une technique couramment utilisée par les attaquants pour manipuler ou compromettre une application en injectant du code SQL non autorisé. Pour prévenir de telles attaques, nous avons mis en place des mesures de sécurité appropriées dans notre code. +Ce rapport vise à expliquer comment notre application Express.js se protège contre les attaques d'injections SQL lors +des requêtes à la base de données. L'injection SQL est une technique couramment utilisée par les attaquants pour +manipuler ou compromettre une application en injectant du code SQL non autorisé. Pour prévenir de telles attaques, nous +avons mis en place des mesures de sécurité appropriées dans notre code. ## Utilisation de placeholders pour les paramètres -Dans notre code, nous utilisons des placeholders sous la forme de points d'interrogation (`?`) pour les paramètres de requête. Ces placeholders permettent de remplacer les valeurs des paramètres par des valeurs réelles lors de l'exécution de la requête, évitant ainsi les injections SQL. +Dans notre code, nous utilisons des placeholders sous la forme de points d'interrogation (`?`) pour les paramètres de +requête. Ces placeholders permettent de remplacer les valeurs des paramètres par des valeurs réelles lors de l'exécution +de la requête, évitant ainsi les injections SQL. Voici un extrait de code qui illustre l'utilisation des placeholders : @@ -20,7 +25,7 @@ if (filterOffer) { params.push(filterOffer.region); } } -return new Promise<[OffreDePoste]>( +return new Promise < [OffreDePoste] > ( (resolve, reject) => pool.query(query, params, (err, result) => { // Gestion des résultats de la requête @@ -28,23 +33,36 @@ return new Promise<[OffreDePoste]>( ); ``` -Dans cet exemple, nous construisons dynamiquement notre requête SQL en ajoutant des conditions basées sur les paramètres fournis. Les valeurs des paramètres sont stockées dans un tableau `params`, et lors de l'exécution de la requête, ces valeurs sont remplacées par les placeholders correspondants. Ainsi, les paramètres ne sont pas interprétés comme du code SQL potentiellement malveillant. +Dans cet exemple, nous construisons dynamiquement notre requête SQL en ajoutant des conditions basées sur les paramètres +fournis. Les valeurs des paramètres sont stockées dans un tableau `params`, et lors de l'exécution de la requête, ces +valeurs sont remplacées par les placeholders correspondants. Ainsi, les paramètres ne sont pas interprétés comme du code +SQL potentiellement malveillant. ## Avantages de l'utilisation de placeholders L'utilisation de placeholders présente plusieurs avantages en termes de sécurité : -1. **Prévention des injections SQL**: En utilisant des placeholders, nous séparons clairement les instructions SQL des données utilisateur. Cela empêche les attaquants d'injecter du code SQL malveillant en manipulant les données fournies. -2. **Protection contre les caractères spéciaux**: Les placeholders assurent l'échappement automatique des caractères spéciaux présents dans les valeurs des paramètres. Cela garantit que ces caractères sont traités comme des données normales et non comme du code SQL potentiellement dangereux. -3. **Facilité d'utilisation**: L'utilisation de placeholders simplifie la construction des requêtes SQL, en évitant la concaténation manuelle des valeurs des paramètres dans la chaîne de requête. Cela réduit les erreurs potentielles et facilite la maintenance du code. +1. **Prévention des injections SQL**: En utilisant des placeholders, nous séparons clairement les instructions SQL des + données utilisateur. Cela empêche les attaquants d'injecter du code SQL malveillant en manipulant les données + fournies. +2. **Protection contre les caractères spéciaux**: Les placeholders assurent l'échappement automatique des caractères + spéciaux présents dans les valeurs des paramètres. Cela garantit que ces caractères sont traités comme des données + normales et non comme du code SQL potentiellement dangereux. +3. **Facilité d'utilisation**: L'utilisation de placeholders simplifie la construction des requêtes SQL, en évitant la + concaténation manuelle des valeurs des paramètres dans la chaîne de requête. Cela réduit les erreurs potentielles et + facilite la maintenance du code. # Protection contre les attaques CSRF (Cross-Site Request Forgery) -En plus de la protection contre les injections SQL, notre application Express.js met également en place des mesures de sécurité pour se prémunir contre les attaques CSRF (Cross-Site Request Forgery). Les attaques CSRF exploitent la confiance d'un utilisateur authentifié pour effectuer des actions non autorisées à son insu. +En plus de la protection contre les injections SQL, notre application Express.js met également en place des mesures de +sécurité pour se prémunir contre les attaques CSRF (Cross-Site Request Forgery). Les attaques CSRF exploitent la +confiance d'un utilisateur authentifié pour effectuer des actions non autorisées à son insu. ## Génération d'un token CSRF unique -Lorsqu'un utilisateur authentifié interagit avec notre application, nous générons un token CSRF unique et l'associons à sa session. Ce token est créé à l'aide d'un middleware qui s'exécute avant chaque requête. Voici un extrait de code illustrant cette fonctionnalité : +Lorsqu'un utilisateur authentifié interagit avec notre application, nous générons un token CSRF unique et l'associons à +sa session. Ce token est créé à l'aide d'un middleware qui s'exécute avant chaque requête. Voici un extrait de code +illustrant cette fonctionnalité : ```javascript export function createCSRFToken(req: any, res: any, next: any) { @@ -58,21 +76,28 @@ export function createCSRFToken(req: any, res: any, next: any) { } ``` -Ce middleware vérifie si l'utilisateur est authentifié et, le cas échéant, génère un token CSRF unique en utilisant la fonction `randomBytes` pour créer une chaîne aléatoire de 64 octets. Ce token est stocké dans la session de l'utilisateur. +Ce middleware vérifie si l'utilisateur est authentifié et, le cas échéant, génère un token CSRF unique en utilisant la +fonction `randomBytes` pour créer une chaîne aléatoire de 64 octets. Ce token est stocké dans la session de +l'utilisateur. ## Utilisation du token CSRF dans les formulaires -Lors du rendu d'un formulaire, nous ajoutons le token CSRF généré dans un champ caché du formulaire. Cela permet de "signer" le formulaire avec le token CSRF associé à la session de l'utilisateur. Voici un exemple de code HTML montrant l'utilisation du token CSRF dans un formulaire : +Lors du rendu d'un formulaire, nous ajoutons le token CSRF généré dans un champ caché du formulaire. Cela permet de " +signer" le formulaire avec le token CSRF associé à la session de l'utilisateur. Voici un exemple de code HTML montrant +l'utilisation du token CSRF dans un formulaire : ```html ``` -Le token CSRF est récupéré depuis la session et inséré dans le champ caché du formulaire à l'aide d'un moteur de template (dans cet exemple, `<%= csrfToken %>` représente l'insertion du token CSRF dans le HTML). +Le token CSRF est récupéré depuis la session et inséré dans le champ caché du formulaire à l'aide d'un moteur de +template (dans cet exemple, `<%= csrfToken %>` représente l'insertion du token CSRF dans le HTML). ## Vérification du token CSRF lors de la soumission d'un formulaire -Lorsqu'un utilisateur soumet un formulaire, le contrôleur correspondant à cette action vérifie que le token CSRF du formulaire correspond à celui stocké dans la session de l'utilisateur. Cela garantit que le formulaire a été généré par notre serveur et n'a pas été forgé par un attaquant. Voici un extrait de code illustrant cette vérification : +Lorsqu'un utilisateur soumet un formulaire, le contrôleur correspondant à cette action vérifie que le token CSRF du +formulaire correspond à celui stocké dans la session de l'utilisateur. Cela garantit que le formulaire a été généré par +notre serveur et n'a pas été forgé par un attaquant. Voici un extrait de code illustrant cette vérification : ```javascript let csrfToken = req.body._csrf; @@ -83,26 +108,48 @@ if (!csrfValidation(req, csrfToken)) { } ``` -Le token CSRF soumis avec le formulaire est extrait de la requête (`req.body._csrf`) et comparé au token stocké dans la session. Si les tokens ne correspondent pas, une erreur CSRF est générée et l'utilisateur est déconnecté par mesure de sécurité. +Le token CSRF soumis avec le formulaire est extrait de la requête (`req.body._csrf`) et comparé au token stocké dans la +session. Si les tokens ne correspondent pas, une erreur CSRF est générée et l'utilisateur est déconnecté par mesure de +sécurité. # Rapport de sécurité - Protection contre les attaques XSS ## Introduction -Les mesures de sécurité mises en place dans notre application afin de prévenir les attaques XSS (Cross-Site Scripting). L'attaque XSS est une technique couramment utilisée par les attaquants pour injecter du code JavaScript malveillant dans les pages web, qui est ensuite exécuté par les navigateurs des utilisateurs. +Les mesures de sécurité mises en place dans notre application afin de prévenir les attaques XSS (Cross-Site Scripting). +L'attaque XSS est une technique couramment utilisée par les attaquants pour injecter du code JavaScript malveillant dans +les pages web, qui est ensuite exécuté par les navigateurs des utilisateurs. ## Protection de la base de données -Une des mesures de sécurité que nous avons mises en place consiste à échapper automatiquement tous les caractères lorsqu'ils sont stockés dans la base de données. L'échappement des caractères implique la conversion de certains caractères spéciaux en leur équivalent sûr, empêchant ainsi leur interprétation en tant que code exécutable. Lorsqu'un utilisateur soumet des données, telles que des commentaires, elles sont traitées et échappées avant d'être stockées dans la base de données. +Une des mesures de sécurité que nous avons mises en place consiste à échapper automatiquement tous les caractères +lorsqu'ils sont stockés dans la base de données. L'échappement des caractères implique la conversion de certains +caractères spéciaux en leur équivalent sûr, empêchant ainsi leur interprétation en tant que code exécutable. Lorsqu'un +utilisateur soumet des données, telles que des commentaires, elles sont traitées et échappées avant d'être stockées dans +la base de données. + +```javascript + +``` ## Avantages de l'échappement automatique en base de données L'échappement automatique des caractères en base de données présente plusieurs avantages en termes de sécurité : -1. **Prévention des attaques XSS**: En échappant automatiquement tous les caractères lorsqu'ils sont stockés en base de données, nous nous assurons que le code JavaScript malveillant ne sera pas exécuté lors de l'affichage des données sur notre site. Les caractères spéciaux sont convertis en leur forme sécurisée, évitant ainsi l'injection de scripts malveillants. -2. **Protection contre les erreurs humaines**: L'échappement automatique en base de données réduit les risques d'erreurs humaines lors de l'affichage des données. Même si une étape de filtrage ou d'encodage est omise lors de l'affichage, les caractères échappés en base de données garantissent que le code potentiellement dangereux ne sera pas exécuté. -3. **Uniformité de la sécurité**: En échappant les caractères au niveau de la base de données, nous appliquons une mesure de sécurité uniforme à toutes les données stockées. Cela garantit que toutes les données, même celles qui ont été stockées antérieurement, sont protégées contre les attaques XSS lors de leur affichage. +1. **Prévention des attaques XSS**: En échappant automatiquement tous les caractères lorsqu'ils sont stockés en base de + données, nous nous assurons que le code JavaScript malveillant ne sera pas exécuté lors de l'affichage des données + sur notre site. Les caractères spéciaux sont convertis en leur forme sécurisée, évitant ainsi l'injection de scripts + malveillants. +2. **Protection contre les erreurs humaines**: L'échappement automatique en base de données réduit les risques d'erreurs + humaines lors de l'affichage des données. Même si une étape de filtrage ou d'encodage est omise lors de l'affichage, + les caractères échappés en base de données garantissent que le code potentiellement dangereux ne sera pas exécuté. +3. **Uniformité de la sécurité**: En échappant les caractères au niveau de la base de données, nous appliquons une + mesure de sécurité uniforme à toutes les données stockées. Cela garantit que toutes les données, même celles qui ont + été stockées antérieurement, sont protégées contre les attaques XSS lors de leur affichage. ## Conclusion -Grâce à l'échappement automatique des caractères en base de données, notre application prévient efficacement les attaques XSS en empêchant l'exécution de code JavaScript malveillant lors de l'affichage des données. Cette mesure de sécurité assure l'intégrité et la sécurité de notre application en empêchant les attaquants d'exploiter cette faille de sécurité. +Grâce à l'échappement automatique des caractères en base de données, notre application prévient efficacement les +attaques XSS en empêchant l'exécution de code JavaScript malveillant lors de l'affichage des données. Cette mesure de +sécurité assure l'intégrité et la sécurité de notre application en empêchant les attaquants d'exploiter cette faille de +sécurité.