Veb
CORS noto'g'ri sozlanganda: Origin'ni aks ettirish, wildcard va null
CORS himoya emas, balki brauzerga beriladigan ruxsat. Noto'g'ri sozlansa, begona sayt foydalanuvchi nomidan API'ingizdan ma'lumot o'qiydi. curl bilan tekshirish va to'g'ri sozlash.
· 9 daq. o'qish

CORS (Cross-Origin Resource Sharing) haqida dasturchilar ko'pincha bitta holatda o'ylaydi: frontend API'ga so'rov yuboradi va brauzer konsolida qizil xato chiqadi. Tez yechim sifatida internetdan topilgan "hammasiga ruxsat" sozlamasi qo'yiladi va xato yo'qoladi. Bu sozlama production'ga ham o'tadi va keyin hech kim unga qaytmaydi.
Bu maqolada CORS aslida nima qilishini, qaysi sozlamalar xavfli ekanini, ularni curl bilan qanday tekshirishni va Laravel, Node hamda nginx'da qanday to'g'ri sozlashni ko'rsatamiz.
CORS nima va nima emas
Brauzerda Same-Origin Policy degan asosiy qoida bor: https://evil.example sahifasidagi JavaScript https://api.your-domain.uz ga so'rov yuborishi mumkin, lekin javobni o'qiy olmaydi. Origin — bu sxema, domen va port birikmasi: https://app.your-domain.uz va https://api.your-domain.uz turli origin hisoblanadi.
CORS — bu qoidadan ongli ravishda istisno qilish mexanizmi. Server javobga quyidagi headerlarni qo'shib, brauzerga "bu origin'ga javobni o'qishga ruxsat ber" deydi:
Access-Control-Allow-Origin: https://app.your-domain.uz
Access-Control-Allow-Credentials: true
Ikki muhim xulosa:
- CORS himoya qatlami emas, ruxsat qatlami. U cheklovni yumshatadi, kuchaytirmaydi. Har bir noto'g'ri qiymat — qo'shimcha ochilgan eshik.
- CORS faqat brauzerda ishlaydi.
curl, server yoki mobil ilova CORS'ga e'tibor bermaydi. Shuning uchun CORS avtorizatsiya o'rnini bosmaydi: API har bir so'rovda foydalanuvchini o'zi tekshirishi kerak.
Nima uchun bu ekspertiza uchun muhim
CORS xatosining xavfi — foydalanuvchining brauzeri hujum vositasiga aylanishida. Foydalanuvchi sizning tizimingizga kirgan holda begona sahifani ochadi. Agar API cookie bilan ishlasa va CORS istalgan origin'ga ishonch bildirsa, o'sha sahifadagi skript foydalanuvchi nomidan so'rov yuborib, javobni — profil, hisobotlar, tokenlar — o'qib oladi va o'z serveriga jo'natadi.
Ekspertizada bu "Security Misconfiguration" yoki ma'lumot ochiqlanishi sifatida baholanadi. Uni topish oson: bir nechta curl so'rovi yetarli. Shuning uchun bu band ekspertizadan oldin albatta tekshirilishi kerak bo'lgan sozlamalar qatoriga kiradi.
Xavfli holat 1: Origin'ni aks ettirish + credentials
Eng jiddiy xato. Server so'rovdagi Origin headerini olib, javobga o'zgarishsiz qaytaradi va cookie'larga ruxsat beradi:
Access-Control-Allow-Origin: https://evil.example
Access-Control-Allow-Credentials: true
Bu amalda "har qanday sayt foydalanuvchi nomidan API'ni o'qishi mumkin" degani. Ko'pincha bu quyidagicha kod natijasi:
// XATO
app.use(cors({ origin: true, credentials: true }));
origin: true — cors paketida "kelgan Origin'ni aks ettir" degan ma'noni beradi.
Xavfli holat 2: wildcard
Access-Control-Allow-Origin: * — "har qanday origin javobni o'qishi mumkin". Brauzerlar * ni Allow-Credentials: true bilan birga qabul qilmaydi, shuning uchun cookie bilan himoyalangan ma'lumot to'g'ridan-to'g'ri o'qilmaydi. Lekin * baribir xavfli bo'lishi mumkin:
- API ichki tarmoqdagi yoki IP bo'yicha cheklangan resurslarni autentifikatsiyasiz qaytarsa.
- Token cookie'da emas, lekin boshqa "ambient" usul bilan (masalan, IP ruxsati) beriladigan bo'lsa.
- Dasturchi
*ishlamagani uchun keyinroq uni "Origin'ni aks ettirish" ga almashtirsa — bu esa 1-holatga olib keladi.
Ommaviy, haqiqatan ochiq ma'lumot (masalan, valyuta kurslari) uchun * qabul qilinadi. Shaxsiy kabinet API'si uchun — yo'q.
Xavfli holat 3: null origin
Ba'zi sozlamalarda ruxsat etilganlar ro'yxatida null turadi — ko'pincha lokal fayllarni sinash uchun qo'shilgan. Lekin Origin: null ni hujumchi ham yuborishi mumkin: sandbox qilingan iframe, data: URL yoki file:// sahifasidan kelgan so'rovlar shu qiymat bilan yuboriladi. null ni hech qachon ruxsat etilgan origin sifatida qo'ymang.
Xavfli holat 4: noto'g'ri tekshirish (regex va endsWith)
Ruxsat etilgan origin'larni tekshirish kodida xato bo'lsa, ro'yxat bor bo'lsa ham u chetlab o'tiladi:
// XATO: evilyour-domain.uz ham, your-domain.uz.evil.example ham o'tadi
if (origin.endsWith('your-domain.uz') || origin.includes('your-domain.uz')) { ... }
// XATO: nuqta qochirilmagan, langar yo'q
/https:\/\/.*.your-domain.uz/
To'g'ri usul — aniq ro'yxat bo'yicha to'liq tenglik yoki qat'iy langarlangan regex:
/^https:\/\/([a-z0-9-]+\.)?your-domain\.uz$/
Yana bir eslatma: http:// origin'larni (shifrlanmagan) production ro'yxatiga qo'shmang — tarmoqdagi hujumchi ularning nomidan kontent kirita oladi.
curl bilan qanday tekshirish
Begona origin bilan so'rov yuboring va javobdagi Access-Control-* headerlarini ko'ring:
curl -si https://api.your-domain.uz/v1/me \
-H "Origin: https://evil.example" | grep -i access-control
curl -si https://api.your-domain.uz/v1/me \
-H "Origin: null" | grep -i access-control
curl -si https://api.your-domain.uz/v1/me \
-H "Origin: https://your-domain.uz.evil.example" | grep -i access-control
Preflight (OPTIONS) so'rovini ham tekshiring — PUT, DELETE yoki maxsus headerli so'rovlardan oldin brauzer aynan shuni yuboradi:
curl -si -X OPTIONS https://api.your-domain.uz/v1/profile \
-H "Origin: https://evil.example" \
-H "Access-Control-Request-Method: DELETE" \
-H "Access-Control-Request-Headers: authorization" | grep -i access-control
Natijani qanday o'qish:
- Begona origin javobda qaytsa va
Allow-Credentials: truebo'lsa — jiddiy topilma. Allow-Origin: nullqaytsa — topilma.*qaytsa — endpoint qanday ma'lumot berishiga qarab baholang.- Begona origin uchun
Access-Control-Allow-Originumuman yo'q — to'g'ri.
Barcha asosiy endpointlarni, jumladan login, profil, fayl yuklab olish va admin API'larini sinang. Ba'zan CORS umumiy middleware'da emas, alohida kontrollerda qo'lda yozilgan bo'ladi.
Laravel'da to'g'ri sozlash
Laravel CORS'ni o'rnatilgan HandleCors middleware va config/cors.php orqali boshqaradi (Laravel 11+ da faylni php artisan config:publish cors bilan chiqarish mumkin):
return [
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
'allowed_origins' => [
'https://app.your-domain.uz',
'https://admin.your-domain.uz',
],
'allowed_origins_patterns' => [],
'allowed_headers' => ['Content-Type', 'Authorization', 'X-Requested-With', 'X-XSRF-TOKEN'],
'exposed_headers' => [],
'max_age' => 600,
'supports_credentials' => true,
];
E'tibor bering:
allowed_originsda'*'vasupports_credentials => truebirga turmasin.- Origin'larni muhitga qarab
.envdan o'qish qulay, lekin production qiymati aniq domenlar ro'yxati bo'lishi kerak. allowed_origins_patternsishlatsangiz, regex^va$bilan langarlangan, nuqtalar qochirilgan bo'lsin.
Node (Express) da to'g'ri sozlash
const allowed = new Set([
'https://app.your-domain.uz',
'https://admin.your-domain.uz',
]);
app.use(cors({
origin(origin, cb) {
// Origin yo'q — brauzerdan tashqari so'rov (curl, server); CORS headeri kerak emas
if (!origin) return cb(null, false);
cb(null, allowed.has(origin));
},
credentials: true,
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
maxAge: 600,
}));
cors paketi origin dinamik bo'lganda Vary: Origin headerini qo'shadi. Bu muhim: aks holda proksi yoki CDN bitta origin uchun berilgan javobni keshlab, boshqasiga ham qaytarishi mumkin.
nginx darajasida
Agar CORS headerlarini nginx qo'shsa, $http_origin ni to'g'ridan-to'g'ri qaytarmang — avval map bilan tekshiring:
map $http_origin $cors_origin {
default "";
"https://app.your-domain.uz" $http_origin;
"https://admin.your-domain.uz" $http_origin;
}
server {
location /api/ {
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Vary Origin always;
# ...
}
}
Bo'sh qiymatli add_header nginx tomonidan yuborilmaydi, shuning uchun ro'yxatda yo'q origin header olmaydi. Bitta joyda sozlang: CORS ham ilovada, ham nginx'da qo'shilsa, takroriy headerlar paydo bo'ladi va brauzer javobni rad etadi.
Bog'liq mavzular
CORS cookie bilan ishlaydigan API'larda CSRF bilan yaqin bog'liq: CORS javobni o'qishni boshqaradi, lekin so'rov yuborilishini to'xtatmaydi. Shuning uchun holatni o'zgartiruvchi so'rovlar CSRF token yoki SameSite cookie bilan alohida himoyalanishi kerak. Token qayerda saqlanishi haqida JWT maqolasida yozganmiz, API bo'yicha umumiy ro'yxat esa OWASP API Top 10 maqolasida.
CORS ro'yxati — bu "biz kimga ishonamiz" degan qaror. U qisqa, aniq va har bir qatori asoslangan bo'lishi kerak.
Checklist
- Ruxsat etilgan origin'lar aniq ro'yxat; Origin aks ettirilmaydi.
*vaAllow-Credentials: truebirga ishlatilmaydi; shaxsiy API'da*yo'q.nullvahttp://origin'lar ro'yxatda yo'q.- Regex tekshiruvlar langarlangan, nuqtalar qochirilgan;
endsWith/includesishlatilmaydi. - Dinamik origin bo'lsa,
Vary: Originyuboriladi. - Ruxsat etilgan usullar va headerlar minimal.
- CORS bitta joyda (ilova yoki nginx) sozlangan.
- API har bir so'rovda avtorizatsiyani CORS'dan mustaqil tekshiradi.
- Begona,
nullva o'xshash domenli origin'lar bilancurltekshiruvi o'tkazilgan.
Xulosa
CORS xatosi kodda emas, bitta konfiguratsiya qatorida yashaydi va ko'pincha "vaqtincha" qo'yilgan bo'ladi. Uni topish ham, tuzatish ham bir necha daqiqa oladi — faqat buni ekspertizadan oldin qilish kerak.
API'ingiz qaysi origin'larga ishonayotganini tekshirmoqchimisiz? Skanerlash uchun ariza qoldiring — Claude AI agenti sozlamalar va kodni ko'rib chiqadi, mutaxassisimiz topilmalarni tasdiqlab, ularni yopishga yordam beradi.


