"Mně nikdo nehackne"
Slyšíme to pořád. "Moje appka je malá, nikoho nezajímá." "Nemám žádná důležitá data." "To se děje jen velkým firmám jako Facebook nebo Google."
Bohužel, realita je úplně jiná. Většina útoků není cílená. Nikdo nesedí u počítače a neříká si "tak dneska hacknu Honzovu todo appku." Místo toho běží automatizované boty, které skenují celý internet a hledají známé zranitelnosti. Tvoje appka není cíl — je jedna z milionů potenciálních obětí.
A tady je ta nepříjemná pravda: čím méně zkušený vývojář, tím snazší cíl. Vibecoder, který nasadil svou první appku bez bezpečnostních opatření, je pro tyto boty jako otevřené dveře.
Pojďme se podívat na tři reálné příběhy, které ukazují, jak snadno se to může stát — a co se z nich můžeš naučit.
Příběh 1: Jeden npm balíček a tisíce napadených projektů
Co se stalo
V roce 2018 se odehrál jeden z nejznámějších supply chain útoků v historii JavaScriptu. Malý npm balíček event-stream měl miliony stažení týdně. Používaly ho tisíce projektů, přímo nebo jako závislost jiné závislosti.
Původní autor balíčku ho přestal udržovat. Objevil se někdo, kdo se nabídl, že se o něj postará. Autor mu dal přístup — proč ne, je to open source, komunita si pomáhá.
Jenže nový správce měl jiný plán. Do balíčku přidal malý kousek kódu, který se aktivoval pouze v aplikaci Copay (bitcoinová peněženka). Tento kód kradl privátní klíče k bitcoinovým peněženkám.
Proč je to relevantní pro tebe
Když ti AI vygeneruje kód, často ti doporučí nainstalovat balíčky. "Nainstaluj tenhle package, vyřeší to za tebe." A ty to uděláš, protože proč ne? AI to doporučilo, má to miliony stažení, vypadá to legitimně.
Ale každý balíček je kód, kterému důvěřuješ. A každá závislost toho balíčku je další kód, kterému důvěřuješ. Typický Node.js projekt má stovky až tisíce tranzitivních závislostí. Kolik z nich jsi zkontroloval?
Co si z toho vzít
- Neinstaluj balíčky bezmyšlenkovitě. Než napíšeš
npm install, zeptej se: opravdu to potřebuju? Nemůžu to napsat sám v pár řádcích? - Kontroluj závislosti. Podívej se na npm stránku balíčku — kolik má správců? Kdy byl naposledy aktualizovaný? Má smysluplný README?
- Používej
npm auditpravidelně a řeš nalezené problémy - Zamykej verze v
package-lock.jsona commituj ho do repozitáře
# Zkontroluj své závislosti
npm audit
# Podívej se, kolik závislostí vlastně máš
npm ls --all | wc -l
# Výsledek tě možná překvapí — klidně stovky balíčků
Příběh 2: Exposed .env soubor — AWS účet za 47 000 dolarů
Co se stalo
Vývojář (říkejme mu Tomáš) vytvořil jednoduchou webovou aplikaci. Nasadil ji na VPS, všechno fungovalo. Ale udělal jednu chybu: jeho .env soubor byl přístupný přes web. Stačilo zadat https://jeho-appka.cz/.env a viděl jsi kompletní konfiguraci — včetně AWS access key a secret key.
Jak dlouho trvalo, než ho někdo našel? Méně než hodinu. Boti neustále skenují internet a zkouší přistoupit k běžným souborům: .env, .git/config, wp-config.php, database.yml, a desítkám dalších.
Co útočník udělal s AWS klíči? Spustil desítky EC2 instancí na mineování kryptoměn. Tomáš si toho všiml, až když mu přišel email od Amazonu: faktura za 47 000 dolarů. Po dlouhém vyjednávání s AWS podporou se nakonec podařilo většinu částky odpustit, ale stálo ho to týdny stresu.
Proč je to relevantní pro tebe
Pokud nasazuješ na VPS a tvůj webový server není správně nakonfigurovaný, můžou být soubory přístupné, které by neměly být. A .env soubor je to první, co boti zkouší.
Ale není to jen .env. Stejné riziko hrozí u:
.git/— celá historie tvého repozitáře včetně všech commitů (a secrets, které jsi tam kdy dal)node_modules/— informace o tvých závislostech a jejich verzích- Zálohy databáze — pokud je máš ve webovém adresáři
- Konfigurační soubory —
config.json,settings.yaml, cokoliv
Co si z toho vzít
-
Nikdy nedávej
.envdo webového adresáře. Ideálně ho drž mimo celou aplikaci. -
Nakonfiguruj webový server aby odmítal přístup k citlivým souborům:
# Nginx - zablokuj přístup k hidden souborům
location ~ /\. {
deny all;
return 404;
}
# Zablokuj přístup ke konfiguračním souborům
location ~* \.(env|git|yaml|yml|toml|lock)$ {
deny all;
return 404;
}
-
Otestuj to sám. Po nasazení zkus v prohlížeči otevřít:
https://tvoje-appka.cz/.envhttps://tvoje-appka.cz/.git/confighttps://tvoje-appka.cz/.git/HEAD
Pokud vidíš obsah souboru místo chyby 404, máš problém.
-
Nastav si AWS billing alerts, aby tě Amazon upozornil, když ti náklady překročí limit:
# AWS CLI - nastav alarm na billing
aws cloudwatch put-metric-alarm \
--alarm-name "BillingAlarm" \
--metric-name EstimatedCharges \
--namespace AWS/Billing \
--threshold 50 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 1 \
--period 21600 \
--statistic Maximum \
--alarm-actions arn:aws:sns:us-east-1:ACCOUNT:billing-alarm
Příběh 3: SQL injection na kontaktním formuláři
Co se stalo
Malá firma měla web s kontaktním formulářem. Nic složitého — jméno, email, zpráva. Backend zpracovával data takhle:
// ❌ Takhle se to NIKDY nedělá
const query = `SELECT * FROM users WHERE email = '${req.body.email}'`;
db.query(query);
Vidíš ten problém? Hodnota z formuláře se přímo vkládá do SQL dotazu. Útočník místo emailu zadal:
' OR '1'='1'; DROP TABLE users; --
A výsledný SQL dotaz vypadal:
SELECT * FROM users WHERE email = '' OR '1'='1'; DROP TABLE users; --'
Tabulka users zmizela. Všechna data pryč. Žádná záloha.
Proč je to relevantní pro tebe
SQL injection je jedna z nejstarších zranitelností — je známá od konce 90. let. A přesto je stále v top 10 nejčastějších webových zranitelností podle OWASPu. Proč? Protože lidi (a AI) stále píšou kód, který je na ni náchylný.
AI ti může vygenerovat zranitelný kód, pokud se explicitně nezeptáš na bezpečnost. A pokud nemáš zkušenosti, nepoznáš rozdíl.
Co si z toho vzít
- Nikdy nevkládej uživatelský vstup přímo do SQL. Používej parametrizované dotazy:
// ✅ Bezpečná verze s parametrizovaným dotazem
const query = "SELECT * FROM users WHERE email = $1";
db.query(query, [req.body.email]);
- Ještě lépe — používej ORM jako Prisma, TypeORM nebo Drizzle. Ty automaticky escapují vstupy:
// ✅ S Prismou je SQL injection prakticky nemožné
const user = await prisma.user.findUnique({
where: { email: req.body.email },
});
- Validuj vstupy než je zpracuješ:
import { z } from "zod";
const contactSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
message: z.string().min(10).max(1000),
});
const handleSubmit = (req, res) => {
const result = contactSchema.safeParse(req.body);
if (!result.success) {
return res.status(400).json({ error: "Neplatný vstup" });
}
// ... zpracuj validovaná data
};
Co motivuje útočníky?
Možná si říkáš: proč by se někdo obtěžoval s mojí malou appkou? Tady jsou hlavní motivace:
Peníze
Nejčastější motivace. Útočníci chtějí:
- Kryptoměny — použijí tvůj server na mining. Ty platíš za elektřinu a výpočetní výkon, oni sbírají Bitcoin.
- Ransomware — zašifrují tvá data a chtějí výkupné.
- Kradené údaje — emailové adresy, hesla, platební údaje se prodávají na dark webu. Email s heslem stojí pár centů, ale když jich máš tisíce...
Botnety
Tvůj server se stane součástí botnetu — sítě napadených počítačů, které útočník používá k DDoS útokům, rozesílání spamu nebo dalším útokům. Ani nemusíš vědět, že se to děje.
"Just because"
Někteří útočníci to dělají pro zábavu, pro reputaci v komunitě, nebo jako trénink. Tvoje appka je pro ně cvičiště.
5 jednoduchých kroků jak se bránit
Nemusíš být bezpečnostní expert. Stačí těchto 5 kroků a budeš výrazně lépe chráněný než většina malých projektů:
1. Aktualizuj závislosti
npm audit fix
Dělej to pravidelně, ideálně každý týden. Nastav si Dependabot na GitHubu — bude to dělat automaticky.
2. Používej environment proměnné
Žádné secrets v kódu, žádné secrets v Gitu. Všechno do .env a ten do .gitignore.
3. Zapni HTTPS
Bez výjimky, bez výmluvy. Let's Encrypt je zdarma, managed platformy to mají automaticky.
4. Validuj vstupy
Každý vstup od uživatele je potenciálně nebezpečný. Validuj typ, délku a formát. Používej knihovny jako Zod nebo class-validator.
5. Nastav rate limiting
Alespoň na přihlašování a registraci. express-rate-limit nastavíš za 5 minut a výrazně zkomplikuješ automatizované útoky.
Bezpečnost není jednorázová záležitost
Největší mýtus o bezpečnosti je, že ji "uděláš" jednou a máš hotovo. Bezpečnost je kontinuální proces. Nové zranitelnosti se objevují každý den, útočníci přicházejí s novými technikami, a tvoje aplikace se mění.
Proto potřebuješ systém. Něco, co ti připomene, na co nemáš zapomenout. Něco, co tě provede procesem krok za krokem.
Začni s bezpečností ještě dnes
Právě proto existuje TunaGuard. Vytvořili jsme interaktivní bezpečnostní checklisty, které jsou navržené přesně pro lidi jako ty — vibecodeři, začátečníci a všichni, kteří chtějí svoji appku zabezpečit, ale nevědí kde začít.
Žádný žargon, žádná akademická teorie. Praktické kroky, které můžeš udělat hned teď.
Registrace je zdarma — začni s bezpečností ještě dnes.
Protože otázka není jestli se někdo pokusí hacknout tvou appku. Otázka je kdy.