15. Güvenlik Kontrol Listesi

DLE size güvenlik araçları verir, otomatik koruma vermez. Eklentinizin güvenliği tamamen sizin sorumluluğunuzdadır. Bu sayfa, sırayla kontrol etmeniz gereken alanları listeler.

✕
En sık yapılan hata: CSRF DLE'nin AJAX yönlendiricisi ve panel yükleyicisi merkezî bir CSRF denetimi yapmaz. Her işleyici kendi user_hash kontrolünü yapar. Bunu atlayan eklentiler, ziyaretçinin isteği dışında işlem yaptırılabilen açıklar üretir.

1. Dosya erişimi

Her PHP dosyanız DLE dışından çağrılamaz olmalıdır. Kalıp her zaman aynıdır:

<?php
if (!defined('DATALIFEENGINE')) {
    header("HTTP/1.1 403 Forbidden");
    header('Location: ../../');
    die("Hacking attempt!");
}
KlasörKoruma
engine/ Kapalı .htaccess ile tüm HTTP erişimi engellenir (Require all denied).
uploads/ Kısıtlı .htaccess ile .php, .cgi, .pl, .phtml dosyalarının çalıştırılması engellenir.
templates/ Dışa açık Statik dosyalar (css/js/görsel) doğrudan servis edilir.

Yani sistem klasörlerinde DATALIFEENGINE denetimi ikinci savunma hattıdır; birincisi web sunucusunun kendi erişim kuralıdır.

2. CSRF koruması (zorunlu)

Anahtar $dle_login_hash'dir ve şu şekilde üretilir:

$dle_login_hash = sha1(SECURE_AUTH_KEY . $_SERVER['HTTP_USER_AGENT']);

Form işleyicilerinde

<input type="hidden" name="user_hash" value="<?php echo $dle_login_hash; ?>">
if (!isset($_REQUEST['user_hash']) || !$_REQUEST['user_hash'] || $_REQUEST['user_hash'] != $dle_login_hash) {
    die("Hacking attempt! User not found");
}

AJAX işleyicilerinde

if (!isset($_REQUEST['user_hash']) || !$_REQUEST['user_hash'] || $_REQUEST['user_hash'] != $dle_login_hash) {
    echo "{\"error\":true, \"errorinfo\":\"Güvenlik kodu geçersiz.\"}";
    die();
}

JavaScript tarafında gönderirken user_hash: dle_login_hash eklemeyi unutmayın.

Panel işlemlerinde ek olarak: referer denetimi

DLE'nin panel işlemleri user_hash'in yanında check_referer() de çağırır (engine/inc/include/functions.inc.php). Aynı host ve aynı betik yolundan gelinmiş olmasını şart koşar:

if( !check_referer($_SERVER['SCRIPT_NAME'] . "?mod=benim-eklentim") ) {
    msg( "error", $lang['index_denied'], $lang['no_referer'], "javascript:history.go(-1)" );
}

3. Yetkilendirme

Panelde bir işlem yaptıran eklenti, kullanıcı grubunu mutlaka kontrol etmelidir:

// Kendi izin anahtarınız varsa
if (!$user_group[$member_id['user_group']]['admin_xfields']) {
    msg("error", $lang['index_denied'], $lang['index_denied']);
}

// veya yalnızca tam yönetici
if ($member_id['user_group'] != 1) {
    msg("error", $lang['addnews_denied'], $lang['db_denied']);
}
!
Menü gizlemek yetkilendirme DEĞİLDİR allow_groups alanı yalnızca menüde görünürlüğü ayarlar. Kullanıcı URL'i doğrudan yazarsa (?mod=benim-eklentim) modülünüz çalışır. Bu yüzden kod içi denetim zorunludur.

4. SQL enjeksiyonu

Veri tipiDoğru yöntem
Sayı$id = intval($_GET['id']);
Metin$ad = $db->safesql($_POST['ad']);
Kesirli sayı$f = floatval($_POST['fiyat']);
Tablo/sütun adıSabit olmalı — kullanıcıdan gelmez.
LIMIT değeriintval() ile zorlanmalı.
// DOĞRU
$id    = intval($_GET['id']);
$limit = intval($_POST['limit']);
if ($limit < 1 || $limit > 100) $limit = 10;

$db->query("SELECT id, baslik FROM " . PREFIX . "_benim_tablom WHERE id = '{$id}' LIMIT {$limit}");

// YANLIŞ — asla yapmayın
$db->query("SELECT * FROM " . PREFIX . "_post WHERE title = '{$_GET['q']}'");

