FlawOpen

flawopen.com/SQL Injection in PHP/Doctrine ORM

Apakah Doctrine ORM aman dari injeksi SQL?

Reference page
Jawaban singkat

DQL aman jika memakai parameter terikat. Merangkai DQL atau SQL native dengan string mengembalikan risiko seperti kueri mentah biasa.

TIDAK AMAN — input menjadi sintaks DQL
$em->createQuery(
  "SELECT u FROM User u "
  . "WHERE u.id = $userId"
);
AMAN — gunakan ekspresi tepercaya
$qb->select('u')
  ->from('User', 'u')
  ->where('u.id = :id')
  ->setParameter('id', $userId);

Nilai terikat tidak melindungi struktur kueri

setParameter() mengikat nilai DQL, lalu Doctrine menerjemahkannya menjadi parameter SQL yang terpisah dari teks kueri. Menggabungkan input ke createQuery() melewati perlindungan itu. Aturan yang sama berlaku pada SQL native: Connection::executeQuery() aman dengan placeholder dan array parameter, bukan saat input disisipkan ke string SQL.

Parameter tidak dapat menggantikan identifier

Placeholder mewakili nilai, bukan identifier DQL, kolom/tabel SQL, operator, atau arah urut. Panduan keamanan ORM memperingatkan bahwa input pengguna pada metode ekspresi QueryBuilder masih dapat membentuk DQL yang dapat diinjeksi. Simpan ekspresi dalam kode tepercaya dan petakan pilihan urut melalui allow-list ketat.

TIDAK AMAN — input menjadi sintaks DQL
$qb->orderBy(
  'u.' . $request->query->get('sort'),
  $request->query->get('direction')
);
AMAN — gunakan ekspresi tepercaya
$fields = [
    'name' => 'u.name',
    'created' => 'u.createdAt',
];
$directions = ['asc' => 'ASC', 'desc' => 'DESC'];

$key = (string) $request->query->get('sort', 'name');
$sort = $fields[$key] ?? $fields['name'];
$requestedDirection = strtolower(
    (string) $request->query->get('direction', 'asc')
);
$direction = $directions[$requestedDirection] ?? 'ASC';

$qb->orderBy($sort, $direction);

Cara memeriksa basis kode

rg -n -g '*.php' 'createQuery\(|orderBy\(|addOrderBy\(|executeQuery\(' .
Tinjau setiap hasil untuk concatenation/interpolation, input pengguna pada API ekspresi, dan identifier di luar allow-list tetap. Hasil pencarian adalah kandidat tinjauan, bukan bukti dapat dieksploitasi.

Sumber dan referensi

Lihat juga SQL Injection (CWE-89): cara kerja dan cara mencegahnya di setiap bahasa — flawopen.com EF Core FromSqlRaw: SQL berparameter yang aman Injeksi SQL FastAPI: Yang Dicegah dan Tidak Dicegah Pydantic GORM Raw SQL: Cegah Injeksi SQL di Go Apakah Escape Tanda Kutip Cukup untuk Mencegah SQL Injection? Apakah memakai ORM cukup untuk mencegah SQL Injection? Apakah Knex.js aman dari SQL Injection?