Sual 🧑‍💻 Gəlin birlikdə səhv tapaq!

İlqar Ramizoğlu

Rəhbər
Administrator
Qoşulub
1 Oktyabr 2022
Mesajlar
121
Dostlar, bu gündən etibarən yeni bir rubrika başlayırıq: “Kodda səhv axtar!” 🔎
Məqsədimiz həm öyrənmək, həm də maraqlı müzakirələr aparmaqdır.

Aşağıda bir neçə kod nümunəsi paylaşmışam. Onların içində qəsdən buraxılmış səhvlər var.
Sizdən xahiş: səhvləri tapın və şərhdə yazın ✍️



🔹 C# nümunəsi​



Kod:
using System;

class Program
{
static void Main(string[] args)
{
int x = 5;
int y = "10"; // burda nə isə səhvdir
if (x = y)    // bura da diqqət edin 😉
{
Console.WriteLine("Bərabərdir");
}
else
{
Console.WriteLine("Fərqlidir");
}
}
}




🔹 SQL nümunəsi​



Kod:
SELECT name age FROM employees
WHERE age > "25";




🔹 CSS nümunəsi​



Kod:
body {
background-colour: red;
font-size: 16;
}




👉 Sual: Sizcə bu kod parçalarında hansı səhvlər var?
Hər kəs öz fikrini yazsın, sonda isə biz birlikdə düz versiyanı paylaşacağıq ✅
 
C# ilə bağlı səhv artıq bildirilib.

SQL sorğuda sintaksis xətaları var. Belə olmalı idi:
SELECT name, age
FROM employees
WHERE age > 25;
(name ilə age arasında , olmalı idi. Yaş int tipi hesab edilir deyə "25" yalnışdr )


CSS:
body {
background-colour: red; // background-color: red;
font-size: 16;
}
 
Gəlin birlikdə səhv tapaq:

<?php
include 'db.php';

if (isset($_POST['submit'])) {
$name = $_POST['name'];
$email = $_POST['mail'];

$sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')";
$result = mysqli_querry($conn, $sql);

if ($result) {
echo "Məlumat əlavə edildi!";
} else {
echo "Xəta: " . mysqli_error($conn);
}
}
?>
<form method="post" action="">
Ad: <input type="text" name="name"><br>
Email: <input type="text" name="email"><br>
<input type="submit" name="submit" value="Göndər">
</form>
 
Gəlin birlikdə səhv tapaq:

<?php
include 'db.php';

if (isset($_POST['submit'])) {
$name = $_POST['name'];
$email = $_POST['mail'];

$sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')";
$result = mysqli_querry($conn, $sql);

if ($result) {
echo "Məlumat əlavə edildi!";
} else {
echo "Xəta: " . mysqli_error($conn);
}
}
?>
<form method="post" action="">
Ad: <input type="text" name="name"><br>
Email: <input type="text" name="email"><br>
<input type="submit" name="submit" value="Göndər">
</form>
Kodda bir neçə səhv var:
  1. mysqli_querry yazılıb → düzgün funksiyanın adı mysqli_query olmalıdır.
    Kod:
    $result = mysqli_query($conn, $sql);

  2. Formdakı input name ilə PHP-də oxunan dəyişən fərqlidir:
    • Formda name="email" yazmısınız, amma kodda $_POST['mail'] oxuyursunuz.
      Düzgünü belə olmalıdır:
    Kod:
    $email = $_POST['email'];

  3. (Məsləhət olaraq) SQL sorğusunda dəyişənləri birbaşa qoymaq təhlükəlidir → SQL Injection riski var. mysqli_real_escape_string və ya prepared statement istifadə etmək daha düzgün olar.

Düzəldilmiş variant:

Kod:
<?php
include 'db.php';

if (isset($_POST['submit'])) {
    $name = $_POST['name'];
    $email = $_POST['email']; // düzəldildi

    $sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')";
    $result = mysqli_query($conn, $sql); // düzəldildi

    if ($result) {
        echo "Məlumat əlavə edildi!";
    } else {
        echo "Xəta: " . mysqli_error($conn);
    }
}
?>
<form method="post" action="">
    Ad: <input type="text" name="name"><br>
    Email: <input type="text" name="email"><br>
    <input type="submit" name="submit" value="Göndər">
</form>
 
Gəlin birlikdə səhv tapaq:

<?php
include 'db.php';

if (isset($_POST['submit'])) {
$name = $_POST['name'];
$email = $_POST['mail'];

$sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')";
$result = mysqli_querry($conn, $sql);

if ($result) {
echo "Məlumat əlavə edildi!";
} else {
echo "Xəta: " . mysqli_error($conn);
}
}
?>
<form method="post" action="">
Ad: <input type="text" name="name"><br>
Email: <input type="text" name="email"><br>
<input type="submit" name="submit" value="Göndər">
</form>
Gəl, təhlükəsiz prepared statement ilə tam işləyən nümunə verim. Burada e-poçtu yoxlayırıq, girişləri trim() ilə təmizləyirik və mysqli prepared statement istifadə edirik:

