2 Commits
Author SHA1 Message Date
jhoogie 65233fb5b4 Merge pull request 'bugfix' (#18) from update-1.0.12 into main
Reviewed-on: #18
2026-09-18 15:25:08 +02:00
Jordy Hoogeveen 2799bc12ee bugfix 2026-09-18 15:18:47 +02:00
8 changed files with 85 additions and 3 deletions
+34
View File
@@ -335,6 +335,40 @@ dan is het antwoord `no configuration file provided: not found`. Met
Pullen zelf werkt anoniem zolang de organisatie public is — zie
[Pullen op een deploy-machine](#pullen-op-een-deploy-machine).
### De scan meldt 46 CVE's op postgres:18-alpine
Dat klopt, en het blijft zo. Ze zitten allemaal in één bestand:
```bash
# Alle bevindingen komen uit /usr/local/bin/gosu, niets uit de Alpine-pakketten
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image --scanners vuln postgres:18-alpine
```
`gosu` is een klein Go-programma dat het postgres-entrypoint gebruikt om van
root naar de `postgres`-gebruiker te schakelen. Upstream compileert het met Go
1.24.6, en alle meldingen zijn CVE's in die Go-standaardbibliotheek. Je kunt er
niets aan verhelpen met een `pull`: dit ís de nieuwste versie.
Wat wél is gedaan: beide compose-bestanden starten de container met
`user: "postgres"`. Het entrypoint roept gosu alleen aan als het als root start
(`if [ "$(id -u)" = '0' ]`), dus die tak wordt overgeslagen en de binary draait
nooit. De CVE's zijn daarmee onbereikbaar — de scanner kijkt naar wat aanwezig
is, niet naar wat uitgevoerd wordt.
> Dit werkt ook op een volume dat ooit als root is aangemaakt: de
> data-directory is dan al eigendom van postgres. Getest met een bestaande
> database; die start en de data blijft intact.
**Waarom geen eigen image zonder gosu.** Dat kan (`FROM postgres:18-alpine` +
`RUN rm -f /usr/local/bin/gosu`) en zet de scan op nul, maar je ruilt een
onbereikbaar risico voor een echt risico: je moet dat image dan zelf herbouwen
bij elke postgres-patch. Precies die achterstand was het probleem toen het image
vier maanden op 18.4 stond met 143 bevindingen. Met het officiële image haalt
`docker compose pull` de patches vanzelf op, en zodra upstream gosu met een
nieuwere Go herbouwt is het gratis opgelost. `test.ps1` waarschuwt daarom bij
stap 4 als `postgres:18-alpine` in de registry nieuwer is dan wat je lokaal hebt.
### PostgreSQL versie-upgrade
Twee soorten, met een belangrijk verschil. Kijk eerst welke je voor je hebt:
+21
View File
@@ -2,6 +2,27 @@
## [Niet vrijgegeven]
### Beveiliging
- **De postgres-container draait niet meer als root.** Beide compose-bestanden
starten hem met `user: "postgres"`. Alle 46 bevindingen op `postgres:18-alpine`
zitten in één bestand — `/usr/local/bin/gosu`, dat upstream met Go 1.24.6
compileert — en het entrypoint roept gosu alleen aan als het als root start.
Non-root starten slaat die tak over, dus de binary draait nooit meer. De
Alpine-pakketten in dat image zijn zelf schoon
- Getest op een bestaande database die ooit als root was aangemaakt: die start
als non-root en de data blijft intact. Ook een verse database initialiseert
gewoon
- Bewust géén eigen postgres-image gebouwd om die binary te verwijderen. Dat zou
de scan op nul zetten maar je verplichten het image zelf te herbouwen bij elke
postgres-patch — precies de achterstand die het image vier maanden op 18.4 met
143 bevindingen hield. De afweging staat in `BEHEER.md`, zodat de volgende
scan niet opnieuw tot dezelfde vraag leidt
- `test.ps1` waarschuwt bij stap 4 wanneer `postgres:18-alpine` in de registry
nieuwer is dan wat er lokaal staat. Die achterstand is het werkelijke risico;
het getal in de scan is dat niet
## [1.0.11] - 2026-09-18
### Beveiliging
- **PostgreSQL 18.4 → 18.6.** Het `postgres:18-alpine` image dat in gebruik was
dateerde van vier maanden geleden. Dat is een patch binnen dezelfde major, dus
+1 -1
View File
@@ -10,7 +10,7 @@ Eigen vermogen · Schulden · Voortgang · Gebruikersbeheer
![Node.js](https://img.shields.io/badge/Node.js_22-339933?style=flat&logo=node.js&logoColor=white)
![PostgreSQL](https://img.shields.io/badge/PostgreSQL_18-4169E1?style=flat&logo=postgresql&logoColor=white)
![Docker](https://img.shields.io/badge/Docker_Compose-2496ED?style=flat&logo=docker&logoColor=white)
![Version](https://img.shields.io/badge/versie-1.0.10-8b5cf6?style=flat)
![Version](https://img.shields.io/badge/versie-1.0.11-8b5cf6?style=flat)
![Built with Claude](https://img.shields.io/badge/Gebouwd_met-Claude.ai-8b5cf6?style=flat&logo=anthropic&logoColor=white)
<img src="docs/screenshot-dashboard.png" alt="VibeFinance dashboard" width="820">
+3
View File
@@ -15,6 +15,9 @@ services:
postgres:
image: postgres:18-alpine
container_name: vibefinance-postgres-dev
# Zie docker-compose.yml: non-root starten omzeilt gosu, waar alle CVE's
# van dit image in zitten.
user: "postgres"
environment:
POSTGRES_DB: ${POSTGRES_DB:-vibefinance}
POSTGRES_USER: ${POSTGRES_USER:-vibefinance}
+7
View File
@@ -16,6 +16,13 @@ services:
image: postgres:18-alpine
container_name: vibefinance_postgres
restart: unless-stopped
# Meteen als postgres draaien in plaats van als root. Het entrypoint schakelt
# anders zelf terug met `gosu`, en juist die binary bevat alle 46 CVE's van
# dit image (Go stdlib 1.24.6, meegecompileerd door upstream). Start de
# container al als postgres, dan slaat het entrypoint die tak over en wordt
# gosu nooit uitgevoerd. Werkt ook op een volume dat ooit als root is
# aangemaakt — de data-directory is dan al van postgres.
user: "postgres"
environment:
POSTGRES_DB: ${POSTGRES_DB:-vibefinance}
POSTGRES_USER: ${POSTGRES_USER:-vibefinance}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "vibefinance-frontend",
"version": "1.0.11-dev",
"version": "1.0.12-dev",
"private": true,
"type": "module",
"scripts": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "vibefinance",
"version": "1.0.11",
"version": "1.0.12",
"description": "VibeFinance — persoonlijk vermogensbeheer",
"private": true,
"repository": "https://vibehoogie.duckdns.org/vibe/VibeFinance",
+17
View File
@@ -124,6 +124,23 @@ if (-not $SkipScan) {
exit 1
}
Write-Host "Imagescan schoon ($ernst)" -ForegroundColor Green
# Het postgres-image scannen we niet als gate: alle bevindingen daarin zitten
# in /usr/local/bin/gosu, en die binary wordt nooit uitgevoerd omdat de
# compose-bestanden de container al als `postgres` starten (zie BEHEER.md).
# Wat wél misgaat is achterstand: het image stond vier maanden op 18.4 met
# 143 bevindingen omdat niemand pullde. Daar waarschuwen we voor — falen zou
# onterecht zijn, want een release van de app hangt er niet van af.
$pgTag = "postgres:18-alpine"
$lokaal = (docker image inspect $pgTag --format '{{index .RepoDigests 0}}' 2>$null)
if ($lokaal) {
$remote = (docker buildx imagetools inspect $pgTag --format '{{.Manifest.Digest}}' 2>$null)
if ($remote -and $lokaal -notlike "*$remote*") {
Write-Host "Let op: $pgTag is nieuwer in de registry — draai 'docker compose pull postgres'." -ForegroundColor Yellow
} else {
Write-Host "$pgTag is actueel" -ForegroundColor Green
}
}
} else {
Write-Step "[4/5] Imagescan overgeslagen (-SkipScan)"
}