<link rel="stylesheet" href="/assets/fonts/jetbrains-mono/jetbrains-mono.css" />
All posts

Fjalëkalime në historinë e git-it: si i hoqa (dhe pse nuk mjafton)

Po bëja një rishikim të përgjithshëm të projektit tim, në kërkim të gjërave të harruara. Gjeta një që nuk do ta kisha dashur: një skedar konfigurimi për deploy, me brenda çelësin që nënshkruan token-at e hyrjes, fjalëkalimin e administratorit dhe fjalëkalimin për dërgimin e email-eve. Në tekst të hapur, në historinë e git-it, në tri degë.

Si ndodhi

Skedari ishte te .gitignore. Problemi është se përfundoi aty pasi ishte bërë commit një herë, dhe .gitignore injoron vetëm skedarët që nuk ndiqen ende: një skedar që ndiqet tashmë vazhdon të ndiqet, ndryshim pas ndryshimi, edhe nëse emri i tij është në listë.

Repository-ja ishte private, por private nuk do të thotë e sigurt: e shohin bashkëpunëtorët, shërbimet e CI-së, backup-et dhe çdo kompjuter ku është klonuar.

Heqja nga e gjithë historia

Fshirja e skedarit me një commit të ri nuk ndihmon: ai mbetet në të gjitha commit-et e mëparshme. Duhet rishkruar historia e çdo dege. Përdora git filter-repo mbi një klon mirror, pastaj bëra push të detyruar dhe verifikova që asnjë commit nuk e përmbante më:

# 1. Stop tracking the file (it stays on disk)
git rm --cached .env.deploy
git commit -m "Stop tracking .env.deploy"

# 2. Rewrite the history of EVERY branch on a mirror clone
git clone --mirror git@github.com:me/my-repo.git
cd my-repo.git
git filter-repo --path .env.deploy --invert-paths
git push --force --mirror

# 3. Verify: no commit on any branch may still contain it
git log --all --oneline -- .env.deploy

Pas një rishkrimi të tillë, kushdo që ka një kopje lokale duhet ta rirreshtojë me remote-n e ri: commit-et e vjetra nuk duhen ripublikuar më.

Pse nuk mjafton

Këtu qëndron mësimi më i rëndësishëm. Edhe pas rishkrimit, commit-et e vjetra mund të mbeten të arritshme: GitHub, për shembull, mban referenca të brendshme për pull request-et që një push i detyruar nuk mund t'i fshijë. Dhe nuk dihet kush e ka shkarkuar repository-n në të kaluarën.

Heqja e një sekreti nga historia shërben që situata të mos përkeqësohet; e vetmja gjë që e zgjidh është ndryshimi i tij. Në praktikë:

  • Një çelës i ri për nënshkrimin e token-ave: i zhvlerëson të gjitha sesionet ekzistuese, ndaj të gjithë duhet të hyjnë sërish. Është çmimi që paguhet.
  • Një fjalëkalim i ri për administratorin.
  • Revokimi i fjalëkalimit të aplikacionit të postës dhe krijimi i një të riu.
  • Përditësimi i variablave në çdo mjedis ku përdoren.

Herën e dytë, e njëjta skemë

Disa javë më vonë gjeta të njëjtin problem në një formë tjetër: një skript shumë i rehatshëm për instalimin e serverit, që i shkruante kredencialet drejtpërdrejt në skedarin e konfigurimit. Është skema që përsëritet: skripti i rehatisë që mban sekretet që të mos kesh nevojë të konfigurosh asgjë. E rishkrova që t'i gjenerojë çelësat në moment dhe t'i kërkojë fjalëkalimet kujt e ekzekuton:

# Before: secrets written into a script tracked by git
# JWT_SECRET=hardcoded-value...

# After: generated or asked at runtime, never committed
JWT_SECRET="$(openssl rand -base64 48)"
read -rsp "SMTP password: " SMTP_PASS; echo
umask 077   # the .env file is readable by its owner only
printf 'JWT_SECRET=%s\nSMTP_PASS=%s\n' "$JWT_SECRET" "$SMTP_PASS" > .env

Zakonet që e parandalojnë përsëritjen

  1. Një .env.example i bërë commit, me emrat e variablave dhe pa vlera; .env-i i vërtetë nuk hyn kurrë në repository.
  2. Një skaner sekretesh para çdo commit-i, si gitleaks në një hook pre-commit: e bllokon commit-in para se të bëhet dëmi.
  3. Mbrojtja e push-eve që ofrojnë GitHub dhe GitLab, e cila refuzon push-et që përmbajnë sekrete të njohshme.
  4. Kurrë sekrete në skripte: gjenerohen në runtime ose lexohen nga mjedisi.
  5. Një kontroll periodik i historisë: një sekret që e gjen ti është një incident i vogël, një që e gjejnë të tjerët jo.

Në përmbledhje

Një sekret në një repository duhet trajtuar si i komprometuar në çastin që e gjen. Rishkrimi i historisë është i nevojshëm, por jo i mjaftueshëm: korrigjimi i vërtetë është ndryshimi i çdo kredenciali të ekspozuar. Pastaj ia vlen ta bësh problemin të pamundur për t'u përsëritur, me skanerë dhe rregulla të qarta. Praktika të tjera sigurie kam mbledhur në këtë udhëzues.

💬 Shënime nga lexuesit

0 shënime

Shkruaj një shënim

Ndaj mendimin tënd, një sugjerim ose një kompliment

Shënimet e fundit

Ende asnjë shënim. Bëhu i pari që komenton!