Skip to content

Fix: Guard installer POST routes agar tidak bisa dijalankan saat aplikasi sudah terinstal - #1697

Merged
analisopendesa merged 4 commits into
rilis-devfrom
fix/environment
Aug 12, 2026
Merged

Fix: Guard installer POST routes agar tidak bisa dijalankan saat aplikasi sudah terinstal#1697
analisopendesa merged 4 commits into
rilis-devfrom
fix/environment

Conversation

@pandigresik

Copy link
Copy Markdown
Contributor

Pull Request: Fix: Guard installer POST routes agar tidak bisa dijalankan saat aplikasi sudah terinstal

Description

Pada installer OpenDK, route POST /install/environment/saveWizard, /install/environment/saveClassic, dan /install/final masih bisa dijalankan meskipun aplikasi sudah terinstal, karena pengecekan sudahInstal() tidak diterapkan secara konsisten. PR ini memindahkan guard installer ke middleware terpusat dan menambahkan FormRequest untuk validasi input.

Changes

  1. [security] Tambah middleware InstallerCheck untuk memblokir seluruh installer route ketika sudahInstal() bernilai true.
  2. [refactor] Tambah route middleware installer.check pada grup route installer di routes/web.php.
  3. [refactor] Hapus pengecekan sudahInstal() yang berulang di setiap method InstallerController.
  4. [feature] Tambah FormRequest: EnvironmentWizardSaveRequest, EnvironmentClassicSaveRequest, dan PerformInstallationRequest.
  5. [test] Tambah test Pest untuk middleware dan FormRequest installer.
  6. [fix] Migrasi: ganti Schema::drop() menjadi Schema::dropIfExists().
  7. [fix] Seeder: hindari duplikasi insert dengan pengecekan exists sebelum insert.

Reason for change

  • Keamanan: Sebelumnya, route GET installer sudah dilindungi, tapi route POST tetap bisa menimpa .env dan menjalankan migrasi setelah aplikasi terinstal.
  • DRY: Pengecekan sudahInstal() yang duplikat di 9 method controller dipindah ke satu middleware.
  • Maintainability: Validasi input dipindah dari controller ke FormRequest agar lebih rapi dan reusable.

Impact of change

Keamanan: Installer POST route diblokir otomatis setelah instalasi selesai.
Konsistensi: Semua route installer menggunakan guard yang sama.
Kode lebih bersih: Controller fokus ke logic bisnis, bukan validasi dan guard berulang.
Testability: Perilaku installer bisa diuji secara terpisah lewat middleware dan FormRequest.

Related Issue

Steps to Reproduce

Before fix (problem):

  1. Install OpenDK sampai file storage/installed terbuat.
  2. Kirim POST ke /install/environment/saveClassic dengan payload .env baru.
  3. File .env bisa ditimpa meskipun aplikasi sudah terinstal.
  4. ❌ Konfigurasi aplikasi bisa diubah tanpa autentikasi.

After fix (solution):

  1. Install OpenDK sampai file storage/installed terbuat.
  2. Kirim POST ke /install/environment/saveClassic dengan payload .env baru.
  3. ✅ Redirect ke / karena middleware installer.check memblokir request.

Testing on related features:

  • Installer GET route ✅ Tidak berubah
  • Installer POST route ✅ Sekali dilindungi oleh middleware
  • FormRequest validation ✅ Berjalan otomatis sebelum controller

Checklist

  • I have complied with script writing rules
  • I have followed pull request review process
  • I have created [unit test/integration test] to verify the fix
  • Manual testing has been done in development environment
  • No console errors or warnings
  • Code has been reviewed by [at least 1 person]

Technical Details

Technical Explanation

Route installer sekarang diamankan oleh middleware InstallerCheck yang dijalankan di grup route dan constructor controller. FormRequest mengambil alih validasi dari $request->validate() agar otomatis dijalankan sebelum method controller dieksekusi.

Configuration changes

bootstrap/app.php — ditambahkan alias middleware:

'installer.check' => \App\Http\Middleware\InstallerCheck::class,

routes/web.php — route installer sekarang menggunakan middleware:

Route::prefix('install')->middleware(['installer.check'])->group(function () {
    // ...
});

Dependencies added

No new dependencies.

Testing