safesql() tek parametre alır. Bir kullanımda ikinci parametre görürseniz (DLE'nin kendi kodunda bile rastlanır), PHP onu yok sayar — siz yazmayın.

5. XSS (çıktı kaçışı)

Kullanıcıdan veya veritabanından gelen her metni ekrana basmadan önce kaçırın:

$guvenli = htmlspecialchars($deger, ENT_QUOTES, 'UTF-8');

$tpl->set('{baslik}', $guvenli);
echo "<a href=\"#\">{$guvenli}</a>";
i
Şablon motoru sizi tamamen korumaz $tpl->set() yalnızca { ve [ karakterlerini geçici olarak kaçırır (etiket sanılmasınlar diye). <script> gibi HTML enjeksiyonunu engellemez. Kaçışı siz yapmalısınız.

6. Dosya yükleme

  • Kendi yükleyicinizi yazmak yerine DLE'nin engine/ajax/upload.php modülünü kullanın; uzantı beyaz listesi, boyut denetimi ve görsel işleme hazırdır.
  • Yüklenen dosya adını asla doğrudan kullanmayın; ../ gibi dizin atlama denemelerini engelleyin.
  • Yüklenen dosyaları uploads/ dışına yazmayın (o klasörde PHP çalıştırma engellidir).
  • Yalnızca gerçekten gereken uzantılara izin verin.

7. cron.php'yi açıkta bırakmayın

$allow_cron = 0;   // varsayılan: KAPALI — dosya 403 döner

Açmanız gerekirse DLE'nin kendi önerisini uygulayın:

  • Dosyayı cron.php yerine tahmin edilemez bir adla yeniden adlandırın.
  • Mümkünse yalnızca sunucunun IP'sinden erişilebilir yapın.
  • Tercihen hiç URL ile çağırmayın; sunucu zamanlayıcısından komut satırıyla çalıştırın.

8. PLUGINS_READ_ONLY

engine/classes/plugins.class.php başında şu sabit tanımlıdır:

define('PLUGINS_READ_ONLY', false);

true yapılırsa panelden eklenti kurma, düzenleme ve silme tamamen engellenir. Yönetimi devrettiğiniz sitelerde veya kilitli kurulumlarda kullanışlıdır.

9. DLE_API'yı açıkta bırakmayın

✕
engine/api/api.class.php kimlik doğrulaması yapmaz Kullanıcı şifresi değiştirme dahil 25 metodu vardır ve içinde api_key kontrolü yoktur. Onu çağıran bir betiği web'den erişilebilir yere koymayın.

10. Hata gösterimini kapatın

Geliştirme sırasında açtığınız hata gösterimi yayında kapalı olmalıdır (Sistem Ayarları → PHP hatalarını göster). Aksi hâlde sunucu yolları ve veritabanı bilgileri ziyaretçilere sızabilir.

11. Yedekleme ve geri alma

  • Veritabanı tablonuz literatürde {prefix}_ ile başlamalı ki DLE'nin yedekleme aracı onu bulsun.
  • mysqldelete ve phpdelete bloklarınızı test edin; silinen eklentinin artıkları kalmasın.

12. Çekirdek dosyaları koruyun

DLE'nin antivirus sınıfı, korunması gereken dosyaların bir listesini tutar. Eklenti silinirken filedelete mekanizması bu listeyi atlar; yani yanlış yapılandırılmış bir filelist çekirdek dosyalarınızı silmez.

Ayrıca şu dosyalar eklenti yamasına tamamen kapalıdır: engine/classes/mysql.php, engine/classes/plugins.class.php, engine/data/config.php, dbconfig.php, socialconfig.php, videoconfig.php.

Güvenlik kontrol listesi (özet)

#Kontrol
1Her PHP dosyasında DATALIFEENGINE denetimi var.
2Tüm form/AJAX işlemlerinde user_hash doğrulanıyor.
3Panel işlemlerinde check_referer() var.
4Kod içi grup/izin denetimi var (menü gizlemesine güvenilmiyor).
5Sayısal girdiler intval(), metinler safesql().
6Tüm çıktılar htmlspecialchars(…, ENT_QUOTES, 'UTF-8') ile kaçırılıyor.
7Dosya yükleme DLE'nin yükleyicisiyle veya güvenli doğrulamayla yapılıyor.
8Kullanıcıdan gelen dosya adlarında dizin atlama engellenmiş.
9Yayında PHP hata gösterimi kapalı.
10DLE_API veya cron gibi korumasız uçlar açıkta değil.
11Hassas veri (anahtar, şifre) kaynak kodda veya çıktıda yok.
12Eklenti silindiğinde veri ve dosya artığı kalmıyor.

Sırada: Paketleme ve Yayın.