Kembali ke blog
27 Oktober 2025Sergei Solod5 mnt baca

Situs Next.js statis saya menerima ribuan vulnerability scan per hari. Nginx nyaris tidak terpengaruh

Log saya penuh probe yang mencari WordPress, backdoor PHP, .env, dan .git/config. Pada setup Next.js statis + Nginx saya, sebagian besar berakhir sebagai miss murah dan 404, sementara beban CPU tetap sama selama pengamatan. Inilah arti sebenarnya bagi keamanan situs statis—beserta batas kesimpulannya.

KeamananNext.jsNginxDevOpsHosting statisAttack Surface

Setiap hari, log server saya mencatat ribuan vulnerability scan otomatis. Request-nya terlihat cukup mengkhawatirkan:

  • /wp-admin/wp.php
  • /111.php
  • /code.php
  • /.git/config
  • /i.php
  • /admin
  • /api/.env
  • /kal.php

Yang mengejutkan saya bukan jumlahnya, melainkan betapa sedikit server bereaksi. Selama saya mengamati traffic ini, beban CPU tidak menunjukkan perubahan yang terlihat.

Observasi itu nyata, tetapi penjelasan awal saya terlalu mutlak. Static delivery bukan perisai ajaib dan 404 tidak gratis. Keuntungan nyata arsitektur saya lebih spesifik: banyak probe oportunistik sangat murah karena hampir tidak ada logika aplikasi server-side di public request path yang bisa mereka capai.

Ini probe, bukan bukti kompromi

Melihat /wp-admin/wp.php atau /111.php membuat kita mudah menyebut setiap request sebagai “exploit”. Secara teknis itu kurang tepat. Yang terutama saya lihat adalah automated probing: bot mencoba filename dan endpoint umum lalu melihat apa yang merespons.

Beberapa path jelas menargetkan WordPress atau PHP. Yang lain, seperti /.git/config dan /api/.env, mencari konfigurasi atau secret yang tidak sengaja terekspos. /admin bahkan lebih umum dan bisa saja merupakan route sah. Request yang mencurigakan memberi tahu saya apa yang dicari scanner, bukan membuktikan vulnerability itu ada.

Dalam kasus saya, arsitekturnya yang menentukan: situs publik berupa HTML statis yang diprerender oleh Next.js dan disajikan langsung oleh Nginx.

Mengapa traffic ini murah di stack saya

Untuk halaman yang saya bahas, tidak ada PHP runtime atau database di belakang setiap request. Nginx menyajikan file yang sudah ada. Jika scanner meminta /111.php dan file itu tidak ada, tidak ada aplikasi PHP yang boot, tidak ada kode WordPress yang berjalan, dan tidak ada query database. Request hanya miss dan berakhir dengan 404.

Itu mengubah cost model. Dalam aplikasi dinamis, satu request bisa melewati routing, framework, authentication, rendering, database, atau service lain. Jalur statis saya punya jauh lebih sedikit moving parts. Nginx tetap harus menerima koneksi, memproses HTTP, mencari resource, menulis log, dan mengirim response, tetapi kerja aplikasinya kecil.

Saya juga memakai caching agresif untuk situs, yang membantu static delivery normal. Namun saya tidak akan menganggap setiap 404 acak murah karena cache. URI palsu yang baru bisa tetap melewati processing Nginx biasa dan filesystem lookup sebelum 404 dikirim.

Koreksi penting: statis bukan berarti “aman secara otomatis”

Bagian inilah yang sekarang akan saya tulis lebih hati-hati. Arsitektur statis menghapus banyak komponen server-side dari public request path, tetapi tidak menghapus pekerjaan keamanan.

  • File yang terekspos tetap terekspos. Jika .git, .env, backup, atau secret masuk ke direktori publik, Nginx dapat menyajikannya seefisien HTML jika konfigurasi tidak memblokirnya.
  • Nginx, TLS, sistem operasi, dan jaringan tetap merupakan attack surface. Semuanya tetap perlu dipatch dan dikonfigurasi dengan baik.
  • Kode client-side masih bisa memiliki vulnerability. HTML statis tidak otomatis membuat JavaScript, logika auth di browser, atau third-party script aman.
  • Resource exhaustion tetap mungkin. Koneksi, bandwidth, TLS handshake, worker capacity, log I/O, dan ruang disk terbatas. Traffic yang cukup besar tetap bisa mengganggu situs statis.

Jadi kesimpulan yang benar bukan “request ini tidak penting”, melainkan: banyak probe yang spesifik untuk suatu aplikasi tidak menemukan apa pun untuk dieksekusi pada arsitektur ini.

“Ribuan scan per hari” bisa terdengar lebih buruk daripada beban sebenarnya

Log membuat background noise Internet terlihat sangat intens karena setiap probe gagal muncul sebagai satu baris. Namun total harian saja tidak menjelaskan dampak operasional. Beberapa ribu request yang tersebar selama 24 jam sangat berbeda dari jumlah yang sama dalam burst singkat.

CPU juga hanya satu sinyal. Dalam kasus saya, CPU tetap stabil, yang merupakan bukti berguna bahwa saat itu traffic tersebut tidak menciptakan compute pressure yang terlihat. Itu tidak membuktikan biaya di resource lain nol. Untuk evaluasi yang lebih benar saya juga akan melihat request rate, bandwidth, koneksi aktif, utilisasi worker Nginx, response latency, volume log, dan penggunaan disk.

Apa yang saya pelajari dari noise ini

Pelajaran terbesar bagi saya adalah arsitektur dapat membuat seluruh kategori serangan otomatis menjadi tidak relevan tanpa perlu rule untuk setiap scanner signature. Bot boleh mencari backdoor WordPress dan PHP sepanjang hari; jika public request path tidak memiliki WordPress atau PHP, probe itu hampir tidak punya apa pun untuk dimanfaatkan.

Tetapi sekarang saya tidak menyamakan “tidak relevan untuk stack saya” dengan “traffic yang tidak berbahaya”. Checklist saya saat ini sederhana:

  • Ketahui runtime dan service apa yang benar-benar reachable dari jalur publik.
  • Simpan secret, repository metadata, backup, dan build artifact di luar web root atau blokir secara eksplisit.
  • Anggap probe 404 berulang sebagai background noise Internet normal selama tidak ada bukti lain tentang targeting atau impact.
  • Jangan menyimpulkan abusive traffic gratis hanya dari CPU.
  • Tetap patch Nginx, OS, library TLS, dan dependencies walaupun aplikasinya statis.

Apa yang tidak dibuktikan pengalaman ini

Saya tidak menjalankan controlled benchmark dan tidak mensimulasikan DDoS. Saya hanya mengamati production log dan beban server ketika ribuan scanner request masuk setiap hari. Itu cukup untuk kesimpulan praktis tentang setup saya, tetapi tidak membuktikan aturan universal bahwa “statis selalu menang”.

Yang bisa saya pastikan lebih spesifik: pada Next.js static export saya yang disajikan Nginx, traffic scanner yang saya lihat sebagian besar berubah menjadi file miss murah dan 404, bukan mencapai PHP runtime atau aplikasi berbasis database. Beban CPU tidak berubah selama saya mengamatinya.

Itulah keuntungan resilience yang saya pedulikan. Lebih sedikit moving parts tidak membuat sistem kebal. Itu hanya memberi random Internet noise lebih sedikit tempat untuk berubah menjadi kerja aplikasi yang nyata.