Perisai Framework

Perisai framework: default aman Django, Rails, FastAPI, dan Laravel untuk production.

Daftar isi

Framework menyediakan sebagian besar pertahanan aplikasi web dalam bentuk siap pakai, mulai dari query berparameter, perlindungan CSRF, hingga pengodean keluaran secara otomatis. Kata perisai pada topik ini menunjuk peran tersebut, yaitu lapisan yang menahan satu kelas kerentanan tanpa perlu ditulis ulang oleh setiap pengembang. Pertahanan bawaan hanya bekerja bila konfigurasinya benar, sedangkan nilai bawaan framework ditujukan untuk kenyamanan pengembangan dan sering tidak aman untuk production. Topik ini meninjau default yang wajib diganti, memeriksanya dengan skrip ala linter, memperdalam contoh Django, lalu menutupnya dengan pembanding singkat Rails, FastAPI, dan Laravel.

Pertahanan bawaan yang perlu dinyalakan#

Kerentanan yang dibahas pada modul-modul sebelumnya memiliki penawarnya di dalam framework. SQL injection ditahan ORM yang menulis query berparameter, XSS ditahan template engine yang mengodekan keluaran secara otomatis, dan CSRF ditahan middleware yang memeriksa token pada setiap permintaan yang mengubah data. Pertahanan semacam ini sering dianggap aktif tanpa usaha, padahal sebagian hanya aktif bila konfigurasinya dinyatakan secara eksplisit. Keadaan itu wajar karena framework tidak dapat menebak lingkungannya, sedangkan nama domain production dan keputusan pemaksaan HTTPS sepenuhnya milik aplikasi yang dipasang. Tabel berikut memetakan pertahanan itu beserta syarat aktifnya.

Pertahanan bawaanBentuk pada frameworkSyarat aktif
Query berparameterORM menulis parameter ke dalam queryAkses data selalu melalui ORM, bukan penggabungan string
Perlindungan CSRFMiddleware pemeriksa tokenMiddleware terpasang dan template menyisipkan token
Pengodean keluaranTemplate engine mengodekan otomatisKeluaran dirender melalui template, bukan penggabungan string
Cookie sesi bertandaAtribut HttpOnly dan SecurePengaturan cookie produksi dinyatakan eksplisit

Kegagalan menyalakan pertahanan ini masuk kategori A02:2025 Security Misconfiguration pada OWASP Top 10:2025, kategori yang menempati peringkat kedua pada edisi tersebut. Akibat operasionalnya sudah diperlihatkan pada topik Konfigurasi Default di modul Miskonfigurasi dan Supply Chain, yaitu halaman debug yang membocorkan isi variabel. Topik ini melihat kejadian yang sama dari sisi pertahanannya, yaitu daftar nilai yang harus diganti sebelum aplikasi menerima lalu lintas publik.

Pemeriksa hardening ala linter#

Pemeriksaan manual cepat terlewat karena konfigurasi tersebar di beberapa berkas dan lingkungan. Pola yang lebih tahan lama meniru linter, yaitu satu skrip menerima kamus konfigurasi aplikasi dan menandai setiap nilai yang tidak aman beserta alasannya. Skrip berikut memuat empat pemeriksaan, yaitu mode debug, daftar host yang diizinkan, perlindungan CSRF, dan atribut Secure pada cookie. Simpan berkas berikut, lalu jalankan dengan perintah python3 periksa-hardening.py.

python periksa-hardening.py
"""Pemeriksa hardening konfigurasi aplikasi ala linter.

Fungsi periksa menerima kamus konfigurasi aplikasi dan menandai setiap
nilai default yang tidak aman bila terbawa ke production. Dua
konfigurasi diperiksa berurutan, yaitu pengaturan pengembangan yang
cacat dan pengaturan production yang lolos seluruh pemeriksaan.
"""


