← Portal SIPASI R&D
Audit SIPASI (CI4) — 26 Agustus 2026
Dokumen ini merupakan laporan audit teknis dan keamanan independen menyeluruh untuk aplikasi
SIPASI (Sistem Informasi Pengelolaan Air dan Skema Irigasi) berbasis
CodeIgniter 4, dengan struktur aplikasi di `app_sipasi/` dan direktori web root di `public_html/`.
1. Ringkasan Eksekutif
- Skor Kesehatan Aplikasi: 3.5 / 10 (*Kritis - Memerlukan Remediasi Darurat Sebelum Production*)
Aplikasi SIPASI dibangun di atas CodeIgniter 4.4.3, namun secara arsitektur dan pola penulisan kode masih mengadopsi paradigma *legacy* (pola procedural PHP era CodeIgniter 2/3). Terdapat celah keamanan kritikal tingkat tinggi (*Remote Data Wipe*, *Arbitrary SQL Execution*, *Plaintext Credentials*, dan *Unauthenticated Sensitive Endpoints*) yang sangat berisiko terhadap kerahasiaan, integritas, dan ketersediaan data irigasi nasional.
5 Temuan Terpenting
- Unauthenticated Remote Database Wipe via Wizard Instalasi (`P0 - Critical`)
- Lokasi: `app_sipasi/Controllers/Install.php:21-37` dan `app_sipasi/Models/Sipasi/Mdl_installer.php:65-370`
- Dampak: Endpoint `POST /install/auto_generate` dan `GET /install` dapat diakses secara publik tanpa otentikasi/token apa pun. Ketika dipanggil, fungsi ini langsung mengeksekusi `TRUNCATE` dan `DELETE` ke seluruh tabel master dan transaksional (`dts_profil_daerah_irigasi`, `dts_saluran_irigasi`, `dts_bangunan_irigasi`, `dts_petak_tersier`, `dts_skema_jaringan`, `dd_pt_profil`, dll.), menghancurkan seluruh data operasional seketika.
- Celah SQL Injection Masif & Backdoor Query Mentah (`P0 - Critical`)
- Lokasi: Terdeteksi >270 titik query dengan konkatenasi string langsung tanpa *parameter binding*.
- Contoh Terparah: `app_sipasi/Models/Modul/Mdl_db_ajax.php:37-43` menerima parameter `table`, `fl`, `wh`, `opt` via `$_POST` dan mengeksekusi query dinamis mentah (`SELECT $list_fieldname FROM $tabel WHERE $wh $opt`), bertindak sebagai pintu belakang (*backdoor*) eksekusi SQL sembarang.
- Manajemen Kredensial Tidak Aman & Plaintext Password (`P0 - Critical`)
- Lokasi: `db_dump/DB_SIPASI_Oransbari.sql:2748-2772`, `app_sipasi/Models/Cms/CmsLogIn.php:28-40`, `app_sipasi/Controllers/Cmsm.php:21-30`
- Dampak: Password administrator (`user_admin`) dan petugas lapangan (`dts_user_petugas`) disimpan dalam format PLAINTEXT tanpa hashing (`user_pass = 'admin'`). Login menerima kredensial via `GET/POST` (`getGetPost`), berisiko bocor di log web server. Selain itu, modul administrator tabel `Cmsm.php` (`/cmsm`) sama sekali tidak memiliki pengecekan sesi login.
- Eksekusi Kode Berbahaya via `eval()` & Kerentanan SSRF (`P0 - Critical`)
- Lokasi: `app_sipasi/Models/Cms/CmsListing.php:336`, `app_sipasi/Models/Cms/CmsFormatField.php:237,349`, `app_sipasi/Models/Sipasi/Mdl_skema_jaringan.php:1048`, `app_sipasi/Controllers/Iopost.php:1044`
- Dampak: Pemanggilan fungsi `eval()` digunakan di lebih dari 10 lokasi untuk parsing konfigurasi PHP dinamis dan struktur skema. Jika data tabel terkompromi, penyerang dapat menjalankan *Remote Code Execution* (RCE). Controller SCADA `Iopost::command()` juga rentan *Server-Side Request Forgery* (SSRF) karena mem-forward permintaan cURL ke parameter `ip` sembarang dari request pengguna.
- Technical Debt Akut, Duplikasi Ekstrem & Ketiadaan Index Database (`P1 - High`)
- Lokasi: `db_dump/DB_SIPASI_Oransbari.sql`, `app_sipasi/Views/Sipasi/`, `app_sipasi/Helpers/bassic_helper.php`
- Dampak: Skema database memiliki 0 Foreign Key constraints, campuran charset (`latin1` vs `utf8` vs `utf8mb4`), dan 48 dari 55 tabel tidak memiliki secondary index. Pada tabel besar seperti `dd_debit_real_ruas` (205.745 baris), query harian memicu *Full Table Scan* dan N+1 query loop parah. Terdapat duplikasi view raksasa (>3.100 baris per file diduplikasi 5 kali) serta file biner/firmware mikroprosesor yang keliru disimpan di folder view.
2. Profil Teknis
| Parameter | Spesifikasi / Temuan | Keterangan |
| :--- | :--- | :--- |
|
Framework Version | CodeIgniter
v4.4.3 | Dikonfirmasi dari `system/CodeIgniter.php:26` (`CI_VERSION = '4.4.3'`) |
|
PHP Min Requirement |
PHP ^7.4 || ^8.0 | Didefinisikan di `composer.json:11` dan `public_html/index.php:3` |
|
Database Driver | MySQLi (`MySQLiHandler`) | Koneksi MariaDB/MySQL (`Config/Database.php`) |
|
Ekstensi Wajib | `intl`, `json`, `mbstring`, `mysqli`, `curl`, `gd` | Kebutuhan CI4 core, telemetri, manipulasi gambar, dan kalkulasi |
|
Library / Dependency | `laminas/laminas-escaper: ^2.9`
`psr/log: ^1.1`
`kint-php/kint: ^5.0.4` | Dependensi standar framework CodeIgniter 4 |
|
Arsitektur Aplikasi | Hybrid MVC / Procedural Custom Routing | Modifikasi routing dengan helper `urinext()`, model monolitik multi-tujuan |
Analisis Arsitektur & Pola Desain
- Routing & Dispatching:
- Alih-alih memanfaatkan *Named Routes* dan *HTTP Verb Controller Mapping* modern CI4, aplikasi menggunakan *catch-all routes* di `app_sipasi/Config/Routes.php` (misalnya: `$routes->get('/api/(:any)', 'Api::/');`, `$routes->add('/cms/(:any)','Cms::index/');`).
- Controller melakukan dispatching method secara manual dengan membaca segmen URI menggunakan fungsi bantuan custom `urinext($key)` di `app_sipasi/Helpers/bassic_helper.php:3-15`.
- Model Layer:
- Sebagian besar Model (seperti `CmsContent`, `CmsListing`, `CmsUpdate`, `Mdl_skema_jaringan`) tidak menggunakan `CodeIgniter\Model` ActiveRecord/Entity secara murni. Model bertindak ganda sebagai *Data Access Object*, *Business Logic Service*, *HTML Form Generator*, dan *Template Renderer*.
- Controller Layer:
- Controller sangat tipis atau sebaliknya memuat logika I/O hardware, parsing JSON, cURL, dan rendering tampilan dalam satu class tanpa *Dependency Injection* atau *Separation of Concerns*.
3. Audit Keamanan (Prioritas Tinggi)
a) SQL Injection (Kritis)
Ditemukan lebih dari 270 titik eksekusi SQL mentah (`$this->db->query`) yang menggabungkan variabel input langsung tanpa sanitasi atau parameter binding.
#### Bukti Temuan Kode:
- Backdoor Query Arbitrary — `app_sipasi/Models/Modul/Mdl_db_ajax.php:37-43`
php
// Mdl_db_ajax.php: L37-43
$tabel = $_POST['table'];
$list_fieldname = !empty($_POST['fl']) ? $_POST['fl'] : ' * ';
$WH = !empty($_POST['wh']) ? ' WHERE '. $_POST['wh'] : '';
$OPT = !empty($_POST['opt']) ? $_POST['opt'] : '';
$query = $this->db->query("SELECT $list_fieldname FROM $tabel $WH $OPT ");
- Bukti Bahaya:* Penyerang dapat mengirimkan POST request ke `/cms/mdl/db_ajax` dengan payload `table=user_admin&wh=1=1` untuk mengekstrak seluruh isi database tanpa batasan.
- Injeksi Parameter Search via Session — `app_sipasi/Models/Cms/CmsListing.php:306, 318` & `app_sipasi/Models/Cms/CmsContent.php:27-37`
php
// CmsContent.php: L30-33
foreach($arrSearchField AS $fnm){
if(!empty($fnm)){
$search .= $dan. "$fnm LIKE '%".$_POST[$fnm]."%'";
$dan = ' AND ';
}
}
// CmsListing.php: L318
$querytab = $this->db->query("SELECT $idkey AS id, $listSelect FROM $tabel $WHERE ORDER BY $ORDER_BY $ASC LIMIT $LIMIT");
- Injeksi Parameter Perencanaan Irigasi — `app_sipasi/Models/Sipasi/Mdl_perencanaan.php:156, 380`
php
// Mdl_perencanaan.php: L156
$RPT = $this->db->query("SELECT * FROM dd_pt_profil WHERE id = '$idRPT' AND kode_di = '$this->id_di' ORDER BY id DESC LIMIT 1")->getRowArray();
// Mdl_perencanaan.php: L380
$tersierData = $this->db->query("SELECT * FROM dts_petak_tersier WHERE id = '$idPetak'")->getRowArray();
- Injeksi Parameter Sensor SCADA — `app_sipasi/Controllers/Scadapost.php:145, 154`
php
// Scadapost.php: L145
$groupBB = $this->db->query("SELECT * FROM dts_device_node WHERE device_type = 'AWLMS' AND nama_bb = '".$row['id_stasiun']."'")->getResultArray();
// Scadapost.php: L154
$query = "SELECT id_ruas,nama_ruas,last_update,debit_sensor,tma_sensor,bukaan_pintu,id_admin FROM dd_debit_real_ruas WHERE DATE(last_update) = CURRENT_DATE() AND id_ruas = '".$bb['id_ruas']."' ORDER BY last_update DESC LIMIT 1";
- Injeksi Pemeriksaan Tabel — `app_sipasi/Controllers/Io.php:57`
php
// Io.php: L57
$querydata = $this->db->query('SHOW TABLES LIKE "dts_'.$dataPost['data'].'"');
b) Cross-Site Scripting / XSS (Tinggi)
- Dari 173 ekspresi echo/print di dalam direktori `Views`, hanya 65 pemanggilan yang menggunakan fungsi proteksi `esc()`.
- Nilai variabel sistem dan input pengguna di-output langsung tanpa encoding entitas HTML.
#### Bukti Temuan Kode:
- `app_sipasi/Views/Public/Pbl_Mainpage.php:70`:
php
<main class="content"><?= $BODY_CONTENT ?></main>
- `app_sipasi/Views/Public/Pbl_Dss.php:238-244`:
php
<h4 class="mb-0 text-white"><?= $namaDI ?></h4>
<p class="mb-0 text-muted">Luas: <?= $luas_layanan ?> Ha | Wilayah: <?= $kabupaten ?></p>
- `app_sipasi/Models/Cms/CmsUpdate.php:345`:
php
$data = $parser->setData($arrParser)->renderString($template);
Template form dibangun dengan merangkai HTML mentah langsung dari field database (`cms_listing_field`) dan di-render menggunakan parser tanpa escaping otomatis.
c) CSRF (Cross-Site Request Forgery) (Tinggi)
- Status Filter CSRF: DINONAKTIFKAN (OFF)
- Bukti Konfigurasi: `app_sipasi/Config/Filters.php:34-38`
php
public array $globals = [
'before' => [
// 'honeypot',
// 'csrf',
// 'invalidchars',
],
'after' => [
'toolbar',
// 'honeypot',
// 'secureheaders',
],
];
- Dampak: Tidak ada satu pun request `POST` (seperti update profil irigasi, hapus petak tersier, perintah buka/tutup pintu SCADA, atau upload file) yang memverifikasi token CSRF. Penyerang dapat memicu aksi berbahaya melalui *phishing* atau situs pihak ketiga saat korban memiliki sesi aktif.
d) Autentikasi & Otorisasi (Kritis)
- Penyimpanan Password Plaintext:
- Tabel `user_admin` (`db_dump/DB_SIPASI_Oransbari.sql:2748, 2771`) menyimpan password administrator langsung tanpa hashing (`user_pass = 'admin'`).
- Tabel `dts_user_petugas` (`db_dump/DB_SIPASI_Oransbari.sql:2689`) membatasi panjang kolom password hanya `varchar(16)`, yang tidak mencukupi untuk algoritma modern (bcrypt membutuhkan 60 karakter, Argon2id 96+ karakter).
- Ketiadaan Filter Otentikasi Terpusat:
- Tidak ada filter otentikasi yang terdaftar di `Config/Filters.php`. Otentikasi dilakukan secara ad-hoc per controller.
- Endpoint Sensitif Tanpa Otentikasi:
- `app_sipasi/Controllers/Cmsm.php:21-30`: Controller pengelola tabel dan metadata CMS dapat diakses langsung oleh publik tanpa pengecekan sesi.
- `app_sipasi/Controllers/Install.php:10-38`: Wizard instalasi dan inisialisasi database terbuka penuh.
- `app_sipasi/Controllers/Dev.php:12-370`: Script agregasi data dan perhitungan ETo dapat dijalankan publik.
- Pengiriman Kredensial via HTTP GET:
- `app_sipasi/Models/Cms/CmsLogIn.php:23`: Menggunakan `$this->request->getGetPost('uid')` dan `$this->request->getGetPost('ulock')`. Penyerang atau proxy dapat melihat username/password yang dikirimkan via query string URL.
e) Penanganan File Upload & Path Traversal (Kritis)
#### Bukti Temuan Kode:
- Upload Telemetri Tanpa Validasi MIME & Ekstensi — `app_sipasi/Controllers/Apk.php:500-530`
php
// Apk.php: L505-520
$folder_name = 'upload/'.$ruas_id.'/';
if (!is_dir($folder_name)) {
mkdir($folder_name, 0777, true);
}
$img_name = $img_id.'.jpg';
$image_parts = explode(";base64,", $image);
$image_base64 = base64_decode($image_parts[1]);
$file_path = $folder_name . $img_name;
file_put_contents($file_path, $image_base64);
- *Risiko 1:* Permission folder `0777` (Full Read/Write/Execute untuk semua pengguna OS).
- *Risiko 2:* Parameter `$ruas_id` dan `$user_id` tidak disanitasi dari karakter `../` (*Directory/Path Traversal*).
- *Risiko 3:* Tidak ada validasi magic bytes atau verifikasi tipe data gambar.
- Upload Kamera CCTV — `app_sipasi/Controllers/Iopost.php:285-295`
php
// Iopost.php: L285-292
$uploadDir = 'device/'.$idKey.'/';
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$uploadFile = $uploadDir. $file_name;
move_uploaded_file($_FILES['file_contents']['tmp_name'], $uploadFile);
- Direktori upload (`public_html/upload/`, `public_html/device/`) berada langsung di dalam *docroot* publik tanpa konfigurasi pencegahan eksekusi script PHP di level web server.
f) Konfigurasi Berisiko & Kebocoran Informasi (Tinggi)
| File & Baris | Konfigurasi Aktif | Risiko / Dampak |
| :--- | :--- | :--- |
| `sipasi_oransbari/.env:19-21` | `CI_ENVIRONMENT = production`
`error_reporting = E_ALL`
`display_errors = 1` | Menampilkan pesan error PHP lengkap, file path absolut, dan query SQL langsung ke browser pengguna saat runtime exception terjadi. |
| `sipasi_oransbari/.env:27-29` | `database.default.username = sipasi`
`database.default.password = SipasiRiset2026!` | Kredensial database tersimpan di environment file dengan permission standar (`644`). |
| `app_sipasi/Config/Encryption.php:22` | `public string $key = '';` | Kunci enkripsi default kosong, menyebabkan kegagalan keamanan pada enkripsi cookie/session atau token. |
| `app_sipasi/Config/App.php:178` | `public bool $CSPEnabled = false;` | Content Security Policy nonaktif, memudahkan serangan XSS dan inject script eksternal. |
| `app_sipasi/Controllers/Scadapost.php:218-230` | `readfile/file_get_contents(WRITEPATH . 'logs/log-...')` | Method `Scadapost::debug()` mem-print 10 baris terakhir log aplikasi langsung ke browser tanpa otentikasi. |
| `app_sipasi/Controllers/Iopost.php:1044-1065` | `curl_init("http://{$ipAddress}/api/command")` | Method `command()` menerima parameter `ip` dari JSON request tanpa validasi whitelist, membuka celah SSRF (*Server-Side Request Forgery*) ke internal server / port localhost (e.g. 127.0.0.1, AWS metadata 169.254.169.254). |
4. Analisis Teknik Lama & Technical Debt
a) MyISAM vs InnoDB & Kekacauan Charset
- Engine MyISAM: Tabel `cms_level_admin` masih menggunakan `ENGINE=MyISAM` (`db_dump/DB_SIPASI_Oransbari.sql:28`). MyISAM tidak mendukung transaksi ACID, *row-level locking*, maupun *foreign key constraints*.
- Fragmentasi Charset & Collation:
- 23 Tabel menggunakan `latin1` (`latin1_swedish_ci`).
- 27 Tabel menggunakan `utf8` (`utf8_general_ci` / `utf8_unicode_ci`).
- 4 Tabel menggunakan `utf8mb4` (`utf8mb4_general_ci`).
- *Dampak:* Ketidakkonsistenan charset mengakibatkan konversi implisit (*implicit collation casting*) yang merusak performa JOIN query dan memicu kegagalan penyimpanan karakter non-ASCII (seperti simbol derajat hidrologi °C, m³, atau teks khusus).
b) Mindset PHP Legacy & Anti-Patterns
- Eksekusi String PHP Dinamis (`eval`):
- `app_sipasi/Models/Sipasi/Mdl_skema_jaringan.php:1048`:
php
$data_argbn = str_replace(':','=>',$argbn[1]);
eval('$'.trim($argbn[0]).'= array'.$data_argbn.';');
Konstruksi array PHP dijalankan menggunakan `eval()` dari string kustom alih-alih menggunakan serialisasi standar `json_decode()` / `json_encode()`.
- Variable Variables & Dynamic Variables:
- `app_sipasi/Models/Sipasi/Mdl_blangko_o.php:447`:
php
${'debitHarian'.$vTgl} = $this->db->query("SELECT * FROM dd_debit_ruas_harian WHERE DATE(last_update) = '$tahun-$bulan-$vTgl' ...")->getResultArray();
- Konvensi Penamaan Legacy:
- Penggunaan prefix dan istilah lawas: `ko_tabel`, `id_protab`, `protab`, `proNav`, `dts_` vs `dd_` vs `cms_`.
- Helper Raksasa & Monolitik:
- `app_sipasi/Helpers/bassic_helper.php` (373 baris, dengan *typo* pada nama file "bassic"): Berisi 17 fungsi prosedural global yang mencampuradukkan koneksi DB langsung (`outRow`, `ifData`, `getID`), pemrosesan gambar GD (`resize_image`), perayapan URI (`urinext`, `uriafter`), dan HTML pagination generator (`paging`).
- `app_sipasi/Helpers/kat_helper.php` (263 baris): Berisi kalkulasi matematis/hidrologi rumit (KAT padi, palawija, tebu, ET0) tanpa enkapsulasi class atau automated unit test.
c) Duplikasi Kode Masif & Artefak Sampah
Daftar File Duplikat Ekstrem (Kloning View Rencana PT):
├── app_sipasi/Views/Sipasi/xxx_RencanaPT_admin.php (3.237 baris)
├── app_sipasi/Views/Sipasi/RencanaPT_admin.php (3.165 baris)
├── app_sipasi/Views/Sipasi/RencanaPT_admin_copy.php (3.126 baris)
├── app_sipasi/Views/Sipasi/Rencana_PT.php (3.122 baris)
└── app_sipasi/Views/Sipasi/Rencana_PTX.php (3.104 baris)
Total: >15.750 baris kode hasil copy-paste manual
#### Artefak & File yang Berada di Tempat yang Salah:
- `app_sipasi/Views/Scada/main.cpp` (656 baris): Merupakan source code C++ firmware Arduino/ESP32 mikroprosesor yang diletakkan di direktori Views framework web.
- `app_sipasi/Views/samples/blangko_4o.pdf`: File dokumen binary PDF diletakkan di folder Views.
- `app_sipasi/Controllers/sapon.sipasi.net.code-workspace` & `app_sipasi/Views/Public/sapon.sipasi.net.code-workspace`: File konfigurasi VS Code internal developer tertinggal di folder Controller dan View.
- File backup/eksperimental aktif: `xxxxxxxxCms_Listing.php`, `Main_cmsm_x.php`, `image_crop_xxx.php`, `XXXXPbl_Dashboard.php`, `xxxPbl_Dashboad.php`, `xxx_Dss.php`, `yes.txt`, `yesnote.md`.
5. Kualitas Data & Analisis Database
a) Statistik Tabel Terbesar
Berdasarkan dump database operasional (`DB_SIPASI_Sapon.sql` & `DB_SIPASI_Oransbari.sql`):
| Nama Tabel | Engine | Charset | Estimasi Baris Data | Primary Key | Secondary Index |
| :--- | :--- | :--- | :--- | :--- | :--- |
|
`dd_debit_real_ruas` | InnoDB | `utf8` |
205.745 | `id` |
TIDAK ADA |
|
`dd_petak_tersier_harian`| InnoDB | `latin1` |
32.030 | `id` |
TIDAK ADA |
|
`dd_debit_ruas_panca` | InnoDB | `latin1` |
5.695 | `id` |
TIDAK ADA |
|
`dd_debit_sumber_harian`| InnoDB | `latin1` |
5.655 | `id_debit` |
TIDAK ADA |
|
`debit_intake_sapon` | InnoDB | `latin1` |
5.529 | `id` | Ada (1 index) |
|
`iklim` | InnoDB | `utf8mb4`|
5.449 | `id` | Ada (1 index) |
|
`dd_awlr_log` | InnoDB | `utf8` |
3.926 | `id` |
TIDAK ADA |
|
`dd_debit_ruas_harian` | InnoDB | `latin1` |
1.534 | `id` |
TIDAK ADA |
|
`dd_debit_sumber_panca` | InnoDB | `latin1` |
1.125 | `id_debit` |
TIDAK ADA |
b) Masalah Index & Pola N+1 Query
- Ketiadaan Secondary Index (Missing Indexes):
- 48 dari 55 tabel hanya memiliki `PRIMARY KEY` tanpa index sekunder pada kolom pencarian dan filtering.
- Tabel `dd_debit_real_ruas` (205.745 baris) sering di-query dengan pola:
sql
WHERE DATE(last_update) = CURRENT_DATE() AND id_ruas = 'b1xb2' ORDER BY last_update DESC
Karena tidak ada index pada `(id_ruas, last_update)`, database melakukan
Full Table Scan (205k baris) pada setiap request SCADA dan halaman publik.
- Pola Loop N+1 Query yang Merusak Latensi Server:
- `app_sipasi/Controllers/Scadapost.php:144-170`: Looping pada stasiun -> loop perangkat AWLMS -> query `dd_debit_real_ruas` per perangkat -> query `dd_device_image` per perangkat.
- `app_sipasi/Models/Sipasi/Mdl_blangko_o.php:445-455`: Melakukan 31 kali query terpisah ke `dd_debit_ruas_harian` di dalam perulangan hari kalender (1 s.d. 31).
- `app_sipasi/Controllers/Iopost.php:578-615` & `Scada.php:62-95`: Query individu di dalam perulangan `foreach` untuk setiap baris saluran.
- Index Suppression oleh Pemanggilan Fungsi SQL:
- Penggunaan klausa `WHERE DATE(last_update) = CURDATE()` atau `WHERE MONTH(tanggal) = ...` membatalkan penggunaan index B-Tree (bahkan jika index ditambahkan nantinya). Harus diganti menjadi range query: `WHERE last_update >= ? AND last_update < ?`.
c) Foreign Key & Integritas Relasional
- Jumlah Foreign Key di Seluruh Database: 0 (NOL)
- Tidak ada relasi formal antar tabel (seperti `dts_ruas_saluran` ke `dts_bangunan_irigasi`, atau `dd_debit_real_ruas` ke `dts_ruas_saluran`). Integritas data sepenuhnya bergantung pada logika kode aplikasi yang rentan bug, menyebabkan tingginya potensi data yatim (*orphaned records*).
6. Roadmap Modernisasi & Rencana Tindak Lanjut
Matriks Prioritas & Estimasi Effort
┌────────────────────────────────────────────────────────────────────────┐
│ P0: Darurat Keamanan (Wajib segera sebelum deployment publik) │
│ P1: Penting & Struktural (Stabilitas, Integritas Data & Performa) │
│ P2: Nice-to-Have / Polish (Kualitas Kode Jangka Panjang & Arsitektur) │
└────────────────────────────────────────────────────────────────────────┘
| Kode | Kategori | Item Pekerjaan / Remediasi | Estimasi Effort | Bukti / Lokasi Target |
| :---: | :---: | :--- | :---: | :--- |
|
P0-1 | Keamanan |
Amankan / Hapus Wizard Instalasi Tanpa AuthBeri proteksi filter autentikasi admin atau hapus endpoint `Install::auto_generate` agar database tidak dapat di-truncate publik. |
Kecil *(1-2 jam)* | `Controllers/Install.php:21`
`Config/Routes.php:57-59` |
|
P0-2 | Keamanan |
Tutup Backdoor Arbitrary Query di `Mdl_db_ajax`Hapus method eksekusi query dinamis mentah atau gantikan dengan whitelist handler spesifik. |
Kecil *(1-2 jam)* | `Models/Modul/Mdl_db_ajax.php:37` |
|
P0-3 | Keamanan |
Terapkan Otentikasi Terpusat via CI4 FilterBuat filter auth (`AuthFilter`) dan daftarkan di `Config/Filters.php` untuk memproteksi `/cms`, `/cmsm`, `/dev`, dan endpoint administratif. |
Sedang *(1-2 hari)* | `Config/Filters.php`
`Controllers/Cmsm.php`
`Controllers/Dev.php` |
|
P0-4 | Keamanan |
Migrasi Password ke `password_hash()` (Bcrypt / Argon2id)Ubah tipe kolom password database (`varchar(255)`), terapkan `password_hash` dan `password_verify` pada proses login. |
Sedang *(1-2 hari)* | `Models/Cms/CmsLogIn.php:28`
`db_dump/DB_SIPASI_Oransbari.sql:2689` |
|
P0-5 | Keamanan |
Validasi Ketat Upload File & Pindahkan dari DocrootGunakan validasi CI4 File Validation (MIME type, ekstensi whitelist), cegah path traversal pada `ruas_id`, simpan di direktori non-executable. |
Sedang *(1-2 hari)* | `Controllers/Apk.php:500`
`Controllers/Iopost.php:280` |
|
P0-6 | Keamanan |
Perbaiki Konfigurasi Environment & Nonaktifkan Display ErrorsSet `display_errors = 0` di production, generate `app.encryptionKey`, dan hapus endpoint `Scadapost::debug()` yang membocorkan log. |
Kecil *(1-2 jam)* | `.env:21`
`Config/Encryption.php:22`
`Controllers/Scadapost.php:218` |
|
P0-7 | Keamanan |
Eliminasi Penggunaan `eval()`Gantikan parsing skema dan template berbasis `eval()` dengan `json_decode()` dan template builder aman. |
Sedang *(2-3 hari)* | `Models/Cms/CmsListing.php:336`
`Models/Sipasi/Mdl_skema_jaringan.php:1048` |
|
P1-1 | Stabilitas |
Parameterisasi Seluruh Query SQL (Query Binding)Ganti seluruh konkatenasi string SQL mentah (>270 titik) dengan Query Binding CI4 (`$db->query($sql, [$param])`) atau Query Builder. |
Besar *(1-2 minggu)* | Seluruh Model di `Models/Sipasi/`, `Models/Cms/` |
|
P1-2 | Database |
Penambahan Composite Index pada Tabel KritisTambahkan index pada `dd_debit_real_ruas (id_ruas, last_update)`, `dd_petak_tersier_harian (petak_id, tanggal)`, `dts_device_node (device_type, nama_bb)`. |
Sedang *(1 hari)* | `db_dump/DB_SIPASI_Oransbari.sql` |
|
P1-3 | Database |
Standarisasi Database Engine ke InnoDB & Charset UTF-8Konversi tabel `cms_level_admin` ke InnoDB dan migrasikan seluruh tabel `latin1` ke `utf8mb4_unicode_ci`. |
Sedang *(1-2 hari)* | Skema Database MariaDB |
|
P1-4 | Performa |
Refactoring N+1 Query Loop Menjadi Batch QueriesOptimalkan controller `Scadapost`, `Scada`, dan `Mdl_blangko_o` agar mengambil data menggunakan single `IN (...)` atau `JOIN` query. |
Besar *(3-5 hari)* | `Controllers/Scadapost.php:144`
`Models/Sipasi/Mdl_blangko_o.php:447` |
|
P1-5 | Keamanan |
Aktifkan Proteksi CSRF GlobalAktifkan filter `'csrf'` di `Config/Filters.php` dan tambahkan CSRF token di AJAX headers / form input. |
Sedang *(2-3 hari)* | `Config/Filters.php:36`
`public_html/assets/js/` |
|
P1-6 | Kebersihan |
Pembersihan Kode Mati & File ArtefakHapus duplikat view `xxx_RencanaPT`, file firmware `.cpp`, file `.pdf`, dan file `.code-workspace` dari direktori web. |
Kecil *(2-4 jam)* | `Views/Sipasi/`, `Views/Scada/`, `Controllers/` |
|
P2-1 | Arsitektur |
Restrukturisasi View Monolitik Menjadi Modular ComponentsPecah view 3.000+ baris `RencanaPT` menjadi partial view terpisah (UI components, SVG canvas, data tables). |
Besar *(1-2 minggu)* | `Views/Sipasi/Rencana_PT.php` |
|
P2-2 | Arsitektur |
Refactoring `bassic_helper` Menjadi Service ClassesBongkar fungsi procedural `bassic_helper.php` dan `kat_helper.php` menjadi *HydrologyCalculationService*, *DateHelper*, dan *ImageService* berstandar OOP PSR-4. |
Sedang *(3-5 hari)* | `Helpers/bassic_helper.php`
`Helpers/kat_helper.php` |
|
P2-3 | Arsitektur |
Penerapan CI4 Entities & Form Request ValidationGunakan validasi CI4 otomatis (`$validation->setRules()`) dan Entity mapping pada model transaksi. |
Besar *(1-2 minggu)* | `Models/`, `Controllers/` |
|
P2-4 | Kualitas |
Implementasi Automated Unit Testing (PHPUnit)Buat automated test suite untuk memvalidasi akurasi perhitungan rumus hidrologi (KAT, ETo, Alokasi Debit Irigasi). |
Sedang *(3-5 hari)* | `tests/` |
Kesimpulan Auditor
Aplikasi
SIPASI memiliki fungsionalitas inti yang sangat kaya dan spesifik untuk manajemen hidrologi dan otomasi irigasi (SCADA/IoT). Namun, kode saat ini berada dalam kondisi
resiko keamanan dan performa yang sangat tinggi.
Implementasi perbaikan pada kategori
P0 (Darurat Keamanan) mutlak harus diselesaikan sebelum sistem diakses oleh publik atau dihubungkan dengan perangkat telemetri jaringan luas, disusul dengan perbaikan indeks database dan eliminasi duplikasi kode pada kategori
P1.