Kod:
<?php
include 'db.php'; // burada $conn mysqli bağlantısı olmalıdır

if (isset($_POST['submit'])) {
    // təmizləmə və yoxlama
    $name = trim($_POST['name'] ?? '');
    $email = trim($_POST['email'] ?? '');

    if ($name === '' || $email === '') {
        echo "Zəhmət olmasa bütün sahələri doldurun.";
        exit;
    }

    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        echo "Düzgün e-mail daxil edin.";
        exit;
    }

    // Prepared statement ilə təhlükəsiz INSERT
    $sql = "INSERT INTO users (`name`, `email`) VALUES (?, ?)";
    $stmt = mysqli_prepare($conn, $sql);

    if (!$stmt) {
        // hazırlama alınmadıqda xəta göstər
        echo "Hazırlama xətası: " . mysqli_error($conn);
        exit;
    }

    // Parametrləri bağla: "ss" — iki string
    mysqli_stmt_bind_param($stmt, "ss", $name, $email);

    // icra et
    if (mysqli_stmt_execute($stmt)) {
        echo "Məlumat əlavə edildi!";
    } else {
        echo "İcra xətası: " . mysqli_stmt_error($stmt);
    }

    // təmizlik
    mysqli_stmt_close($stmt);
}
?>
<form method="post" action="">
    Ad: <input type="text" name="name"><br>
    Email: <input type="text" name="email"><br>
    <input type="submit" name="submit" value="Göndər">
</form>


Qısa izah:


  • ? yerlərinə bind_param ilə verilənlər təhlükəsiz şəkildə ötürülür — SQL Injection riski azalır.
  • filter_var(..., FILTER_VALIDATE_EMAIL) e-mail formatını yoxlayır.
  • Xətalar üçün mysqli_error və mysqli_stmt_error istifadə olundu.
 
Gəl, təhlükəsiz prepared statement ilə tam işləyən nümunə verim. Burada e-poçtu yoxlayırıq, girişləri trim() ilə təmizləyirik və mysqli prepared statement istifadə edirik:

Kod:
<?php
include 'db.php'; // burada $conn mysqli bağlantısı olmalıdır

if (isset($_POST['submit'])) {
    // təmizləmə və yoxlama
    $name = trim($_POST['name'] ?? '');
    $email = trim($_POST['email'] ?? '');

    if ($name === '' || $email === '') {
        echo "Zəhmət olmasa bütün sahələri doldurun.";
        exit;
    }

    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        echo "Düzgün e-mail daxil edin.";
        exit;
    }

    // Prepared statement ilə təhlükəsiz INSERT
    $sql = "INSERT INTO users (`name`, `email`) VALUES (?, ?)";
    $stmt = mysqli_prepare($conn, $sql);

    if (!$stmt) {
        // hazırlama alınmadıqda xəta göstər
        echo "Hazırlama xətası: " . mysqli_error($conn);
        exit;
    }

    // Parametrləri bağla: "ss" — iki string
    mysqli_stmt_bind_param($stmt, "ss", $name, $email);

    // icra et
    if (mysqli_stmt_execute($stmt)) {
        echo "Məlumat əlavə edildi!";
    } else {
        echo "İcra xətası: " . mysqli_stmt_error($stmt);
    }

    // təmizlik
    mysqli_stmt_close($stmt);
}
?>
<form method="post" action="">
    Ad: <input type="text" name="name"><br>
    Email: <input type="text" name="email"><br>
    <input type="submit" name="submit" value="Göndər">
</form>


Qısa izah:


  • ? yerlərinə bind_param ilə verilənlər təhlükəsiz şəkildə ötürülür — SQL Injection riski azalır.
  • filter_var(..., FILTER_VALIDATE_EMAIL) e-mail formatını yoxlayır.
  • Xətalar üçün mysqli_error və mysqli_stmt_error istifadə olundu.

Çox gözəl izah 👏
 
Gəl, təhlükəsiz prepared statement ilə tam işləyən nümunə verim. Burada e-poçtu yoxlayırıq, girişləri trim() ilə təmizləyirik və mysqli prepared statement istifadə edirik:

Kod:
<?php
include 'db.php'; // burada $conn mysqli bağlantısı olmalıdır