def periksa(konfigurasi):
    """Mengembalikan daftar temuan atas satu kamus konfigurasi."""
    temuan = []
    if konfigurasi.get("mode_debug", True):
        temuan.append("mode debug aktif, halaman error membocorkan isi variabel")
    if konfigurasi.get("host_diizinkan") == ["*"]:
        temuan.append("host yang diizinkan berupa '*', header Host apa pun dilayani")
    if not konfigurasi.get("csrf_aktif", False):
        temuan.append("perlindungan CSRF mati, permintaan lintas situs dapat dipalsukan")
    if not konfigurasi.get("cookie_aman", False):
        temuan.append("cookie tanpa atribut Secure dapat terbawa lewat HTTP")
    return temuan


PENGEMBANGAN = {
    "mode_debug": True,
    "host_diizinkan": ["*"],
    "csrf_aktif": False,
    "cookie_aman": False,
}

PRODUKSI = {
    "mode_debug": False,
    "host_diizinkan": ["perpustakaan.example"],
    "csrf_aktif": True,
    "cookie_aman": True,
}


for nama, konfigurasi in (("pengembangan", PENGEMBANGAN), ("produksi", PRODUKSI)):
    print(f"== konfigurasi {nama} ==")
    temuan = periksa(konfigurasi)
    if temuan:
        for butir in temuan:
            print(f"  GAGAL: {butir}")
    else:
        print("  LOLOS: tidak ada default tidak aman yang tersisa")
text Keluaran
== konfigurasi pengembangan ==
  GAGAL: mode debug aktif, halaman error membocorkan isi variabel
  GAGAL: host yang diizinkan berupa '*', header Host apa pun dilayani
  GAGAL: perlindungan CSRF mati, permintaan lintas situs dapat dipalsukan
  GAGAL: cookie tanpa atribut Secure dapat terbawa lewat HTTP
== konfigurasi produksi ==
  LOLOS: tidak ada default tidak aman yang tersisa

Konfigurasi pertama adalah pengaturan pengembangan yang belum disentuh, dan seluruh barisnya dinyatakan GAGAL beserta alasannya. Konfigurasi kedua memuat nilai produksi yang benar, sehingga pemeriksa meloloskannya. Nama kunci pada skrip sengaja dibuat netral terhadap framework, misalnya host_diizinkan yang padanannya adalah ALLOWED_HOSTS pada Django, sedangkan padanan cookie_aman adalah SESSION_COOKIE_SECURE. Pemetaan yang sama berlaku pada framework lain, sehingga satu skrip dapat memeriksa banyak aplikasi dengan daftar nilai yang berbeda. Pemeriksaan juga dijalankan ulang setiap kali konfigurasi berubah, sehingga pelanggaran baru tertangkap sebelum rilis.

Contoh yang diperdalam: Django#

Django dipilih untuk contoh yang diperdalam karena daftar pengaturannya terdokumentasi lengkap, termasuk daftar periksa deployment resminya. Kutipan berikut memuat pengaturan produksi yang paling menentukan, dan setiap barisnya dipetakan ke satu pemeriksaan pada skrip sebelumnya. Nama host menggunakan ranah contoh perpustakaan agar konsisten dengan contoh lain di modul ini.

python Contoh: pengaturan Django untuk production
# tidak-dijalankan
# kutipan settings.py, proyek Django tidak tersedia di sandbox
DEBUG = False
ALLOWED_HOSTS = ["perpustakaan.example"]
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True

Baris DEBUG = False mematikan halaman error yang membocorkan isi variabel, sedangkan ALLOWED_HOSTS yang eksplisit menolak permintaan dengan header Host palsu. Dua baris berikutnya menandai cookie CSRF dan cookie sesi agar hanya terkirim melalui HTTPS, dan SECURE_SSL_REDIRECT memaksa seluruh lalu lintas HTTP berpindah ke HTTPS. Django menyediakan perintah python manage.py check --deploy yang memeriksa banyak pengaturan semacam ini secara otomatis, sehingga gagasan pemeriksa ala linter pada bagian sebelumnya memiliki padanan resmi di dalam framework itu sendiri. Keluarannya berupa daftar pengaturan yang perlu diperbaiki beserta penjelasan singkat, sehingga hasilnya dapat langsung diterjemahkan menjadi suntingan berkas settings.py.

Pembanding singkat: Rails, FastAPI, dan Laravel#

