18-bo‘lim
Xavfsiz dasturlash amaliyoti
Xavfsizlikni ishlab chiqish jarayoniga singdirish - tahdid modeli, xavfsiz kod standartlari, CI tekshiruvlari va kod ko'rigi.
Ushbu bo‘lim mundarijasi
- Xarajat egri chizig'i
- Xavfsiz ishlab chiqish sikli
- Xavfsizlik talablari
- Dizayn bosqichida tahdid modeli
- Xavfsiz kod standartlari
- Kirish tekshiruvi qatlami
- CI da xavfsizlik tekshiruvlari
- Xavfsizlik testlari
- Bog'liqliklar siyosati
- Kod ko'rigi ro'yxati
- Xavfsizlik yetakchilari
- Xavfsiz standart holat
- Ishga tushirishdan oldingi ro'yxat
- Xulosa
Xavfsizlikni oxirida qo'shib bo'lmaydi. U dizayn bosqichidan boshlab jarayonning bir qismi bo'lishi kerak.
Xarajat egri chizig'i #
Xavfsiz ishlab chiqish sikli #
Xavfsizlik talablari #
# Foydalanuvchi hikoyasi: Parolni tiklash
## Funksional talablar
- Foydalanuvchi elektron pochtasini kiritadi
- Havola yuboriladi
- Havola orqali yangi parol o'rnatiladi
## Xavfsizlik talablari
- [ ] Token kriptografik tasodifiy, kamida 32 bayt
- [ ] Token bazada **xeshlangan** holda saqlanadi
- [ ] Token 30 daqiqada eskiradi
- [ ] Token bir marta ishlatiladi
- [ ] Foydalanuvchi mavjudligi oshkor qilinmaydi
- [ ] IP va pochta bo'yicha tezlik cheklovi
- [ ] Parol o'zgargach barcha sessiyalar tugatiladi
- [ ] Foydalanuvchiga xabar yuboriladi
- [ ] Barcha urinishlar jurnalga yoziladi
## Suiiste'mol holatlari
- Hujumchi tokenni taxmin qilishga urinadi → uzunlik va tezlik cheklovi
- Hujumchi tokenni bazadan o'g'irlaydi → xeshlash
- Hujumchi pochtalar ro'yxatini tekshiradi → bir xil javob
- Hujumchi havolani qayta ishlatadi → bir martalik token
Odatiy talablar "foydalanuvchi nima qila oladi" ni tasvirlaydi.
Suiiste'mol holati esa "hujumchi nima qilishga urinadi" ni tasvirlaydi.
Har bir muhim funksiya uchun kamida 3 ta suiiste'mol holati yozing. Bu tahdid modelining eng oddiy shakli.
Dizayn bosqichida tahdid modeli #
# Tahdid modeli: Fayl yuklash funksiyasi
## 1. Nima quriladi?
Foydalanuvchilar profil rasmini yuklaydi.
## 2. Nima noto'g'ri ketishi mumkin? (STRIDE)
| Tahdid | Ssenariy | Himoya |
|--------|----------|--------|
| Spoofing | Boshqaning profiliga yuklash | Sessiya tekshiruvi |
| Tampering | .php faylni rasm sifatida | MIME + kengaytma + qayta kodlash |
| Repudiation | "Men yuklamadim" | Jurnal: kim, qachon, IP |
| Info disclosure | Boshqaning faylini o'qish | Tasodifiy nom, huquq tekshiruvi |
| DoS | 10 GB fayl yuklash | Hajm cheklovi, tezlik cheklovi |
| Elevation | Web shell orqali kod bajarish | Alohida domen, bajarish taqiqi |
## 3. Nima qilamiz?
- Hajm: maksimum 2 MB
- Turlar: faqat jpg, png, webp
- Tekshiruv: `getimagesize()` + qayta kodlash
- Saqlash: veb-ildizdan tashqarida
- Nom: tasodifiy UUID
- Xizmat: alohida domen (static.dokon.uz)
- Nginx: shu papkada PHP bajarish o'chirilgan
## 4. Yetarlimi?
- [x] Har bir tahdid uchun himoya bor
- [x] Himoyalar testlar bilan qoplangan
- [ ] Antivirus tekshiruvi - keyingi bosqichda
final class RasmYuklovchi
{
private const MAKS_HAJM = 2 * 1024 * 1024;
private const RUXSAT = ['image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp'];
public function yuklang(array $fayl, int $foydalanuvchiId): string
{
if ($fayl['error'] !== UPLOAD_ERR_OK) {
throw new YuklashXatosi('Yuklashda xato');
}
if ($fayl['size'] > self::MAKS_HAJM) {
throw new YuklashXatosi('Fayl juda katta');
}
// MIME ni mazmundan aniqlaymiz, sarlavhadan emas
$mime = (new finfo(FILEINFO_MIME_TYPE))->file($fayl['tmp_name']);
if (!isset(self::RUXSAT[$mime])) {
throw new YuklashXatosi('Ruxsat etilmagan tur');
}
// Haqiqiy rasmmi?
$olcham = @getimagesize($fayl['tmp_name']);
if ($olcham === false) {
throw new YuklashXatosi('Bu rasm emas');
}
// Qayta kodlash - yashirin kodni yo'q qiladi
$tasvir = match ($mime) {
'image/jpeg' => imagecreatefromjpeg($fayl['tmp_name']),
'image/png' => imagecreatefrompng($fayl['tmp_name']),
'image/webp' => imagecreatefromwebp($fayl['tmp_name']),
};
$nom = bin2hex(random_bytes(16)) . '.jpg';
$yol = $this->saqlashYoli . '/' . $nom;
imagejpeg($tasvir, $yol, 85);
imagedestroy($tasvir);
$this->jurnal->yozing('rasm.yuklandi', [
'foydalanuvchi' => $foydalanuvchiId,
'nom' => $nom,
'hajm' => $fayl['size'],
'ip' => $_SERVER['REMOTE_ADDR'],
]);
return $nom;
}
}
Hujumchi rasm ichiga PHP kodini yashirishi mumkin (polyglot fayl).
imagecreatefromjpeg() + imagejpeg() faylni piksel darajasida
qayta yaratadi. Yashirin kod yo'qoladi, chunki u pikselga aylanmagan.
Bu tekshiruvdan ko'ra ishonchliroq.
Xavfsiz kod standartlari #
# Xavfsiz kod standarti - PHP
## 1. Ma'lumotlar bazasi
- HAR DOIM tayyorlangan so'rov (prepared statement)
- Jadval/ustun nomi dinamik bo'lsa - oq ro'yxat
- TAQIQ: so'rovga o'zgaruvchini birlashtirish
## 2. Chiqish
- HTML: htmlspecialchars($x, ENT_QUOTES, 'UTF-8')
- JS ichida: json_encode($x, JSON_HEX_TAG | JSON_HEX_AMP)
- URL: rawurlencode($x)
- Shablon avtomatik ekranlash bilan bo'lsin
## 3. Autentifikatsiya
- password_hash() PASSWORD_ARGON2ID bilan
- Kirish muvaffaqiyatli bo'lgach session_regenerate_id(true)
- Sessiya cookie: HttpOnly, Secure, SameSite=Lax
## 4. Tasodifiylik
- random_bytes(), random_int() - faqat shular
- TAQIQ: rand(), mt_rand(), uniqid()
## 5. Taqqoslash
- Sirlarni hash_equals() bilan solishtiring
- TAQIQ: == yoki === sirlar uchun
## 6. Fayllar
- Foydalanuvchi kiritgan yo'l - hech qachon to'g'ridan-to'g'ri
- realpath() + prefiks tekshiruvi
## 7. Tashqi buyruqlar
- Iloji boricha ishlatmang
- Kerak bo'lsa: escapeshellarg() har bir argument uchun
- TAQIQ: shell_exec($foydalanuvchiKiritgani)
## 8. Deserializatsiya
- TAQIQ: unserialize($ishonchsiz)
- json_decode() ishlating
## 9. Xatolar
- display_errors = Off (ishlab chiqarishda)
- Foydalanuvchiga umumiy xabar, jurnalga to'liq
## 10. Sirlar
- Kodda sir bo'lmasin - muhit o'zgaruvchisi yoki sir boshqaruvchisi
- .env fayl git ga qo'shilmasin
// Xavfsiz asos sinf - loyihada barcha so'rovlar shu orqali
final class XavfsizBaza
{
public function __construct(private PDO $pdo) {}
public function tanlang(string $sql, array $parametrlar = []): array
{
$sorov = $this->pdo->prepare($sql);
$sorov->execute($parametrlar);
return $sorov->fetchAll(PDO::FETCH_ASSOC);
}
/** Dinamik saralash - faqat oq ro'yxatdan */
public function saralashUchun(string $ustun, array $ruxsat): string
{
if (!in_array($ustun, $ruxsat, true)) {
throw new InvalidArgumentException('Ruxsat etilmagan ustun');
}
return $ustun;
}
}
Kirish tekshiruvi qatlami #
/**
* Barcha tashqi ma'lumot shu qatlamdan o'tadi.
* Nazorat: oq ro'yxat, qat'iy turlar, chegara.
*/
final class Tekshiruvchi
{
private array $xatolar = [];
public function butun(string $maydon, mixed $qiymat, int $min, int $maks): ?int
{
$son = filter_var($qiymat, FILTER_VALIDATE_INT);
if ($son === false) {
$this->xatolar[$maydon] = 'Butun son bo\'lishi kerak';
return null;
}
if ($son < $min || $son > $maks) {
$this->xatolar[$maydon] = sprintf('%d va %d orasida bo\'lsin', $min, $maks);
return null;
}
return $son;
}
public function pochta(string $maydon, mixed $qiymat): ?string
{
$pochta = filter_var((string) $qiymat, FILTER_VALIDATE_EMAIL);
if ($pochta === false || strlen($pochta) > 254) {
$this->xatolar[$maydon] = 'Pochta manzili noto\'g\'ri';
return null;
}
return strtolower($pochta);
}
public function tanlov(string $maydon, mixed $qiymat, array $ruxsat): ?string
{
$qator = (string) $qiymat;
if (!in_array($qator, $ruxsat, true)) {
$this->xatolar[$maydon] = 'Noto\'g\'ri qiymat';
return null;
}
return $qator;
}
public function matn(string $maydon, mixed $qiymat, int $maksUzunlik): ?string
{
$qator = trim((string) $qiymat);
if ($qator === '') {
$this->xatolar[$maydon] = 'Bo\'sh bo\'lmasin';
return null;
}
if (mb_strlen($qator) > $maksUzunlik) {
$this->xatolar[$maydon] = sprintf('Maksimum %d belgi', $maksUzunlik);
return null;
}
// Boshqaruv belgilarini olib tashlaymiz
return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $qator);
}
public function xatolarBormi(): bool
{
return $this->xatolar !== [];
}
public function xatolar(): array
{
return $this->xatolar;
}
}
// Ishlatish
$t = new Tekshiruvchi();
$malumot = [
'pochta' => $t->pochta('pochta', $_POST['pochta'] ?? ''),
'yosh' => $t->butun('yosh', $_POST['yosh'] ?? '', 14, 120),
'holat' => $t->tanlov('holat', $_POST['holat'] ?? '', ['faol', 'nofaol']),
'izoh' => $t->matn('izoh', $_POST['izoh'] ?? '', 1000),
];
if ($t->xatolarBormi()) {
return $this->javob->xato(422, $t->xatolar());
}
Ba'zilar noto'g'ri ma'lumotni tozalab ishlatadi:
$nom = str_replace(['<', '>'], '', $_POST['nom']); // Yomon
Bu ishonchsiz - hujumchi tozalashni chetlab o'tish yo'lini topadi
(<<script>>, kodlash, Unicode).
To'g'ri yondashuv: rad eting. Ma'lumot talabga mos kelmasa, xato qaytaring.
CI da xavfsizlik tekshiruvlari #
# .github/workflows/xavfsizlik.yml
name: Xavfsizlik tekshiruvi
on:
pull_request:
push:
branches: [asosiy]
schedule:
- cron: '0 3 * * 1' # Haftalik - yangi CVE lar uchun
permissions:
contents: read
security-events: write
jobs:
sirlar:
name: Sirlarni qidirish
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Butun tarix
- name: Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
bogliqliklar:
name: Bog'liqliklar (SCA)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
- name: Composer audit
run: composer audit --format=plain
- name: Trivy
uses: aquasecurity/trivy-action@master
with:
scan-type: fs
severity: CRITICAL,HIGH
exit-code: '1'
ignore-unfixed: true
statik:
name: Statik tahlil (SAST)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
tools: psalm
- name: Psalm taxonomiya
run: psalm --taint-analysis --report=psalm.sarif
- name: Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/php
p/security-audit
p/owasp-top-ten
p/secrets
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: psalm.sarif
konteyner:
name: Konteyner obrazi
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Obraz yig'ish
run: docker build -t dokon:sinov .
- name: Trivy obraz skani
uses: aquasecurity/trivy-action@master
with:
image-ref: dokon:sinov
severity: CRITICAL,HIGH
exit-code: '1'
- name: Dockerfile lint
uses: hadolint/hadolint-action@v3
with:
dockerfile: Dockerfile
testlar:
name: Xavfsizlik testlari
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: composer install --no-interaction
- run: vendor/bin/phpunit --testsuite=xavfsizlik
--taint-analysis foydalanuvchi ma'lumoti (manba) xavfli funksiyaga
(cho'kma) yetib borishini kuzatadi:
$_GET['id'] → $so'rov → $pdo->query() ← XATO topildi
Bu oddiy naqsh qidirishdan ancha kuchli - u ma'lumot oqimini kuzatadi.
Xavfsizlik testlari #
final class XavfsizlikTesti extends TestCase
{
public function test_sql_inyeksiya_ishlamaydi(): void
{
$zararli = [
"1' OR '1'='1",
"1; DROP TABLE mijozlar; --",
"1 UNION SELECT parol_xesh FROM foydalanuvchilar",
"1' AND SLEEP(5) --",
];
foreach ($zararli as $kirish) {
$javob = $this->soragan('GET', '/mahsulot?id=' . urlencode($kirish));
$this->assertContains($javob->kodi(), [400, 404, 422]);
$this->assertStringNotContainsStringIgnoringCase('sql', $javob->tanasi());
$this->assertStringNotContainsStringIgnoringCase('syntax', $javob->tanasi());
}
// Jadval hali joyida
$this->assertTrue($this->baza->jadvalBormi('mijozlar'));
}
public function test_xss_ekranlanadi(): void
{
$yuk = '<script>alert(1)</script>';
$this->kiring('[email protected]');
$this->soragan('POST', '/izoh', ['matn' => $yuk]);
$javob = $this->soragan('GET', '/izohlar');
$this->assertStringNotContainsString('<script>', $javob->tanasi());
$this->assertStringContainsString('<script>', $javob->tanasi());
}
public function test_idor_bloklanadi(): void
{
$birinchi = $this->mijozYarating();
$ikkinchi = $this->mijozYarating();
$buyurtma = $this->buyurtmaYarating($ikkinchi->id);
$this->kiring($birinchi->pochta);
$javob = $this->soragan('GET', "/buyurtma/{$buyurtma->id}");
$this->assertSame(404, $javob->kodi());
}
public function test_csrf_tokensiz_rad_etiladi(): void
{
$this->kiring('[email protected]');
$javob = $this->soragan('POST', '/profil', ['ism' => 'Yangi'], csrf: false);
$this->assertSame(419, $javob->kodi());
}
public function test_admin_yoliga_oddiy_foydalanuvchi_kira_olmaydi(): void
{
$this->kiring('[email protected]');
foreach (['/admin', '/admin/foydalanuvchilar', '/admin/sozlamalar'] as $yol) {
$this->assertSame(403, $this->soragan('GET', $yol)->kodi(), $yol);
}
}
public function test_parol_xeshlangan_holda_saqlanadi(): void
{
$this->royxatdanOting('[email protected]', 'JudaKuchliParol123!');
$xesh = $this->baza->qiymat(
'SELECT parol_xesh FROM foydalanuvchilar WHERE pochta = :pochta',
['pochta' => '[email protected]']
);
$this->assertStringStartsWith('$argon2id$', $xesh);
$this->assertTrue(password_verify('JudaKuchliParol123!', $xesh));
}
public function test_xavfsizlik_sarlavhalari_mavjud(): void
{
$javob = $this->soragan('GET', '/');
$this->assertNotEmpty($javob->sarlavha('Content-Security-Policy'));
$this->assertSame('nosniff', $javob->sarlavha('X-Content-Type-Options'));
$this->assertStringContainsString('max-age=', $javob->sarlavha('Strict-Transport-Security'));
}
public function test_tezlik_cheklovi_ishlaydi(): void
{
for ($i = 0; $i < 6; $i++) {
$javob = $this->soragan('POST', '/kirish', [
'pochta' => '[email protected]',
'parol' => 'notogri',
]);
}
$this->assertSame(429, $javob->kodi());
}
}
Zaiflik topilganda:
- Uni ko'rsatadigan test yozing (test yiqiladi)
- Zaiflikni tuzating (test o'tadi)
- Test doim CI da ishlaydi
Shunday qilib bir marta tuzatilgan zaiflik qaytib kelmaydi.
Bog'liqliklar siyosati #
# Bog'liqliklar siyosati
## Yangi kutubxona qo'shishdan oldin
- [ ] Haqiqatan kerakmi? (25 qatorlik kod uchun kutubxona shart emas)
- [ ] Oxirgi yangilanish 12 oydan yaqinmi?
- [ ] Ochiq CVE bormi? (osv.dev da qidiring)
- [ ] Nechta o'z bog'liqligi bor? (kamroq - yaxshiroq)
- [ ] Litsenziya mos keladimi?
- [ ] Kim qo'llab-quvvatlaydi? (bitta odammi?)
## Muddatlar
| Jiddiylik | Yangilash muddati |
|-----------|-------------------|
| Kritik + ekspluatatsiya bor | 24 soat |
| Kritik | 7 kun |
| Yuqori | 30 kun |
| O'rta | 90 kun |
| Past | Keyingi rejalashtirilgan yangilanish |
## Versiyalar
- composer.lock **git da** bo'lsin
- Ishlab chiqarishda `composer install`, hech qachon `update`
- Renovate/Dependabot haftalik PR yaratadi
## Taqiqlangan
- Qo'llab-quvvatlanmaydigan kutubxonalar
- Nomi mashhur paketga o'xshash paketlar (typosquatting)
- To'g'ridan-to'g'ri git URL dan (versiya belgilanmagan)
{
"extends": ["config:recommended"],
"schedule": ["before 6am on monday"],
"vulnerabilityAlerts": {
"labels": ["xavfsizlik"],
"schedule": ["at any time"],
"automerge": false
},
"packageRules": [
{
"matchUpdateTypes": ["patch"],
"matchCurrentVersion": "!/^0/",
"automerge": true
}
]
}
Kod ko'rigi ro'yxati #
Har bir PR da tekshiring:
| Savol | Nima qidiriladi |
|---|---|
| Yangi kirish nuqtasi bormi? | Yangi marshrut, forma, API |
| Ma'lumot qayerdan keladi? | $_GET, $_POST, sarlavha, fayl |
| U tekshirildimi? | Tekshiruvchi qatlamidan o'tdimi |
| So'rov tayyorlanganmi? | Birlashtirish yo'qmi |
| Chiqish ekranlanganmi? | htmlspecialchars yoki shablon |
| Huquq tekshirildimi? | Faqat autentifikatsiya emas, avtorizatsiya ham |
| Sir kodda bormi? | Kalit, parol, token |
| Xato xabari nima oshkor qiladi? | Yo'l, versiya, SQL |
| Jurnalga nima yoziladi? | Parol, karta, token yozilmasin |
| Yangi bog'liqlik bormi? | Siyosatga mos keladimi |
| Test yozilganmi? | Salbiy holatlar ham |
# Tez qo'lda tekshiruv - PR dagi o'zgarishlar bo'yicha
git diff asosiy...HEAD -- '*.php' | grep -nE '^\+' | grep -E \
'query\(|exec\(|eval\(|shell_exec|system\(|unserialize|\$_(GET|POST|REQUEST|COOKIE)'
Xavfsizlik yetakchilari #
- PR larda xavfsizlik ko'rigini o'tkazadi
- Tahdid modeli sessiyalarini boshqaradi
- Jamoaga yangi tahdidlarni yetkazadi
- Xavfsizlik jamoasi bilan bog'lovchi
- Oyiga bir marta xavfsizlik jamoasi bilan uchrashadi
Bu to'liq stavka emas - vaqtining 20% i. Lekin xavfsizlik madaniyatini butun tashkilotga tarqatadi.
Xavfsiz standart holat #
// Yomon: xavfsizlikni yoqish kerak
$sozlama = new Sozlama();
$sozlama->csrfYoqing(); // Unutilsa - zaiflik
$sozlama->xssHimoyasiniYoqing();
// Yaxshi: xavfsizlik standart, o'chirish ongli qaror
final class Sozlama
{
private bool $csrf = true;
private bool $xss = true;
/** Faqat aniq sabab bilan o'chiring */
public function csrfOchiring(string $sabab): self
{
// Sabab jurnalga yoziladi va ko'rikda ko'rinadi
$this->jurnal->ogohlantirish('CSRF o\'chirildi', ['sabab' => $sabab]);
$this->csrf = false;
return $this;
}
}
// Marshrutlar: standart holatda himoyalangan
final class Marshrut
{
private array $himoyalar = ['auth', 'csrf', 'tezlik'];
/** Ochiq sahifa - ongli qaror */
public function ochiq(): self
{
$this->himoyalar = array_diff($this->himoyalar, ['auth']);
return $this;
}
}
// Ishlatish
$marshrutlar->get('/profil', [ProfilNazorat::class, 'korsating']); // Himoyalangan
$marshrutlar->get('/', [BoshNazorat::class, 'korsating'])->ochiq(); // Ochiq (aniq)
Agar dasturchi bir narsani unutsa, natija xavfsiz bo'lishi kerak, zaif emas.
Bu prinsip "fail secure" deb ataladi va u insonni ishonchsiz bo'g'inligini tan oladi.
Ishga tushirishdan oldingi ro'yxat #
| Talab | Bajarildi |
|---|---|
display_errors = Off | |
| Nosozliklarni tuzatish rejimi o'chirilgan | |
| Standart parollar o'zgartirilgan | |
| Sinov hisoblari o'chirilgan | |
.env, .git veb orqali ochilmaydi | |
| Barcha sirlar muhit o'zgaruvchisida | |
| HTTPS majburiy, HSTS yoqilgan | |
| Xavfsizlik sarlavhalari o'rnatilgan | |
| Tezlik cheklovi yoqilgan | |
| Jurnal markazlashtirilgan | |
| Zaxira sozlangan va sinovdan o'tgan | |
| Bog'liqliklarda kritik CVE yo'q | |
| SAST va SCA CI da o'tadi | |
| Xavfsizlik testlari yashil | |
security.txt joylashtirilgan |
- Loyihangizdagi bitta funksiya uchun 5 ta suiiste'mol holati yozing.
- Shu funksiya uchun tahdid modelini tuzing.
- Xavfsiz kod standartini loyihangiz uchun yozing.
- Kirish tekshiruvi qatlamini amalga oshiring.
- CI ga Semgrep va sirlarni qidirish qo'shing.
- Composer audit ni CI da majburiy qiling.
- Beshta xavfsizlik testini yozing (SQL, XSS, IDOR, CSRF, huquq).
- Bog'liqliklar siyosatini hujjatlang.
- Kod ko'rigi ro'yxatini jamoangizga tarqating.
- Ishga tushirish tekshiruv ro'yxatini to'ldiring.
Xulosa #
- Dizayn bosqichida topilgan zaiflik 100 marta arzon.
- Xavfsizlik talablari funksional talablar bilan birga yoziladi.
- Suiiste'mol holatlari - tahdid modelining eng oddiy shakli.
- Kirish ma'lumotini tozalamang, rad eting.
- Fayl yuklashda qayta kodlash eng kuchli himoya.
- CI da: sirlar, SCA, SAST, konteyner skani, xavfsizlik testlari.
- Har bir topilgan zaiflik uchun test yozing - qaytmasligi uchun.
- Bog'liqliklar siyosati va yangilash muddatlarini belgilang.
- Kod ko'rigida xavfsizlik ro'yxatidan foydalaning.
- Har bir jamoada xavfsizlik yetakchisi bo'lsin.
- Xavfsizlik standart holatda bo'lsin, qo'shimcha emas.
Keyingi bo'limda siyosat, muvofiqlik va boshqaruvni ko'ramiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.