Manual Testing

  • Akses /install setelah instalasi selesai, harus redirect ke /
  • Akses /install/environment/saveClassic setelah instalasi selesai, harus redirect ke /
  • Akses /install/environment/saveWizard setelah instalasi selesai, harus redirect ke /
  • Akses /install/final setelah instalasi selesai, harus redirect ke /

Automated Testing

  • Pest: InstallerControllerTest — middleware + FormRequest coverage

Screenshot / Video

simplescreenrecorder-2026-08-06_06.13.21.mp4

Breaking Changes

None

Migration Guide

Not required

References


Additional notes: Perubahan ini mencegah overwrite .env dan migrasi ulang setelah aplikasi sudah terinstal. Route installer tetap bisa diakses selama storage/installed belum ada.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🔄 AI PR Review sedang antri di server...

Proses review akan segera dimulai di background — hasil akan muncul sebagai komentar setelah selesai.
Powered by CrewAI · PR #1697

@apidong apidong left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Keamanan — Guard Installer POST Routes

Terima kasih atas PR ini. Solusi middleware InstallerCheck yang diterapkan ke seluruh group route install sudah benar dan menyelesaikan akar masalah pada issue wiki-keamanan#50: route POST /install/environment/saveClassic dan /environment/saveWizard yang sebelumnya tanpa guard sudahInstal() kini diblokir setelah aplikasi terinstal.

✅ Yang sudah baik

  • Guard dipindah dari 9 method controller ke satu middleware terpusat (DRY & konsisten untuk GET + POST).
  • Bonus: GET /install/environment/classic yang sebelumnya membocorkan isi .env (berisi secret) ikut tertutup.
  • Tidak ada konflik dengan middleware installed (KDInstalled) — keduanya komplementer.
  • Package rachidlaasri/laravel-installer sudah tidak aktif, tidak ada rute installer lama yang lolos dari middleware.

🔴 Temuan HIGH — Test middleware flaky & bergantung environment

tests/Feature/Controllers/Installer/InstallerControllerTest.php:13-23 hanya benar jika file storage/installed ada di environment jalan test. Tidak ada beforeEach yang mengatur file tersebut:

  • Pada fresh checkout tanpa storage/installed, sudahInstal() = false, middleware memanggil $next($request) dan test gagal (mengharapkan 302).
  • Di CI test baru lolos karena workflow test.yml menjalankan touch storage/installed.

Rekomendasi: buat/hapus file storage/installed di beforeEach, atau mock sudahInstal(), agar test deterministik di semua environment.

🟠 Temuan HIGH — Belum ada test integrasi untuk skenario exploit asli

Tidak ada test yang mensimulasikan eksploitasi sebenarnya: POST /install/environment/saveClassic saat aplikasi sudah terinstal harus menghasilkan redirect dan .env tidak berubah. Test saat ini hanya menguji middleware secara isolasi sehingga regresi di routes/web.php (mis. middleware terlepas dari group) tidak akan tertangkap.

Rekomendasi: tambahkan test seperti:

$this->post(route('installer.environmentSaveClassic'), ['envConfig' => '...'])
    ->assertRedirect('/');
// lalu pastikan isi .env tidak berubah

🟡 Temuan MEDIUM — Scope creep pada migrasi & seeder

Perubahan Schema::drop()dropIfExists() dan penghapusan kolom id eksplisit pada seeder tidak terkait langsung dengan fix keamanan ini. Perlu dipertimbangkan untuk dipisah ke PR terpisah agar review lebih fokus dan risiko konflik dengan instalasi existing lebih kecil.


Kesimpulan: Implementasi inti layak untuk merge, namun disarankan test diperbaiki/dilengkapi lebih dulu (2 temuan HIGH di atas). Terima kasih!

@pandigresik

Copy link
Copy Markdown
Contributor Author

Temuan MEDIUM — Scope creep pada migrasi & seeder Perubahan Schema::drop() → dropIfExists() dan penghapusan kolom id eksplisit pada seeder tidak terkait langsung dengan fix keamanan ini. Perlu dipertimbangkan untuk dipisah ke PR terpisah agar review lebih fokus dan risiko konflik dengan instalasi existing lebih kecil.

Sengaja dilakukan karena ketika testing gagal proses instalasi awal, jadi sekalian dilakukan perbaikan

@analisopendesa
analisopendesa merged commit 0b21803 into rilis-dev Aug 12, 2026
@analisopendesa
analisopendesa deleted the fix/environment branch August 12, 2026 09:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants