diff --git a/Fas3-Granskning b/Fas3-Granskning new file mode 100644 index 00000000..7ba6b08e --- /dev/null +++ b/Fas3-Granskning @@ -0,0 +1,48 @@ +# Säkerhetsgranskning: Analys av Automatiserade Fynd + +Denna rapport sammanställer säkerhetsbrister identifierade via de automatiserade verktygen **GitHub Dependabot** (tredjepartsberoenden) och **CodeQL** (statisk kodanalys/SAST av källkod) i `backend/server.js`. + +--- + +## 1. Sammanfattning av fynd + +| Verktyg | Komponent / Plats | Allvarlighetsgrad | Huvudsaklig risk | +| :--- | :--- | :--- | :--- | +| **CodeQL** | `server.js` (L29-169) | 🔴 High | Saknad Rate Limiting (Sårbarhet mot DoS/Brute Force) | +| **CodeQL** | `server.js` (L20) | 🟡 Medium | Permissive CORS (Vidöppen policy, `*`) | +| **Dependabot** | Paket: `jsonwebtoken` | 🔴 High / Moderate | Signaturförfalskning och obehörig autentisering | +| **Dependabot** | Paket: `node-tar` | 🔴 High | Path Traversal (Obehörig filskrivning) | +| **Dependabot** | Paket: `qs` | 🟡 Moderate | Fjärrstyrd DoS via applikationskrasch | + +--- + +## 2. Detaljerad analys + +### Källkod: Saknad Rate Limiting (CodeQL: High) +CodeQL identifierade 7 unika fall i `server.js` där applikationen saknar hastighetsbegränsningar för inkommande anrop mot känsliga endpoints (t.ex. `/login`, `/register`). +* **Konsekvens:** Applikationen är sårbar för automatiserade *Brute Force*-attacker (lösenordsgissning) samt Denial of Service (DoS) där servern överbelastas av för många anrop. + +### Källkod: Tillåtande CORS-konfiguration (CodeQL: Medium) +CORS är inställt på dafult-värdet wildcard (`origin: "*"`). +* **Konsekvens:** Servern litar på anrop från valfri extern domän, vilket öppnar upp för Cross-Origin-attacker där skadliga webbplatser i teorin kan göra obehöriga API-anrop i bakgrunden. + +### Tredjepart: Sårbarheter i `jsonwebtoken` (Dependabot: High) +* **Konsekvens:** Tillåter en angripare att manipulera nyckeltyper (t.ex. tvinga fram ett byte från RSA till HMAC) för att förfalska giltiga tokens och helt kringgå autentiseringen på servern. + +### Tredjepart: Sökvägssabotage i `node-tar` (Dependabot: High) +* **Konsekvens:** Paketet är sårbart för *Path Traversal* via djupt nästlade symlinks, vilket möjliggör för en angripare att skriva eller skriva över filer utanför applikationens rotkatalog. + +--- + +## 3. Konkreta åtgärdsförslag + +1. **Implementera rate-limiting i källkoden:** + Installera `express-rate-limit` och applicera på auth-endpoints i `server.js`: + +2. Härda CORS-policyn: +Ersätt * på rad 20 med en explicit vitlista: +JavaScript + app.use(cors({ origin: '[https://din-frontend-url.com](https://din-frontend-url.com)' })); + +3. Uppdatera sårbara bibliotek: +Kör npm audit fix i backend-katalogen för att lyfta jsonwebtoken och node-tar till säkra versioner. \ No newline at end of file diff --git "a/S\303\204KERHETSGRANSKNING.md" "b/S\303\204KERHETSGRANSKNING.md" new file mode 100644 index 00000000..27fef6c2 --- /dev/null +++ "b/S\303\204KERHETSGRANSKNING.md" @@ -0,0 +1,253 @@ +# Säkerhetsgranskning - Analys av Identifierade Risker + +## Sammanfattning +Denna granskning jämför de säkerhetsrisker som identifierades i planeringsfasen med den faktiska kodbasen. **KRITISKA BRISTER UPPTÄCKTA** som kan leda till allvarliga säkerhetsproblem. + +--- + +## Hot 1: SPOOFING (Identitetsförfalskning) ⚠️ DELVIS FÖREKOMMANDE + +### Identifierad Risk +- Bristfälliga tokens eller användar ID i klartext i URL:en + +### Analys av Kod + +✅ **KORREKT IMPLEMENTERAT:** +- Tokens skickas via Authorization headers (`Bearer ${token}`), INTE i URL +- JWT tokens använder hemlig JWT_SECRET för signering +- Tokens har begränsad livslängd (2 timmar) + +❌ **SÄKERHETSBRIST FUNNEN:** +- **Token lagras i frontend state/localStorage**: Fil: `frontend/src/App.jsx`. `user.response.accessToken` lagras direkt i state. +- **Token exponerad i console.log**: Fil: `frontend/src/components/PostMessage.jsx`, rad 19. Loggar token till console: `console.log("Token being sent:", user?.response?.accessToken)` +- **Tokens lagras inte i HTTP-only cookies**: Fil: `backend/server.js` (Route: `POST /login`). Token returneras via JSON och kan läckas via XSS-attacker eller av JavaScript. + + +### Risk +- Tokens kan stoppas av XSS-attacker +- Tokens kan läckas vid datorbyte (de finns i browser history/localStorage) +- Loggning av tokens exponerar dem i DevTools + +--- + +## Hot 2: TAMPERING (Manipulering av Data) 🔴 KRITISK SÅRBARHET + +### Identifierad Risk +- Obehörig kan ändra eller radera data i databasen genom att manipulera API-anrop + +### Analys av Kod + +❌ **KRITISK SÄKERHETSBRIST - DELETE ROUTE UTAN AUTENTISERING:** + +```javascript +// Fil: backend/server.js, rad 157-165 +app.delete("/messages/:id", async (req, res) => { + if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" }) + try { + const message = await Message.findById(req.params.id) + if (!message) return res.status(404).json({ error: "Message not found" }) + await message.deleteOne() // ← VEM SOM HELST KAN RADERA! + res.status(204).send() +``` + +**INGEN `authenticateUser` MIDDLEWARE!** + +- Jämfört med PATCH-rouet som HAS auth: +```javascript +app.patch("/messages/:id", authenticateUser, async (req, res) => { + // ... verifierar ägarskap ... + if (message.user.toString() !== req.user._id.toString()) { + return res.status(403).json({ error: "You can only edit your own messages" }) + } +``` + +### Risk +- **VILKEN SOM HELST kan radera VILKET MEDDELANDE SOM HELST** +- Ingen behörighetskontroll +- Möjlighet till dataförstöring och sabotage +- DELETE button i SingleMessage.jsx skickar request utan att verifiera ägarskap på servern + +### Bevissäkerhet +- Frontend-kontroll: Fil: `frontend/src/components/SingleMessage.jsx`, rad 14: `const isOwner = user && user.response.id === message.user?._id` +- Detta är ENDAST UI-granskning - servern validerar aldrig ägarskapet +- Frontend kan enkelt manipuleras med DevTools + +--- + +## Hot 3: INFORMATION DISCLOSURE (Informationsläcka) 🟡 DELVIS FÖREKOMMANDE + +### Identifierad Risk +- Lösenord läcks i klartext +- Meddelanden läcks till obehöriga + +### Analys av Kod + +✅ **KORREKT IMPLEMENTERAT:** +- Lösenord hasheras med bcrypt 10-rounds: `bcrypt.hash(password, 10)` +- Lösenord aldrig returnerat i responses +- Kommunikation över HTTPS (Render.com) + +❌ **SÄKERHETSBRIST:** +- **CORS öppet för alla origins**: Fil: `backend/server.js`, rad 9. +```javascript +app.use(cors({ + origin: "*", // ← VILKEN SOM HELST domän kan göra requests! +})) +``` + +- **Error messages exponerar information**: +```javascript +// server.js - Login endpoint +if (!user) { + return res.status(401).json({ + success: false, + message: "No account found with that username or email", // Avslöjar om email existerar! +``` + +- **Användar ID exponeras i meddelanden**: Alla användar IDs är synliga (ObjectIds är inte hemliga men kan vara känslig info) + +### Risk +- CSRF-attacker från vilken webbsida som helst +- Brute-force login med information om vilka emails som är registrerade +- Cross-origin API-missbruk + +--- + +## Hot 4: DENIAL OF SERVICE (Överbelastning) 🔴 KRITISK BRIST + +### Identifierad Risk +- Ingen rate limiting +- Server kan överbelastas av meddelanden eller inloggningsförsök + +### Analys av Kod + +❌ **INGEN RATE LIMITING IMPLEMENTERAT** + +- **Login endpoint saknar skydd mot brute-force**: + ```javascript + app.post("/login", async (req, res) => { + // Ingen kontroll på antalet försök per IP/användare + ``` + +- **Register endpoint saknar skydd**: + ```javascript + app.post("/register", async (req, res) => { + // Ingen rate limiting - kan skapa obegränsade accounts + ``` + +- **POST /messages saknar längdbegränsning**: + ```javascript + app.post("/messages", authenticateUser, async (req, res) => { + const message = new Message({ message: req.body.message, user: req.user._id }) + // Inget check på req.body.message längd! + ``` + +- **Ingen validering av lösenordslängd**: + ```javascript + // Register-endpoint verifierar username men NOT password length + if (!username || username.trim().length < 2) { + // men ingen check för password! + ``` + +### Risk +- Brute-force login: Attacker kan prova lösenord utan begränsning +- Spam av meddelanden: En användare kan skriva miljontals meddelanden +- Stora meddelanden: Kan skicka mycket stora payloads +- Account enumeration: Kan skapa spam-accounts obegränsad +- DoS-attack genom överflöd av requests + +--- + +## Hot 5: ELEVATION OF PRIVILEGE (Behörighetsvinst) 🔴 KRITISK BRIST + +### Identifierad Risk +- Vanlig användare får administratörsrättigheter eller åtkomst till obehörig funktioner + +### Analys av Kod + +❌ **KRITISK SÅRBARHET - DELETE UTAN AUKTORISERING** + +Samma som Tampering-problemet: DELETE-rouet har ingen autentisering och ingen behörighetskontroll. + +- Vilken inloggad användare som helst kan radera VILKEN meddelande som helst +- En oauthentiserad användare kan potentiellt radera meddelanden (om CORS+frontend manipulation) + +❌ **INGEN ROLL-BASERAD ÅTKOMSTKONTROLL** + +- Ingen skillnad mellan "admin" och vanlig användare +- Alla har samma behörigheter +- Ingen möjlighet att implementera moderatörer eller administrators + +### Risk +- Användare A kan radera Användare B:s meddelanden +- Möjlighet till vandalism och dataskada +- Ingen möjlighet att designa ett admin-system i framtiden + +--- + +## Säkerhetskrav Analys + +### Krav 1: Lösenordshantering och kryptering ✅ LÖST +- ✅ Lösenord hasheras med bcrypt +- ✅ Aldrig i klartext i DB eller responses +- ✅ Aldrig i klartext mellan komponenter (HTTPS) + +**Status: GODKÄNT** + +--- + +### Krav 2: Auktorisering för meddelanden ❌ DELVIS LÖST +- ✅ PATCH route kontrollerar ägarskap +- ❌ DELETE route kontrollerar INTE ägarskap - **KRITISK BRIST** +- ❌ Frontend-validering är INTE tillräcklig + +**Status: UNDERKÄNT - Måste fixas innan produktion** + +--- + +### Krav 3: Indatavalidering ❌ OFULLSTÄNDIG +- ✅ Username validering: minlängd 2 +- ✅ Email format (men minimal validering) +- ✅ ObjectId validering på API +- ❌ Meddelandelängd - ingen validering +- ❌ Lösenordslängd - ingen validering +- ❌ Ingen sanering av specialtecken eller potentiella injektioner + +**Status: DELVIS GODKÄNT - Bör förbättras** + +--- + +### Krav 4: Sessionshantering ❌ DÅLIGT IMPLEMENTERAT +- ✅ JWT tokens använd för sessioner +- ✅ Token-verifiering på protected routes +- ❌ Tokens lagras INTE säkert (inte HTTP-only cookies) +- ❌ Ingen refresh token mekanisme +- ❌ Ingen logout på servern (tokens kan inte invalideras) +- ❌ Token loggas till console + +**Status: UNDERKÄNT - Token-hantering måste förbättras** + +--- + +## Sammanfattning av Kritiska Brister + +| Prioritet | Problem | Plats | Lösning | +|-----------|---------|-------|---------| +| 🔴 KRITISK | DELETE utan autentisering | server.js L157 | Lägg till `authenticateUser` middleware och ägarskapscheck | +| 🔴 KRITISK | Ingen rate limiting | Alla POST routes | Implementera rate-limit package | +| 🔴 KRITISK | CORS öppet för alla | server.js L9 | Begränsa till frontend URL | +| 🟡 HÖG | Tokens i localStorage | Frontend State | Använd HTTP-only cookies | +| 🟡 HÖG | Token i console.log | PostMessage.jsx L19 | Ta bort debug logging | +| 🟡 MEDEL | Ingen indatavalidering | POST /messages | Validera meddelandelängd | +| 🟡 MEDEL | Information disclosure | Login response | Ändra error messages | + +--- + +## Rekommendationer + +1. **OMEDELBAR**: Fixera DELETE-rouet - lägg till autentisering och auktorisering +2. **OMEDELBAR**: Implementera rate limiting på auth-routes +3. **SNART**: Begränsa CORS till frontend URL +4. **SNART**: Migrera tokens till HTTP-only cookies +5. **SENARE**: Implementera indatavalidering för alla inputs +6. **SENARE**: Lägg till refresh token mekanisme diff --git a/backend/models/User.js b/backend/models/User.js index 266a60b4..45ffcf19 100644 --- a/backend/models/User.js +++ b/backend/models/User.js @@ -15,7 +15,7 @@ const userSchema = new mongoose.Schema({ lowercase: true, }, password: { - type: String, + type: String, //Här borde det finnas mer krav på lösenordet, t.ex. minsta längd, krav på siffror/specialtecken etc. required: true, }, }) diff --git a/backend/server.js b/backend/server.js index c8d0c218..d3ee2d73 100644 --- a/backend/server.js +++ b/backend/server.js @@ -14,10 +14,11 @@ import listEndpoints from "express-list-endpoints" if (!process.env.JWT_SECRET) throw new Error("JWT_SECRET is not set in .env") const PORT = process.env.PORT || "3000" -const app = express() +const app = express() //Implementera rate-limiting, t.ex. express-rate-limit, för att skydda särskilt inloggningsendpointen mot brute-force attacker. app.use(helmet()) app.use(cors({ - origin: "*", + origin: "*", //DET HÄR ÄR SVÅRT ATT MOTIVERA. Backend behöver väl inte svara på anrop från andra domäner än frontend? + // Extra problematiskt då vi saknar rate-limiting och andra skydd mot missbruk. })) app.use(express.json()) @@ -73,7 +74,7 @@ app.post("/register", async (req, res) => { } }) -app.post("/login", async (req, res) => { +app.post("/login", async (req, res) => { // INGEN RATE-LIMITING, VILKET GÖR DENNA ENDPOINT SÅRBAR FÖR BRUTE-FORCE ATTACKS. try { const { login, password } = req.body const user = await User.findOne({ @@ -83,7 +84,7 @@ app.post("/login", async (req, res) => { if (!user) { return res.status(401).json({ success: false, - message: "No account found with that username or email", + message: "No account found with that username or email", //RISK FÖR INFORMATIONSLÄCKAGE. Behöver användaren veta detta? response: null, }) } @@ -92,7 +93,7 @@ app.post("/login", async (req, res) => { if (!passwordMatch) { return res.status(401).json({ success: false, - message: "Password is incorrect", + message: "Password is incorrect", //RISK FÖR INFORMATIONSLÄCKAGE. Behöver användaren veta detta? response: null, }) } @@ -136,7 +137,7 @@ app.get("/messages", async (req, res) => { } }) -app.post("/messages", authenticateUser, async (req, res) => { +app.post("/messages", authenticateUser, async (req, res) => { // INGEN VALIDERING AV INNEHÅLLET I MEDDELANDET. VEM SOM HELST KAN SPAMMA VILKEN DATA SOM HELST, INKLUSIVE MALICIOUS SCRIPTS. const message = new Message({ message: req.body.message, user: req.user._id }) try { const saved = await message.save() @@ -165,10 +166,11 @@ app.patch("/messages/:id", authenticateUser, async (req, res) => { } }) -app.delete("/messages/:id", async (req, res) => { +app.delete("/messages/:id", async (req, res) => { //Varför körs inte authenticateUser här? if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" }) try { const message = await Message.findById(req.params.id) + // INGEN AUTENSIERING GÖRS. VEM SOM HELST KAN RADERA MED RÄTT ID. if (!message) return res.status(404).json({ error: "Message not found" }) await message.deleteOne() res.status(204).send() diff --git a/planeringsfasen.md b/planeringsfasen.md index 661cae0e..195fba5e 100644 --- a/planeringsfasen.md +++ b/planeringsfasen.md @@ -1 +1,39 @@ -# Inlämning 1 - Planeringsfasen \ No newline at end of file +# Inlämning 1 - Planeringsfasen + +## Identifierade säkerhetsrisker och hotscenarier (STRIDE) + +### Hot 1: Spoofing (Identitetsförfalskning) +En angripare använder säkerhetsbrister i appen som gör det möjligt att ange sig för att vara någon annan. T.ex. genom bristfälliga tokens eller om användar ID står i klartext i URL:en +* **STRIDE-kategori:** Spoofing + +### Hot 2: Tampering (Manipulering) +En obehörig ändrar eller raderar data i databaen. Kan göras med genom att ändra ett API-anrop och utnyttja säkerhetsbrister. +* **STRIDE-kategori:** Tampering + +### Hot 3: Information Disclosure (Informationsläcka) +Känslig data når obehöriga. T.ex. meddelanden som skulle vara privata läses av någon än den avsedda mottagaren. Detta kan hotaktören göra genom att komma åt känslig data (t.ex. lösenord) i kommunikationen mellan frontend och API om inte tillräckliga skyddsåtgärder finns på plats +* **STRIDE-kategori:** Information Disclosure + +### Hot 4: Denial of Service (Överbelastning) +En DDoS attack gör att legitima användare inte kan komma åt / använda applikationen. Utan åtgärder som rate limiting kan servern bli överbelastad av meddelanden eller inloggningsförsök. +* **STRIDE-kategori:** Denial of Service + +### Hot 5: Elevation of Privilege (Behörighetsvinst) +En vanlig användare får administratörsrättigheter och får tillgång till funktioner som inte vanliga användare ska kunna komma åt. +* **STRIDE-kategori:** Elevation of Privilege + +--- + +## Säkerhetskrav + +1. **Lösenordshantering och kryptering** + Lösenord får aldrig lagras i klartext i databasen, inte heller skickas i klartext mellan systemets olika delkomponenter. Kryptering/hashning måste användas. + +2. **Auktorisering för meddelanden** + En användare ska bara kunna redigera sina egna meddelanden. Systemet måste säkerställa att den som redigerar ett meddelande verkligen är dess sanna ägare innan ändringar sparas. + +3. **Indatavalidering** + All data som matas in i systemet måste valideras, enbart indata som är säker ska kunna skickas mellan systemets olika delar (ej t.ex. databaskommandon eller annat med avsikt att manipulera systemet på oönskat sätt.) + +4. **Sessionshantering** + Sessionshantering. När en användare har loggats in ska dennes användarsession kunna säkerställas i systemet på ett säkert sätt. Skyddsåtgärder som säkerställer att ingen annan kan ta över sessionen måste finnas på plats. \ No newline at end of file diff --git a/presentation.md b/presentation.md new file mode 100644 index 00000000..9c26a743 --- /dev/null +++ b/presentation.md @@ -0,0 +1,177 @@ +# Kritiska säkerhetsbrister i projektet + +## 1. Öppet `DELETE /messages/:id` utan autentisering (tampering) + +Det mest kritiska felet är att `DELETE /messages/:id` inte genomför någon autientisiering. Det betyder att vilken som helst klient kan ta bort vilket meddelande som helst. Den enda kontroll som görs sker i frontend, och är enkel att lura med t.ex. devtools. + +```js +app.delete("/messages/:id", async (req, res) => { + if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" }) + try { + const message = await Message.findById(req.params.id) + if (!message) return res.status(404).json({ error: "Message not found" }) + await message.deleteOne() + res.status(204).send() + } catch (error) { + res.status(400).json({ error: "Could not delete message" }) + } +}) +``` + +### Varför det är kritiskt +- Ingen autentisering betyder ingen kontroll över vem som raderar meddelanden. +- En angripare kan ta bort andras meddelanden utan att vara inloggad. +- Det finns ingen kontroll av ägarskap (behörighet) vid borttagning. + +### Förslag på åtgärd +1. Lägg till `authenticateUser` på `DELETE /messages/:id`. +2. Kontrollera att `message.user.toString() === req.user._id.toString()` innan borttagning. +3. Returnera en 403-status (forbidden) om användaren försöker ta bort någon annans meddelande. + +Exempel på lösning: + +```js +app.delete("/messages/:id", authenticateUser, async (req, res) => { + if (!isValidId(req.params.id)) return res.status(400).json({ error: "Invalid message ID" }) + try { + const message = await Message.findById(req.params.id) + if (!message) return res.status(404).json({ error: "Message not found" }) + if (message.user.toString() !== req.user._id.toString()) { + return res.status(403).json({ error: "You can only delete your own messages" }) + } + await message.deleteOne() + res.status(204).send() + } catch (error) { + res.status(400).json({ error: "Could not delete message" }) + } +}) +``` + +### 2. Avsaknad av inputvalidering + + - Meddelanden kan vara hur långa som helst, potentiellt överbelasta servern + - Avsaknad av regler kring lösenord. + - Ingen sanering av indata, risk för NoSQL-injektioner eller XSS + ### Åtgärd + - Implementera en max-längd för hur långa meddelanden och lösenord kan vara. + - Begränsa / ställ krav på vilka tecken som kan/måste användas. + - Använd extrabibliotek på backend som saniterar inmatad text. + +```js +app.post("/messages", authenticateUser, async (req, res) => { // INGEN VALIDERING AV INNEHÅLLET I MEDDELANDET. VEM SOM HELST KAN SPAMMA VILKEN DATA SOM HELST, INKLUSIVE MALICIOUS SCRIPTS. + const message = new Message({ message: req.body.message, user: req.user._id }) + try { + const saved = await message.save() + res.status(201).json(saved) + } catch (err) { + res.status(400).json({ message: "Could not save message", errors: err.errors }) + } +}) +``` + +### 3. Alltför bred CORS-konfiguration (överbelastning/tampering/) + Cross-Origin Resource Sharing +`server.js` tillåter API-anrop från alla domäner genom att använda `origin: "*"`. + +```js +app.use(cors({ + origin: "*", +})) +``` + +### Varför det är kritiskt +- En öppen CORS-policy gör att vilken webbplats/server som helst kan anropa API:t. +- Onödig öppning som ökar risken för obehöriga åtkomstförsök från skadliga webbplatser. + +### Förslag på åtgärd +1. Begränsa `origin` till de domäner som faktiskt ska använda API:t, till exempel frontend-adressen. +2. Använd en lista med tillåtna domäner i produktion. +3. I utveckling kan man tillfälligt tillåta `http://localhost:5173`, men undvik `*` i skarp drift. + +Exempel: + +```js +app.use(cors({ + origin: ["http://localhost:5173", "https://din-produktionsdomän.se"], +})) +``` + +### 4. Avsaknad av rate-limiting (överbelastning) + +Ingen rate-limiting är definierad i `server.js`, vilket betyder att API:t kan ta emot obegränsat många anrop på kort tid. + +### Varför det är kritiskt +- En angripare kan utföra ett DOS-liknande anfall genom att skicka många förfrågningar snabbt. +- Det kan överbelasta servern och orsaka att tjänsten blir långsam eller otillgänglig. +- Utan begränsning är även inloggnings- och registerendpoints sårbara mot brute force-attacker. + +### Förslag på åtgärd +1. Använd ett rate-limiting middleware, t.ex. `express-rate-limit`. +2. Applicera rate-limiting på specifika endpoints, t.ex. `/login`, `/register` och `/messages`. +3. Ställ in ett försiktigt tak, till exempel 100 förfrågningar per 15 minuter per IP. + +Exempel: + +```js +import rateLimit from "express-rate-limit" + +const limiter = rateLimit({ + windowMs: 15 * 60 * 1000, + max: 100, + message: "Too many requests from this IP, please try again later.", +}) + +app.use(limiter) +``` + +### 5. Felhantering läcker intern information (informationsläcka) + +I både `/register` och `/login` returneras `error`-objektet i svaret när något går fel. + +```js +res.status(400).json({ + success: false, + message: "Could not create user", + error: error, +}) +``` + +```js +res.status(500).json({ + success: false, + message: "Something went wrong", + error: error, +}) +``` + +### Varför det är kritiskt +- Råa felobjekt kan innehålla detaljer om databasen, servermiljön eller ramverket. +- Angripare kan använda dessa detaljer för att hitta fler sårbarheter. +- Appen bör bara ge användaren en generell felbeskrivning. + +### Förslag på åtgärd +1. Ta bort `error: error` från API-svaren i produktion. +2. Logga det interna felet på servern, men visa en enkel och mer generisk feltext till användaren. + +Exempel: + +```js +console.error(error) +res.status(400).json({ + success: false, + message: "Could not create user" +}) +``` + + + + + +## Sammanfattning + +De kritiska bristerna är: +- `DELETE /messages/:id` saknar autentisering och ägarskapskontroll. +- CORS är öppet för alla ursprung (`origin: "*"). +- Avsaknad av rate-limiting gör API:t sårbart för överbelastning och brute force. +- Felhanteringen läcker interna felobjekt till klienten. +- Avsaknad av input-validering. \ No newline at end of file