Temuan Berperingkat Risiko

Menyusun temuan berperingkat risiko dengan dasar CVSS dan prioritas yang jujur.

Daftar isi

Empat temuan pada audit aplikasi lab Catatan Pegawai baru menjadi daftar kerja ketika risikonya diberi peringkat. Topik ini menyusun peringkat tersebut dengan Common Vulnerability Scoring System (CVSS) versi 3.1, yaitu kerangka terbuka dari FIRST untuk menyatakan tingkat keparahan kerentanan (severitas) sebagai skor 0.0 sampai 10.0. Rumus skor dasar dijelaskan terlebih dahulu, diimplementasikan dengan Python, diverifikasi terhadap contoh resmi, lalu diterapkan pada keempat temuan. Hasil akhirnya berupa daftar prioritas yang dapat dipertanggungjawabkan beserta batas kejujurannya.

Peringkat risiko sebagai bahasa bersama#

Peringkat risiko menyelesaikan satu masalah komunikasi, yaitu menyepakati urutan pengerjaan antara tim penemu kerentanan dan tim yang memperbaikinya. Tanpa peringkat, setiap temuan dapat diklaim sama pentingnya, sedangkan kapasitas perbaikan selalu terbatas. CVSS menyetel peringkat itu dari delapan metrik dasar yang menggambarkan cara mengeksploitasi dan akibatnya, sehingga dua orang yang membaca vektor yang sama dapat menurunkan skor yang sama. Versi 3.1 yang digunakan di sini adalah versi yang paling umum dipelajari dan menjadi dasar perhitungan banyak basis data kerentanan.

CVSS memiliki tiga kelompok metrik, yaitu Base, Temporal, dan Environmental. Kelompok Base mengukur sifat kerentanan yang tidak terpengaruh waktu maupun lingkungan, dan inilah satu-satunya kelompok yang dikerjakan pada topik ini karena kelompok itulah yang biasanya dipublikasikan. Skor dari kelompok ini disebut skor dasar (Base Score), dan nilainya dipetakan ke skala severitas kualitatif berikut menurut Tabel 14 spesifikasi resmi.

Rentang skorSeveritas
0.0None
0.1 sampai 3.9Low
4.0 sampai 6.9Medium
7.0 sampai 8.9High
9.0 sampai 10.0Critical

Delapan metrik dasar dan rumusnya#

Keempat metrik pertama menggambarkan kemudahan eksploitasi, sedangkan tiga metrik berikutnya menggambarkan dampaknya. Metrik kedelapan bernama Scope menentukan cabang perhitungan. Susunan lengkapnya adalah sebagai berikut.

MetrikNilaiArti singkat
Attack Vector (AV)N, A, L, PJarak penyerang ke target, dari jaringan sampai sentuhan fisik
Attack Complexity (AC)L, HKondisi di luar kendali penyerang yang harus terpenuhi
Privileges Required (PR)N, L, HHak akses yang harus dimiliki sebelum menyerang
User Interaction (UI)N, RKeterlibatan pengguna lain untuk keberhasilan serangan
Scope (S)U, CApakah dampak melampaui komponen yang rentan
Confidentiality (C)H, L, NKehilangan kerahasiaan data
Integrity (I)H, L, NKerusakan integritas data
Availability (A)H, L, NGangguan ketersediaan layanan

Nilai-nilai itu ditulis sebagai vektor, yaitu deretan metrik yang dipisahkan garis miring, misalnya AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N untuk temuan IDOR (Insecure Direct Object References) pada lab. Rumus skor dasar mengolah vektor tersebut melalui tiga subhitungan, yaitu subskor dampak intern (Impact Sub-Score, ISS), dampak (Impact), dan eksploitabilitas (Exploitability). Setiap huruf pada rumus diganti konstanta resminya saat dihitung, dan seluruh konstantanya tercantum pada Tabel 16 spesifikasi.

