Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e688be8
Create Fas1.md
Tripl321 May 25, 2026
e339e86
Merge branch 'Technigo:main' into main
Tripl321 May 27, 2026
574dfa2
Add files via upload
Tripl321 May 27, 2026
a13a8fa
Delete Fas1.md
Tripl321 May 27, 2026
ff14248
Remove duplicate requirement entries in documentation
Tripl321 May 27, 2026
96b632b
Remove emoji placeholders from requirements document
Tripl321 May 27, 2026
e16dc0c
Refine security requirements table format
Tripl321 May 27, 2026
f9aa1f4
Modifierad och kommenterad kod i backend/server.js och frontend/src/c…
Malmqvisten Jun 1, 2026
34da59c
Merge branch 'main' of https://github.com/Tripl321/app-group-assignment
Malmqvisten Jun 1, 2026
3895833
Finslip
Malmqvisten Jun 3, 2026
ecbf739
Create SECURITY.md for security policy
Tripl321 Jun 10, 2026
49fa828
Bump jsonwebtoken from 8.5.1 to 9.0.0 in /backend
dependabot[bot] Jun 10, 2026
5268116
Bump esbuild and vite in /frontend
dependabot[bot] Jun 10, 2026
2ed5d87
Bump qs from 6.15.1 to 6.15.2 in /backend
dependabot[bot] Jun 10, 2026
04b2d8d
Configure Dependabot for npm updates
Tripl321 Jun 12, 2026
ec995e4
Merge pull request #4 from Tripl321/dependabot/npm_and_yarn/backend/q…
Tripl321 Jun 12, 2026
b0de619
Merge pull request #3 from Tripl321/dependabot/npm_and_yarn/frontend/…
Tripl321 Jun 12, 2026
aca73ab
Merge pull request #2 from Tripl321/dependabot/npm_and_yarn/backend/j…
Tripl321 Jun 12, 2026
702fc6a
Upgrade tar module to version > 7.5.11
Tripl321 Jun 12, 2026
79a5281
Document security review findings and actions
Malmqvisten Jun 17, 2026
6e09533
Update granskningsfasen.md
Malmqvisten Jun 17, 2026
692f857
Update granskningsfasen.md
Malmqvisten Jun 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
- package-ecosystem: "npm" # Replace with your ecosystem (e.g., pip, docker, bundler)
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
target-branch: "security-fix" # Dependabot will create PRs against this branch
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Fas 1 – Hotmodellering & Kravspecifikation (STRIDE-E + OWASP 2025)

<aside>

**Syfte:** Identifiera de viktigaste hoten mot vår applikation med hjälp av **STRIDE-E**, mappa varje hot mot **OWASP Top 10 (2025)**, och formulera ett konkret, testbart säkerhetskrav per kategori.

</aside>

## Översikt

Dokumentet utgör **Fas 1** av grupparbetet och är underlaget för kravspecifikationen som implementeras i kommande faser. Varje rad i tabellen nedan består av fyra delar:

1. **STRIDE-E-kategori** – vilken typ av hot vi adresserar.
2. **OWASP Top 10 (2025)** – mappning till en etablerad branschstandard.
3. **Säkerhetskrav** – det konkreta, verifierbara kravet i vår kravspecifikation.
4. **Motivering** – argumentet vi använder i presentationen för *varför* kravet finns.

---

## Hotmodelleringstabell