Kerangka pemeriksaan yang sama berlaku pada framework lain, hanya nama pengaturannya yang berbeda. Tabel berikut merangkum pengaturan kunci yang wajib diperiksa sebelum aplikasi menerima lalu lintas publik.

FrameworkPengaturanNilai untuk production
Railsconfig.force_ssltrue
Railsprotect_from_forgeryaktif pada controller dasar
FastAPIdokumentasi interaktifdimatikan dengan docs_url=None
LaravelAPP_DEBUGfalse
LaravelAPP_ENVproduction
ruby Contoh: pengaturan Rails untuk production
# tidak-dijalankan
# kutipan konfigurasi Rails, runtime Ruby tidak tersedia di sandbox

# config/environments/production.rb
Rails.application.configure do
  config.force_ssl = true
end

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
end
python Contoh: aplikasi FastAPI untuk production
# tidak-dijalankan
# kutipan aplikasi FastAPI, paket fastapi tidak terpasang di sandbox
from fastapi import FastAPI

app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None)
php Contoh: pengaturan Laravel untuk production
// tidak-dijalankan
// kutipan config/app.php, runtime PHP tidak tersedia di sandbox
return [
    'debug' => env('APP_DEBUG', false),
    'env' => env('APP_ENV', 'production'),
];

Rails menegakkan HTTPS melalui config.force_ssl dan memeriksa token CSRF melalui protect_from_forgery pada controller dasar. FastAPI tidak mempunyai halaman debug seperti Django, sehingga penguncian bertumpu pada cara aplikasi dijalankan tanpa mode pengembangan dan pada dokumentasi interaktif yang dimatikan agar struktur endpoint tidak dipamerkan. Laravel menyimpan mode debug pada lingkungan APP_ENV, dan nilai APP_DEBUG=false mencegah halaman error menampilkan jejak pelacakan yang rinci.

Lokasi pengaturannya memang berbeda, yaitu Django menaruhnya pada modul settings, Rails pada berkas konfigurasi lingkungan, FastAPI pada argumen aplikasi dan server, sedangkan Laravel pada berkas lingkungan beserta berkas konfigurasinya. Yang dipindahkan antar-framework bukan nilainya, melainkan daftar pertanyaannya, yaitu apakah mode pengembangan sudah mati, apakah transportasi dipaksa terenkripsi, dan apakah pertahanan permintaan lintas situs aktif. Daftar pertanyaan yang sama juga berlaku untuk framework yang tidak disebut pada topik ini.

Kesalahan umum#

Kesalahan berikut sering ditemukan saat default framework disiapkan untuk production.

  • Membiarkan perlindungan CSRF dimatikan karena sebagian endpoint berpindah ke API. Pengguna browser tetap ada, sehingga middleware hanya dimatikan untuk endpoint yang sesungguhnya tanpa cookie.
  • Menyalin berkas konfigurasi pengembangan ke production tanpa pemeriksaan. Nilai seperti DEBUG = True ikut terbawa tanpa terlihat, dan pemeriksaan otomatis menutup celah ini.
  • Menetapkan daftar host * hanya agar error ALLOWED_HOSTS hilang. Header Host palsu kemudian dilayani, padahal daftar host produksi selalu dapat dituliskan secara eksplisit.
  • Menganggap pembaruan versi framework mengubah konfigurasi lama. Berkas konfigurasi yang sudah ada tidak ikut berubah saat framework diperbarui, sehingga nilai yang tidak aman tetap hidup sampai disunting.

Ringkasan#

  • Framework menyediakan pertahanan siap pakai untuk query, CSRF, pengodean keluaran, dan cookie, tetapi sebagian hanya aktif bila konfigurasinya dinyatakan eksplisit.
  • Pemeriksa hardening ala linter menandai default yang tidak aman, dan padanan resminya sudah tersedia, misalnya python manage.py check --deploy pada Django.
  • Pengaturan kunci yang sama diperiksa pada setiap framework, yaitu mode debug mati, host eksplisit, CSRF aktif, HTTPS dipaksa, dan cookie bertanda.

Referensi#