flawopen.com/SQL Injection in PHP/Doctrine ORM
Apakah Doctrine ORM aman dari injeksi SQL?
DQL aman jika memakai parameter terikat. Merangkai DQL atau SQL native dengan string mengembalikan risiko seperti kueri mentah biasa.
$em->createQuery( "SELECT u FROM User u " . "WHERE u.id = $userId" );
$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.
$qb->orderBy(
'u.' . $request->query->get('sort'),
$request->query->get('direction')
);
$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);
- ✓Ikat setiap nilai eksternal dengan setParameter() atau placeholder DBAL; jangan gabungkan ke DQL atau SQL.
- ✓Perlakukan metode ekspresi QueryBuilder dan fragmen DQL sebagai kode. Batasi field, arah urut, operator, dan fungsi pilihan pengguna dengan allow-list.
- ✓Untuk SQL native, gunakan executeQuery($sql, $params) atau executeStatement($sql, $params) dengan placeholder.
- ✓Periksa aliran data dan struktur kueri. Nilai berparameter tetap dapat membuka rekaman tanpa izin; terapkan otorisasi secara terpisah.
Cara memeriksa basis kode
rg -n -g '*.php' 'createQuery\(|orderBy\(|addOrderBy\(|executeQuery\(' .Sumber dan referensi
- Doctrine ORM — parameter QueryBuilder
- Doctrine ORM — keamanan
- Doctrine DBAL — kueri siap pakai dan parameter
- FlawOpen — injeksi SQL PHP