| **STRIDE-E** | **OWASP Top 10 (2025)** | **Säkerhetskrav** | **Motivering** |
| --- | --- | --- | --- |
| **S — Spoofing** *(Identitetsförfalskning)* | **A07:** Authentication Failures | **Lösenordslös inloggning:** Systemet ska tillåta autentisering via **Passkeys (WebAuthn)** utan traditionella lösenord. | Genom att fasa ut lösenord eliminerar vi själva grundorsaken till läckta konton. Passkeys är kryptografiskt låsta till vår domän, vilket gör plattformen immun mot nätfiske (phishing) och brute-force. |
| **T — Tampering** *(Manipulering)* | **A05:** Injection | **Strikt indatavalidering:** Systemet ska i backend validera att meddelanden är rensade (saniterade) och mellan **3–140 tecken**. | Genom att aldrig lita på data från frontend och tvinga fram validering i vår Express-API skyddar vi databasen från skadlig kod (SQL/NoSQL Injection) och XSS-attacker. |
| **R — Repudiation** *(Förnekande)* | **A09:** Security Logging & Monitoring Failures | **Granskningslogg:** Systemet ska logga **tidsstämpel, användar-ID och händelsetyp** för alla raderade eller ändrade inlägg. | Om en säkerhetsincident inträffar (t.ex. radering av viktig data) måste vi ha spårbarhet. Utan loggning är vi blinda och användare kan förneka sina handlingar i systemet. |
| **I — Information Disclosure** *(Informationsläckage)* | **A02:** Security Misconfiguration | **Skyddade hemligheter:** Inga känsliga API-nycklar eller lösenord får checkas in i Git, utan ska hanteras via dolda **`.env`-filer**. | Att råka publicera produktionsnycklar på GitHub är en av de vanligaste (och farligaste) felkonfigureringarna. Denna rutin minimerar vår attackyta och skyddar konfidentiell data. |
| **D — Denial of Service** *(Överbelastning)* | **A05:** Insecure Design | **Hastighetsbegränsning (Rate Limiting):** API:et ska ha en gräns på antalet tillåtna anrop **per minut och IP-adress**. | För att säkerställa applikationens tillgänglighet måste vi införa resursbegränsningar. Rate limiting skyddar vår backend från att krascha om den utsätts för automatiserad spam eller en överbelastningsattack. |
| **E — Elevation of Privilege** *(Behörighetsökning)* | **A01:** Broken Access Control | **Auktoriseringskontroll:** Backend måste alltid validera att meddelandets **`author_id`** matchar sessionens inloggade användare vid radering/redigering. | Broken Access Control är webbens största sårbarhet. Vi förhindrar behörighetsökning genom att säkerställa att en vanlig användare aldrig kan manipulera någon annans inlägg, oavsett vad frontenden skickar för anrop. |

---

## Sammanfattning av kraven

- **K1 – Autentisering:** Passkeys/WebAuthn istället för lösenord.
- **K2 – Indatavalidering:** Sanitering + längdkontroll (3–140 tecken) i backend.
- **K3 – Loggning:** Granskningslogg med tidsstämpel, användar-ID och händelsetyp för mutationer.
- **K4 – Hemligheter:** Inga secrets i Git; allt via `.env` + `.gitignore`.
- **K5 – Tillgänglighet:** Rate limiting per IP och minut på API.
- **K6 – Auktorisering:** `author_id`-kontroll mot session vid alla mutationer.

---

## Referenser

