Node.js server xavfsizligi
Serverda ishlaydigan dastur brauzerdagi koddan bir jihati bilan keskin farq qiladi: u sizning fayllaringiz, bazangiz va kalitlaringiz yonida turadi. Xatoning narxi ham shunga yarasha.
Bu darsdagi to’rt mavzu — eng ko’p uchraydigan va eng qimmatga tushadigan xatolar.
1. Maxfiy ma’lumot kodda turmaydi
Eng keng tarqalgan xato shunday ko’rinadi:
// Bunday yozmang
const apiKey = "sk-live-8f2a1c443e7b4c91a2d5";
Kalit kodga yozilgan. Demak u omborga tushadi, jamoadagi hammaga ko’rinadi va ombor ochiq bo’lsa — butun internetga.
To’g’ri yo’l — process darsida ko’rgan muhit o’zgaruvchilari.
.env faylida:
API_KEY=sk-live-8f2a1c443e7b4c91a2d5
DATABASE_PATH=./data/app.db
Kodda:
const apiKey = process.env.API_KEY;
if (!apiKey) {
console.log("API_KEY berilmagan");
process.exit(1);
}
console.log("Kalit uzunligi:", apiKey.length);
node --env-file=.env app.js
Kalit uzunligi: 25
Kalit yo’qligini oldindan tekshirish muhim: usiz dastur ishlayveradi va xato ancha keyin, tushunarsiz shaklda chiqadi.
.gitignore majburiy
.env faylini omborga tushmaydigan qilish kerak:
node_modules/
.env
*.db
Tekshiruv usuli:
git status --short
Ro’yxatda .env ko’rinmasligi kerak. Ko’rinsa, .gitignore noto’g’ri
yozilgan yoki fayl allaqachon kuzatuvga olingan.
2. Bog’liqliklar xavfi
Bitta paket o’rnatsangiz, u o’z bog’liqliklarini tortadi, ular esa o’zinikini. Natijada loyihada yuzlab begona paket paydo bo’ladi.
Ma’lum zaifliklarni tekshirish uchun buyruq bor:
npm audit
Muammo topilmasa:
found 0 vulnerabilities
Topilsa, taxminan shunday chiqadi:
# npm audit report
semver <5.7.2
Severity: moderate
semver vulnerable to Regular Expression Denial of Service
fix available via `npm audit fix`
1 moderate severity vulnerability
Tuzatish:
npm audit fix
Paket nomini tekshiring
Hujumchilar mashhur paketga o’xshash nom bilan zararli paket joylashtiradi. Bir harf farq qilgan nom, chalkashtirish uchun qo’yilgan defis — natija bir xil: siz begona kodni o’rnatasiz.
TypeScript darsida buning jonli namunasi
uchradi: npx tsc buyrug’i rasmiy kompilyator o’rniga tsc nomli
begona paketni yuklab oldi.
O’rnatishdan oldin ko’rib chiqing:
npm view express
Uch narsaga qarang:
| Nima | Nimani bildiradi |
|---|---|
| Haftalik yuklab olishlar | Juda kam bo’lsa — ehtiyot bo’ling |
| Oxirgi yangilanish sanasi | Yillar oldin bo’lsa, qo’llab-quvvatlanmaydi |
| Ombor havolasi | Ochiq kodmi, muammolar bo’limi jonlimi |
3. Foydalanuvchi bergan fayl yo’li
Endi fs va path darslariga tayanadigan mavzu.
Dastur foydalanuvchidan fayl nomini olib, uni o’qib berishi kerak deylik. Xavfli yozuv shunday ko’rinadi:
fs.readFileSync(path.join(uploadsDir, userInput))
Bir qarashda himoyalangandek: fayl uploads papkasidan olinyapti.
Muammo userInput ichida nima bo’lishi mumkinligida.
Foydalanuvchi oddiy fayl nomi o’rniga bir necha marta .. yozib
yuborsa, path.join ularni hisobga oladi va natijada hosil bo’lgan yo’l
uploads dan chiqib ketadi. Shu yo’l bilan tizim fayllarini yoki
sizning .env faylingizni so’rash mumkin.
Himoya — yo’lni yig’ib bo’lgandan keyin tekshirish:
const fs = require("node:fs");
const path = require("node:path");
const uploadsDir = path.join(__dirname, "uploads");
function readUserFile(fileName) {
// Yo'lni to'liq, normallashtirilgan shaklga keltiramiz
const fullPath = path.resolve(uploadsDir, fileName);
// Natija ruxsat etilgan papka ichida qoldimi
if (!fullPath.startsWith(uploadsDir + path.sep)) {
throw new Error("Ruxsat etilmagan yo'l");
}
return fs.readFileSync(fullPath, "utf8");
}
try {
console.log(readUserFile("notes.txt"));
} catch (error) {
console.log("Xato:", error.message);
}
Oddiy fayl so’ralganda:
Birinchi qator
Ikkinchi qator
Papkadan chiqishga urinilganda:
Xato: Ruxsat etilmagan yo'l
Kalit qism — path.resolve natijasini tekshirish. .. bo’laklari shu
bosqichda hisoblanib bo’ladi, shuning uchun startsWith tekshiruvi
ishonchli ishlaydi.
4. Buyruqqa kiritma bermaslik
child_process darsidagi qoidani takrorlaymiz, chunki u eng jiddiy xavflardan biri.
exec berilgan satrni shell orqali bajaradi. Shell esa ;, && va |
belgilarini buyruq ajratuvchisi deb biladi. Shuning uchun
foydalanuvchi matnini buyruq satriga yopishtirish begona odamga
serveringizda o’z buyrug’ini bajarish imkonini beradi.
Yechim — shellni umuman ishlatmaslik:
const { execFile } = require("node:child_process");
function checkHost(host) {
// Argument alohida massivda ketadi, shell uni izohlamaydi
execFile("ping", ["-n", "1", host], (error, stdout) => {
if (error) {
console.log("Javob kelmadi");
return;
}
console.log("Javob keldi, uzunligi:", stdout.length);
});
}
checkHost("example.com");
Uchala hujum bir xil mantiqqa asoslanadi: ma’lumot buyruqqa aylanib qolgan.
| Hujum | Ma’lumot qayerga qo’shilgan | Himoya |
|---|---|---|
| SQL injection | So’rov matniga | Parametrli so’rov ? |
| Shell injection | Buyruq satriga | execFile va argument massivi |
| Path traversal | Fayl yo’liga | Natijani tekshirish |
SQL injection darsidagi qoida shu jadvalning birinchi qatori.
Kiruvchi ma’lumotni tekshirish
Umumiy qoida: tashqaridan kelgan qiymat kutilgan shaklda ekanini tasdiqlang.
function parsePage(rawValue) {
const page = Number(rawValue);
if (!Number.isInteger(page) || page < 1 || page > 1000) {
return 1;
}
return page;
}
console.log(parsePage("5"));
console.log(parsePage("salom"));
console.log(parsePage("-3"));
console.log(parsePage("999999"));
node validate-demo.js
5
1
1
1
Noto’g’ri qiymat rad etildi va xavfsiz standart qaytdi. Yuqori chegara ham qo’yilgani muhim: juda katta son bilan bazaga og’ir so’rov yuborishning oldini oladi.
Xatolarni foydalanuvchiga ko’rsatmang
Xatolar va jurnal darsida ko’rgan stack trace ichida fayl yo’llari va ba’zan ma’lumotlar bazasi tuzilishi bo’ladi.
Ikki manzilni ajrating:
const { log } = require("./logger");
function handleError(error) {
// To'liq tafsilot — jurnalga
log("error", "So'rovni bajarishda xato", {
errorName: error.name,
errorMessage: error.message,
});
// Foydalanuvchiga — qisqa xabar
return { message: "Ichki xato yuz berdi" };
}
console.log(handleError(new Error("SQLITE_ERROR: no such table: users")));
{"time":"2026-09-12T13:20:11.004Z","level":"error","message":"So'rovni bajarishda xato","errorName":"Error","errorMessage":"SQLITE_ERROR: no such table: users"}
{ message: 'Ichki xato yuz berdi' }
Jurnalda hamma narsa bor, tashqariga esa faqat umumiy xabar chiqdi.
Node.js ni yangilab turing
Node.js versiyalarida ham zaiflik topiladi va ular yangi chiqarilishlarda tuzatiladi.
node --version
v24.14.1
Qaysi versiya hozir LTS ekanini rasmiy saytdan tekshiring — bu ro’yxat vaqt bilan o’zgaradi.
Amaliy mashq
- Kodda yozilgan kalitni
.envfayliga ko’chiring va--env-filebilan ishga tushiring; .gitignorega.envqo’shib,git status --shortda ko’rinmasligini tasdiqlang;- Loyihada
npm audityuriting va hisobotni o’qing; readUserFilefunksiyasini yozib, oddiy fayl nomi bilan hamda papkadan chiqishga urinish bilan sinang;parsePagefunksiyasini yozib, unga son, matn va manfiy qiymat bering;- Xatoni jurnalga to’liq, javobga qisqa yozadigan funksiya tuzing.
4-qadam eng muhimi: fayl yo’lini tekshirish serverdagi eng ko’p e’tibordan chetda qoladigan zaiflik.
Qisqacha xulosa
- Maxfiy kalit hech qachon kodga yozilmaydi —
.envva.gitignoreishlatiladi. - Git tarixiga tushgan kalit o’chirilmaydi: uni bekor qilish kerak.
- Har o’rnatilgan paket sizning huquqlaringiz bilan ishlaydi —
npm auditbilan tekshirib turing. - Paket nomini o’rnatishdan oldin ko’zdan kechiring: o’xshash nomlar hujum vositasi.
- Foydalanuvchi bergan fayl yo’li
path.resolvedan keyin tekshiriladi. - Foydalanuvchi matni
execbuyrug’iga qo’shilmaydi —execFileva argument massivi ishlatiladi. - Xato tafsiloti jurnalga yoziladi, foydalanuvchiga qisqa xabar qaytariladi.
Keyingi darsda tezlik va profil olish — sekin joyni taxmin qilmasdan o’lchash.