v2.5.2
Giriş yap

Ajax API Güvenliği Hk.

r00t
427 defa görüntülendi

Merhabalar;
Sorum özellikle PHP projelerimdeki Ajax requestlerimin güvenliği için ortaya çıkıyor. Ancak her dil için ortak noktaları elbet vardır.
Sizlerin bu tarz Ajax ile GET/POST gibi requestlerinizde, endpoint tarafında vs. mutlaka dikkat ettiğiniz noktalar nelerdir? Gerek front-end tarafında isteği yollarken, gerek hedef backend dosya üzerinde yaptığınız kontroller vs.
Örneğin;
POST isteği var mı? CSRF-TOKEN eşleşiyor mu? Referer kontrolü, Dosyaya link üzerinden direct access'i blocklama, parametreleri sanitize etme vb.vb.

Gerek buraya aklınıza gelen maddeleri, gerekse faydalanabileceğimiz linkleri bırakırsanız; bu konu başlığı aracılığı ile pek çok kişiye faydası dokunur diye düşünüyorum.

saygılar

sefaaydin
625 gün önce

Bu kısım Ajaxtan gelen verileri aldığımız PHP dosyası. $csrf_token, $recaptcha Göndermeyi unutmayın.
Bunun bir gelişmişi vardı. Bulamadım. Orada şöyle bir işlem daha yapmıştım. Ajax query alan adından mı geliyor? veya bu alan adından gelmeyen ajax isteklerini şuraya yönlendir gibi özellikler vardı. Sende buna göre düzenleyebilirsin.



function isAjaxRequest(){
    return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
}

$errors = [];
$data   = [];


if (isAjaxRequest()){
    
    if(isset($_POST) & !empty($_POST)){

        $postAdi      = strip_tags($_POST["postAdi"]);

        if(empty($recaptcha)){
            $data['status'] = 'error';
            $errors['recaptcha'] = 'Please check the the captcha form.';
            $data['errors'] = $errors;
        }else{

            // CSRF Token Validation
            if(isset($csrf_token)){
                if($csrf_token === $_SESSION['csrf_token']){

                    // CSRF Token Time Validation
                    $max_time = 60*60*24; // in seconds
                    if(isset($_SESSION['csrf_token_time'])){
                        $token_time = $_SESSION['csrf_token_time'];
                        if(($token_time + $max_time) >= time() ){

                            // Tüm hataları burada kontrol edebilirsin.
                            if (empty($postAdi)) {
                                $errors['hataAdi'] = 'Hata açıklaması bu alanda olmalı.';
                            }
                
                            // eğer $errors değişkeni boş değilse hatalar geri dönecek.
                            if (!empty($errors)) {
                                $data['status'] = 'error';
                                $data['errors'] = $errors;
                            } else {
                                // $errors değişkeni boşsa işlemler burada başlayacak.
                                // veritabanı vs işlemleri
                                
                                $data['status'] = 'success';
                                $data['message']= 'işleminiz başarıyla gerçekleşti.';
                            }

                        }else{
                            $errors['csrfExpired'] = 'CSRF token hatası. Sayfayı yenileyin!';
                            $data['status'] = 'error';
                            $data['errors'] = $errors;
                            unset($_SESSION['csrf_token']);
                            unset($_SESSION['csrf_token_time']);
                        }
                    }else{
                        $errors['csrfTime'] = 'CSRF token süresi dolmuştur. Lütfen sayfayı yenileyin!';
                        $data['status'] = 'error';
                        $data['errors'] = $errors;
                    }

                }else{
                    $errors['csrfValidate'] = 'CSRF Token doğrulama hatası. Lütfen sayfayı yenileyin!';
                    $data['status'] = 'error';
                    $data['errors'] = $errors;
                }
            }else{
                $errors['csrfToken'] = 'CSRF Token bulunamadı. Lütfen sayfayı yenileyin!';
                $data['status'] = 'error';
                $data['errors'] = $errors;
            }
        }
    }else {
        $errors['realuser'] = "İstek yöntemi POST değil veya Sayfaya gönderilen POST mevcut değil!";
        $data['status'] = 'error';
        $data['errors'] = $errors;
    }
} else {
    $errors['pageError'] = "Kullanılabilir istek yok veya Gelen istek Ajax değerinde değil!";
    $data['status'] = 'error';
    $data['errors'] = $errors;
}


echo json_encode($data);