FlawOpen

flawopen.com/Command Injection/exec() vs execFile()

Apa perbedaan exec() dan execFile() di Node.js?

Panduan referensi
Jawaban singkat

exec() menerima satu string dan menjalankannya melalui shell: pipe dan wildcard berfungsi, tetapi metakarakter shell dalam input tak tepercaya juga dapat mengubah perintah. execFile() menjalankan program yang ditentukan secara langsung dengan array argumen dan tanpa shell secara default. Ini mencegah parsing shell, tetapi tidak menghilangkan semua risiko: program tujuan masih dapat menafsirkan argumen sebagai opsi atau bertindak atas nilai yang tidak diharapkan.

Perbandingan

exec() — menggunakan shell
exec(`ls ${dir} | grep .txt`,
  (err, out) => {...})
// pipe berfungsi, tetapi metakarakter juga berpengaruh.
execFile() — tanpa shell secara default
execFile('ls', [dir],
  (err, out) => {...})
// tanpa shell; validasi cara ls menafsirkan argumen dir.
// break out of its own argument

Saat fitur shell benar-benar diperlukan

Jika perintah benar-benar memerlukan pipe, ekspansi glob, atau pengalihan shell, execFile() tidak dapat menyatakannya secara langsung. Sebaiknya susun pipeline di Node.js dengan menjalankan setiap tahap secara terpisah dan menghubungkan stream. Jika exec() tidak dapat dihindari, jangan masukkan input tak tepercaya ke string perintah. Array argumen tanpa shell juga tidak mencegah argument injection: validasi setiap nilai sesuai program tujuan, gunakan -- jika didukung program tersebut, dan izinkan hanya perintah serta opsi yang diharapkan. Opsi shell: true mengaktifkan shell pada API yang biasanya tidak menggunakannya; jangan berikan input yang belum disanitasi dalam mode ini.

Pertanyaan umum

File batch Windows mengubah batas keamanan

Di Windows, file .bat dan .cmd tidak dapat dijalankan langsung dengan execFile(). Dokumentasi Node menjelaskan bahwa file tersebut dapat dipanggil melalui exec(), cmd.exe, atau spawn() dengan shell aktif; jalur ini mengembalikan parsing oleh command interpreter. Utamakan executable native atau API langsung. Jika pemanggilan file batch tidak dapat dihindari, tetapkan path skrip dan argumennya atau validasi sesuai kontrak skrip yang tepat. Node juga menandai penggunaan array argumen bersama shell: true sebagai deprecated (sejak v22.15.0 dan v23.11.0).

Apakah spawn() sama dengan execFile()?

spawn() juga berjalan tanpa shell secara default dan menerima array argumen. Perbedaan praktis utamanya adalah penanganan output: spawn() mengalirkan output sebagai stream, sedangkan execFile() menyimpannya dalam buffer. Keduanya tidak mencegah program tujuan menafsirkan argumen sebagai opsi; validasi sesuai program tersebut. Menetapkan shell: true mengaktifkan kembali parsing shell.

Referensi

Lihat juga Injeksi perintah OS (CWE-78): cara kerja dan cara mencegahnya di setiap bahasa — flawopen.com Java Runtime.exec() dan Command Injection: apa bedanya? Risiko command injection pada Node.js exec()