ISS=1−(1−C)×(1−I)×(1−A) \text{ISS} = 1 - (1 - C) \times (1 - I) \times (1 - A)
Impact={6.42×ISSbila S=U7.52×(ISS−0.029)−3.25×(ISS−0.02)15bila S=C \text{Impact} = \begin{cases} 6.42 \times \text{ISS} & \text{bila } S = U \\ 7.52 \times (\text{ISS} - 0.029) - 3.25 \times (\text{ISS} - 0.02)^{15} & \text{bila } S = C \end{cases}
Exploitability=8.22×AV×AC×PR×UI \text{Exploitability} = 8.22 \times AV \times AC \times PR \times UI
BaseScore={0bila Impact≤0Roundup(min⁡(Impact+Exploitability, 10))bila S=URoundup(min⁡(1.08×(Impact+Exploitability), 10))bila S=C \text{BaseScore} = \begin{cases} 0 & \text{bila Impact} \leq 0 \\ \text{Roundup}(\min(\text{Impact} + \text{Exploitability},\, 10)) & \text{bila } S = U \\ \text{Roundup}(\min(1.08 \times (\text{Impact} + \text{Exploitability}),\, 10)) & \text{bila } S = C \end{cases}

Fungsi Roundup membulatkan ke atas ke satu tempat desimal, sehingga hasil 4.02 menjadi 4.1 sedangkan 4.00 tetap 4.0. Nilai PR khusus berubah menurut Scope, dan perbedaannya mudah terlewat.

Implementasi dan verifikasi rumus#

Implementasi berikut menerjemahkan keempat rumus di atas ke dalam Python. Fungsi roundup mengikuti saran Appendix A spesifikasi, yaitu membulatkan pada bilangan bulat terlebih dahulu agar hasilnya sama di semua bahasa pemrograman. Simpan berkasnya sebagai cvss.py, lalu jalankan dengan python3 cvss.py.

python cvss.py
"""Perhitungan CVSS v3.1 Base Score untuk laporan temuan.

Modul ini menerjemahkan rumus pada bagian 7.1 spesifikasi CVSS v3.1 (FIRST)
ke dalam Python, memverifikasinya terhadap dua contoh resmi dokumen Examples
v3.1, lalu memberi peringkat pada empat temuan lab Catatan Pegawai. Jalankan
dengan `python3 cvss.py`.
"""

# Konstanta metrik dasar (Tabel 16 spesifikasi CVSS v3.1).
AV = {"N": 0.85, "A": 0.62, "L": 0.55, "P": 0.20}
AC = {"L": 0.77, "H": 0.44}
UI = {"N": 0.85, "R": 0.62}
CIA = {"H": 0.56, "L": 0.22, "N": 0.0}
# Nilai PR berbeda apabila Scope Changed (Tabel 16 spesifikasi).
PR_S_UNCHANGED = {"N": 0.85, "L": 0.62, "H": 0.27}
PR_S_CHANGED = {"N": 0.85, "L": 0.68, "H": 0.50}


def roundup(nilai):
    """Membulatkan ke atas ke satu desimal (Appendix A spesifikasi v3.1)."""
    bulat = round(nilai * 100000)
    if bulat % 10000 == 0:
        return bulat / 100000.0
    return (bulat // 10000 + 1) / 10.0


def skor_dasar(vektor):
    """Menghitung Base Score dari vektor seperti AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N."""
    metrik = dict(bagian.split(":", 1) for bagian in vektor.split("/"))
    c, i, a = CIA[metrik["C"]], CIA[metrik["I"]], CIA[metrik["A"]]
    iss = 1.0 - (1.0 - c) * (1.0 - i) * (1.0 - a)
    if metrik["S"] == "U":
        dampak = 6.42 * iss
        pr = PR_S_UNCHANGED[metrik["PR"]]
    else:
        dampak = 7.52 * (iss - 0.029) - 3.25 * (iss - 0.02) ** 15
        pr = PR_S_CHANGED[metrik["PR"]]
    eksploitasi = 8.22 * AV[metrik["AV"]] * AC[metrik["AC"]] * pr * UI[metrik["UI"]]
    if dampak <= 0:
        return 0.0
    if metrik["S"] == "U":
        return roundup(min(dampak + eksploitasi, 10.0))
    return roundup(min(1.08 * (dampak + eksploitasi), 10.0))


def label_severitas(skor):
    """Skala severitas kualitatif (Tabel 14 spesifikasi v3.1)."""
    if skor == 0.0:
        return "None"
    if skor <= 3.9:
        return "Low"
    if skor <= 6.9:
        return "Medium"
    if skor <= 8.9:
        return "High"
    return "Critical"


def main():
    print("== Verifikasi terhadap contoh resmi dokumen Examples v3.1 ==")
    resmi = (
        ("CVE-2014-0160", "AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", 7.5),
        ("CVE-2013-0375", "AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N", 6.4),
        ("CVE-2017-5942", "AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", 6.1),
    )
    for cve, vektor, skor_resmi in resmi:
        hitung = skor_dasar(vektor)
        cocok = "COCOK" if hitung == skor_resmi else "TIDAK COCOK"
        print(f"{cve}  {vektor}  hitung {hitung:.1f}  resmi {skor_resmi:.1f}  {cocok}")

    print()
    print("== Peringkat temuan lab Catatan Pegawai ==")
    temuan = (
        ("Token reset dapat diprediksi", "AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"),
        ("IDOR pada endpoint catatan", "AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N"),
        ("Reflected XSS pada pencarian", "AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N"),
        ("Pesan error debug bocor", "AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N"),
    )
    hasil = sorted(
        ((skor_dasar(vektor), nama, vektor) for nama, vektor in temuan),
        key=lambda baris: -baris[0],
    )
    for skor, nama, vektor in hasil:
        print(f"{skor:4.1f}  {label_severitas(skor):<8}  {nama:<30}  {vektor}")


if __name__ == "__main__":
    main()
text Keluaran
== Verifikasi terhadap contoh resmi dokumen Examples v3.1 ==
CVE-2014-0160  AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N  hitung 7.5  resmi 7.5  COCOK
CVE-2013-0375  AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N  hitung 6.4  resmi 6.4  COCOK
CVE-2017-5942  AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N  hitung 6.1  resmi 6.1  COCOK

== Peringkat temuan lab Catatan Pegawai ==
 9.8  Critical  Token reset dapat diprediksi    AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
 7.1  High      IDOR pada endpoint catatan      AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N
 5.4  Medium    Reflected XSS pada pencarian    AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
 4.3  Medium    Pesan error debug bocor         AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N

Bagian pertama keluaran adalah verifikasi. Tiga vektor contoh diambil dari dokumen Examples resmi CVSS v3.1 milik FIRST beserta skornya, masing-masing dengan identifikator CVE (Common Vulnerabilities and Exposures), yaitu CVE-2014-0160 dengan skor resmi 7.5, CVE-2013-0375 dengan 6.4, dan CVE-2017-5942 dengan 6.1. Ketiganya mencetak COCOK, artinya implementasi menghasilkan skor yang sama persis dengan perhitungan resmi, termasuk pada cabang Scope Changed yang konstanta PR-nya berbeda. Implementasi hanya layak digunakan untuk menilai temuan setelah pemeriksaan silang semacam ini lolos.

Bagian kedua keluaran memberi peringkat pada keempat temuan lab. Pilihan metriknya dapat diikuti sebagai berikut. IDOR dinilai PR:L karena penyerang harus memiliki akun sah terlebih dahulu, dengan C:H karena seluruh isi catatan pengguna lain terbaca. Reflected XSS, varian XSS yang memantulkan masukan pada respons, dinilai S:C dengan C:L/I:L karena komponen yang terdampak adalah browser korban, bukan server, dan penyerang tidak memerlukan hak apa pun meskipun korban harus mengklik tautan. Token reset yang dapat diprediksi memberi pengambilalihan akun penuh tanpa hak istimewa, sehingga dinilai PR:N dengan dampak tinggi pada ketiga aspek. Pesan error debug hanya membocorkan informasi terbatas, sehingga dinilai C:L tanpa dampak integritas maupun ketersediaan.

Kejujuran dalam menentukan prioritas#

Skor CVSS menjawab pertanyaan seberapa parah sifat sebuah kerentanan, bukan seberapa mendesak pengerjaannya di organisasi tertentu. Urutan perbaikan yang jujur menempatkan skor sebagai titik awal, lalu menyesuaikannya dengan konteks. Temuan token reset pada lab mendapat skor 9.8 dan memang harus didahulukan, tetapi sebuah temuan 5.4 pada layanan yang terpapar internet dapat mendahului temuan 7.1 pada layanan internal yang hanya dijangkau sedikit orang. Pemanfaatan aktif oleh penyerang, jumlah aset yang terdampak, dan adanya kontrol pengganti juga mengubah urutan tersebut.

Kejujuran lain yang perlu dijaga adalah ketelitian dalam menetapkan metrik. Skor yang dinaikkan agar temuan terdengar mendesak akan mengikis kepercayaan pada laporan berikutnya, sedangkan skor yang ditekan agar antrian perbaikan tampak ringan menunda perbaikan yang sesungguhnya diperlukan. Karena itu, setiap vektor disertai alasan satu kalimat seperti pada bagian sebelumnya, sehingga orang lain dapat menelusuri pilihan metriknya dan mengubahnya apabila bukti baru menunjukkan hal yang berbeda.

TemuanVektorSkorSeveritas
Token reset dapat diprediksiAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H9.8Critical
IDOR pada endpoint catatanAV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N7.1High
Reflected XSS pada pencarianAV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N5.4Medium
Pesan error debug bocorAV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N4.3Medium

Ringkasan#

  • CVSS v3.1 mengubah delapan metrik dasar menjadi skor 0.0 sampai 10.0 melalui subskor dampak intern, dampak, dan eksploitabilitas, dengan cabang khusus untuk Scope Changed.
  • Implementasi Python diverifikasi terhadap tiga contoh resmi FIRST dan menghasilkan skor yang sama, sehingga layak digunakan untuk menilai temuan lab.
  • Peringkat perbaikan menggunakan skor sebagai titik awal yang disesuaikan dengan konteks paparan, pemanfaatan aktif, dan kontrol pengganti.

Referensi#