- [STRIDE threat model (Microsoft)](https://learn.microsoft.com/en-us/azure/security/develop/threat-modeling-tool-threats)
- [OWASP Top 10 (2025)](https://owasp.org/Top10/)
- [WebAuthn / Passkeys (W3C)](https://www.w3.org/TR/webauthn-3/)

<aside>

**Nästa steg (Fas 2):** Översätta varje krav (K1–K6) till konkreta acceptanskriterier och testfall innan implementation påbörjas.

</aside>
21 changes: 21 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Security Policy

## Supported Versions

Use this section to tell people about which versions of your project are
currently being supported with security updates.

| Version | Supported |
| ------- | ------------------ |
| 5.1.x | :white_check_mark: |
| 5.0.x | :x: |
| 4.0.x | :white_check_mark: |
| < 4.0 | :x: |

## Reporting a Vulnerability

Use this section to tell people how to report a vulnerability.

Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc.
20 changes: 17 additions & 3 deletions backend/config/db.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import mongoose from "mongoose"

// [KRAV K4] Skyddade hemligheter (STRIDE: Information Disclosure)
// OWASP A02: Security Misconfiguration

const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/messages"
// FÖRE: const mongoUrl = process.env.MONGO_URL || "mongodb://localhost/messages"
// - Om MONGO_URL saknades i .env anslöt servern tyst till en lokal databas utan autentisering:
// farligt om det sker i produktion av misstag.

mongoose.connect(mongoUrl)
// EFTER: Servern kraschar omedelbart om MONGO_URL saknas.
// - MONGO_URL innehåller ofta användarnamn och lösenord för databasen
// - Den ska ALDRIG hårdkodas i koden utan hanteras via .env
// - .env ligger i .gitignore och checkas aldrig in i Git

if (!process.env.MONGO_URL) throw new Error("MONGO_URL is not set in .env")
const mongoUrl = process.env.MONGO_URL

mongoose.connect(mongoUrl)

mongoose.connection.once("open", () => {
console.log("Connected to MongoDB")
})

mongoose.connection.on("error", err => {
console.error("connection error:", err)
})

9 changes: 9 additions & 0 deletions backend/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import jwt from "jsonwebtoken"
import { User } from "../models/User.js"

// [KRAV K6] Autentiseringsmiddleware (STRIDE: Elevation of Privilege)
// OWASP A01: Broken Access Control

// Denna middleware verifierar JWT-token och sätter req.user.
// KRITISKT: Den MÅSTE användas på alla endpoints som ändrar data (POST, PATCH, DELETE).
// BUGGEN som hittades i Fas 1: DELETE /messages/:id saknade denna middleware helt,
// vilket innebar att vem som helst kunde radera vilkens meddelande som helst.

export const authenticateUser = async (req, res, next) => {
const token = req.headers.authorization?.replace("Bearer ", "")
if (!token) {
return res.status(401).json({ success: false, message: "No token provided" })
}
try {
// [KRAV K4] JWT_SECRET hämtas från .env aldrig hårdkodat
const decoded = jwt.verify(token, process.env.JWT_SECRET)
const user = await User.findById(decoded.userId)
if (!user) {
Expand Down
22 changes: 19 additions & 3 deletions backend/models/Message.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
import mongoose from "mongoose"

const messageSchema = new mongoose.Schema({

// [KRAV K2] Strikt indatavalidering (STRIDE: Tampering / OWASP A05: Injection)

// FÖRE: { type: String, required: true }
// - Ingen min- eller maxlängd: tomma strängar och enorma meddelanden godkändes
// - Ingen trim: whitespace-meddelanden (" ") passerade required-kontrollen

// EFTER: minlength: 3, maxlength: 140, trim: true
// - trim tar bort mellanslag i början och slutet
// - minlength 3 förhindrar meningslösa meddelanden
// - maxlength 140 skyddar mot databasöverbelastning
// - Valideringen sker i Mongoose (backend), vi litar ALDRIG på frontend

message: {
type: String,
required: true
required: [true, "Message is required"],
minlength: [3, "Message must be at least 3 characters"],
maxlength: [140, "Message cannot exceed 140 characters"],
trim: true,
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
createdAt: {
createdAt: {
type: Date,
default: Date.now,
},
})

export const Message = mongoose.model("Message", messageSchema)
export const Message = mongoose.model("Message", messageSchema)
13 changes: 12 additions & 1 deletion backend/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,21 @@ const userSchema = new mongoose.Schema({
unique: true,
lowercase: true,
},

// [KRAV K1] Lösenordslös inloggning — framtida ändring

// NULÄGE: password-fältet lagrar en bcrypt-hash av användarens lösenord.
// bcrypt med salt rounds 10 är en bra implementation, men lösenord i sig är sårbara för phishing och brute force.

// FRAMTIDA IMPLEMENTATION (Passkeys/WebAuthn):
// - Lägg till fält: passkeyCredentialId (String) och passkeyPublicKey (Buffer)
// - Gör password-fältet valfritt (required: false) för Passkey-användare
// - Passkeys binder autentisering kryptografiskt till domänen

password: {
type: String,
required: true,
},
})

export const User = mongoose.model("User", userSchema)
export const User = mongoose.model("User", userSchema)
Loading