if (isset($_POST['submit'])) {
    // təmizləmə və yoxlama
    $name = trim($_POST['name'] ?? '');
    $email = trim($_POST['email'] ?? '');

    if ($name === '' || $email === '') {
        echo "Zəhmət olmasa bütün sahələri doldurun.";
        exit;
    }

    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        echo "Düzgün e-mail daxil edin.";
        exit;
    }

    // Prepared statement ilə təhlükəsiz INSERT
    $sql = "INSERT INTO users (`name`, `email`) VALUES (?, ?)";
    $stmt = mysqli_prepare($conn, $sql);

    if (!$stmt) {
        // hazırlama alınmadıqda xəta göstər
        echo "Hazırlama xətası: " . mysqli_error($conn);
        exit;
    }

    // Parametrləri bağla: "ss" — iki string
    mysqli_stmt_bind_param($stmt, "ss", $name, $email);

    // icra et
    if (mysqli_stmt_execute($stmt)) {
        echo "Məlumat əlavə edildi!";
    } else {
        echo "İcra xətası: " . mysqli_stmt_error($stmt);
    }

    // təmizlik
    mysqli_stmt_close($stmt);
}
?>
<form method="post" action="">
    Ad: <input type="text" name="name"><br>
    Email: <input type="text" name="email"><br>
    <input type="submit" name="submit" value="Göndər">
</form>


Qısa izah:


  • ? yerlərinə bind_param ilə verilənlər təhlükəsiz şəkildə ötürülür — SQL Injection riski azalır.
  • filter_var(..., FILTER_VALIDATE_EMAIL) e-mail formatını yoxlayır.
  • Xətalar üçün mysqli_error və mysqli_stmt_error istifadə olundu.

Təhlükəsizlikdən danışırıqsa bir neçə əlavə də mən edim. :)
Bir neçə kiçik məqam nəzərə alınmalıdır:
  1. form göndərildikdən sonra istifadəçi məlumatını ekranda göstərmək istəsə (echo $name) → XSS riski var. Məsələn, istifadəçi
    "<script> ... </script>" göndərsə, server onu təmizləmədən göstərərsə brauzer həmin script-i icra edər
    • Həll: htmlspecialchars($name, ENT_QUOTES, 'UTF-8') istifadə etmək.
  2. Email uzunluğu yoxlanılmır.
    • DB sütunu limitindən uzun email daxil edilərsə insert xətası ala bilər.
    • Həll: strlen($email) yoxlamaq və ya DB-də uyğun limit təyin etmək.
  3. CSRF qorunması yoxdur. Kimsə formu başqa saytdan avtomatik göndərə bilər.
    • Həll: csrf_token əlavə etmək.
 
Təhlükəsizlikdən danışırıqsa bir neçə əlavə də mən edim. :)
Bir neçə kiçik məqam nəzərə alınmalıdır:
  1. form göndərildikdən sonra istifadəçi məlumatını ekranda göstərmək istəsə (echo $name) → XSS riski var. Məsələn, istifadəçi
    "<script> ... </script>" göndərsə, server onu təmizləmədən göstərərsə brauzer həmin script-i icra edər
    • Həll: htmlspecialchars($name, ENT_QUOTES, 'UTF-8') istifadə etmək.
  2. Email uzunluğu yoxlanılmır.
    • DB sütunu limitindən uzun email daxil edilərsə insert xətası ala bilər.
    • Həll: strlen($email) yoxlamaq və ya DB-də uyğun limit təyin etmək.
  3. CSRF qorunması yoxdur. Kimsə formu başqa saytdan avtomatik göndərə bilər.
    • Həll: csrf_token əlavə etmək.
👍 Mən də əlavə edim ki, bu kimi form işləmələrində başqa bəzi məqamlar da var:

4. SQL Injection riski

Sənin kodunda $sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')"; yazılıb. Əgər istifadəçi '); DROP TABLE users; -- kimi zərərli input göndərsə, DB-də ciddi zərər ola bilər.

Həll: mysqli_prepare və bind_param istifadə etmək lazımdır.



5. Email formatı yoxlanmır

Sadəcə uzunluğu yoxlamaq kifayət etmir. Email ümumiyyətlə düzgün formatdadırmı?

Həll: filter_var($email, FILTER_VALIDATE_EMAIL) istifadə etmək.



6. Name üçün validasiya yoxdur

İstifadəçi adında rəqəm, xüsusi simvol, çox uzun text göndərə bilər.

Həll: Regex və ya uzunluq limitləri ilə yoxlamaq.



7. Error mesajları çox açıqdır

echo "Xəta: " . mysqli_error($conn); – bu cümlə DB strukturu barədə həssas məlumatı istifadəçiyə açır.

Həll: İstifadəçiyə sadə mesaj (“Gözlənilməz xəta baş verdi”) göstərmək, əsl xətanı isə log faylına yazmaq.



8. HTTPS istifadə edilmirsə məlumatlar açıq gedir

Form HTTP üzərindən göndərilərsə, şifrlənmədiyi üçün məlumat oğurlana bilər.

Həll: HTTPS məcburi edilməlidir.
 
Geri
Yuxarı Aşağı