Pengujian manual yang hanya mengandalkan keterampilan tanpa alur kerja menghasilkan cakupan yang berbeda-beda pada setiap sesinya. Topik ini menyusun pengujian manual menjadi empat fase yang berulang, yaitu memetakan permukaan aplikasi, menjelajah perilakunya, mengeksploitasi celah yang muncul, dan mendokumentasikan temuan. Seluruh fase dipraktikkan terhadap satu server lab lokal melalui satu skrip, sehingga alur kerja yang sama dapat diterapkan pada aplikasi apa pun yang diizinkan untuk diuji.
Empat fase yang berulang#
Metodologi manual menuntut setiap sesi pengujian melewati empat fase dengan urutan yang sama. Fase memetakan menghasilkan gambaran permukaan aplikasi, yaitu halaman, tautan, formulir, parameter, dan setiap titik tempat data masuk. Fase menjelajah membuka endpoint yang ditemukan pada peta, mengikuti alur penggunaan normal, dan mencatat perilaku yang menyimpang dari dugaan. Fase mengeksploitasi menguji hipotesis yang tumbuh dari dua fase sebelumnya, misalnya kecurigaan pada sebuah parameter yang memantulkan input tanpa pengodean, kemudian membuktikannya dengan payload uji yang aman pada lab.
Fase keempat, mendokumentasikan, mengubah eksperimen menjadi catatan yang dapat dibaca orang lain. Temuan dicatat bersama lokasi, bukti, dan langkah reproduksinya, sehingga laporan tidak bergantung pada ingatan. Setelah satu putaran selesai, siklus kembali ke fase memetakan dengan peta yang lebih lengkap dan hipotesis baru. Pengujian manual karena itu bukan proses lurus, melainkan perputaran yang menambah kedalaman setiap kali berputar.
Diagram berikut memperlihatkan keempat fase beserta arah perputarannya.
Urutan fase membantu keputusan praktis di lapangan. Eksploitasi tidak dilakukan sebelum ada peta dan pemahaman perilaku, karena percobaan tanpa konteks mudah menjadi tebakan acak yang membuang waktu. Dokumentasi juga tidak ditunda sampai akhir proyek, melainkan dijalankan setiap kali temuan muncul, karena catatan yang ditunda biasanya kehilangan detail permintaan dan responsnya.
Peta hasil fase memetakan juga menjadi bahan yang paling banyak digunakan ulang. Daftar endpoint, parameter, dan formulir yang terkumpul memudahkan pemeriksaan menyeluruh, misalnya saat setiap parameter yang memantulkan input diuji dengan pola serupa untuk melihat apakah perilakunya konsisten. Tanpa peta, pengujian cenderung berhenti pada halaman yang kebetulan dibuka, sedangkan dengan peta, setiap titik masuk memiliki status yang jelas, yaitu sudah diuji, belum diuji, atau tidak berlaku.
Sesi lab: empat fase dalam satu skrip#
Skrip berikut menjalankan keempat fase terhadap satu server lab kecil yang berjalan sebagai thread di dalam skrip yang sama. Fase memetakan mengambil halaman utama dan mengekstrak tautan beserta formulirnya, fase menjelajah membuka endpoint yang ditemukan, fase mengeksploitasi mengirim parameter pencarian berisi muatan HTML, dan fase mendokumentasikan mencetak seluruh temuan. Jalankan berkas berikut dengan perintah python3 sesi-lab.py.
"""Sesi lab metodologi manual: empat fase pengujian yang berulang
terhadap satu server lab lokal.
Fase memetakan mengambil halaman utama dan mencatat tautannya, fase
menjelajah membuka endpoint yang ditemukan, fase mengeksploitasi menguji
parameter pencarian yang memantulkan input tanpa pengodean, dan fase
mendokumentasikan mencetak seluruh temuan. Server lab berjalan sebagai
thread di dalam skrip yang sama, sehingga skrip selesai dan keluarannya
deterministik."""
import re
import threading
import urllib.parse
import urllib.request
from http.server import BaseHTTPRequestHandler, HTTPServer
PORT = 8911
HALAMAN_UTAMA = """<!doctype html>
<html>
<head><title>Katalog Alat Tulis</title></head>
<body>
<h1>Katalog Alat Tulis</h1>
<a href="/tentang">Tentang</a>
<a href="/produk">Daftar produk</a>
<form action="/cari" method="get">
<input name="q" placeholder="cari produk">
<button type="submit">Cari</button>
</form>
</body>
</html>"""
TEMUAN = []
class PenanganLab(BaseHTTPRequestHandler):
def kirim(self, isi):
data = isi.encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "text/html; charset=utf-8")
self.send_header("Content-Length", str(len(data)))
self.end_headers()
self.wfile.write(data)
def do_GET(self):
bagian = urllib.parse.urlparse(self.path)
jalur = bagian.path
query = urllib.parse.parse_qs(bagian.query)
if jalur == "/":
self.kirim(HALAMAN_UTAMA)
elif jalur == "/tentang":
self.kirim("<h1>Tentang</h1><p>Katalog milik lab latihan.</p>")
elif jalur == "/produk":
self.kirim("<h1>Daftar produk</h1><ul><li>Pulpen</li><li>Buku</li></ul>")
elif jalur == "/cari":
# endpoint lab yang sengaja memantulkan input tanpa pengodean
kata = query.get("q", [""])[0]
self.kirim(f"<h1>Hasil pencarian: {kata}</h1>")
else:
self.send_response(404)
self.send_header("Content-Length", "0")
self.end_headers()
def log_message(self, format, *args):
pass # matikan log bawaan agar keluaran tetap rapi
def ambil(target):
"""Kirim satu permintaan GET dan kembalikan (status, isi teks)."""
url = f"http://127.0.0.1:{PORT}{target}"
with urllib.request.urlopen(url, timeout=5) as jawaban:
return jawaban.status, jawaban.read().decode("utf-8")
def fase_memetakan():
print("== Fase 1: memetakan ==")
status, isi = ambil("/")
tautan = re.findall(r'href="([^"]+)"', isi)
print(f"Halaman utama: HTTP {status}, {len(tautan)} tautan ditemukan")
for t in tautan:
print(f" tautan : {t}")
aksi = re.search(r'action="([^"]+)"', isi)
masukan = re.findall(r'name="([^"]+)"', isi)
print(f"Formulir menuju {aksi.group(1)} dengan parameter {masukan[0]}")
return tautan
def fase_menjelajah(tautan):
print("== Fase 2: menjelajah ==")
for t in tautan:
status, isi = ambil(t)
print(f" GET {t:8} HTTP {status} {len(isi)} byte")
TEMUAN.append(
{
"tingkat": "info",
"judul": "Endpoint /cari menerima parameter q dari formulir halaman utama",
"lokasi": "/cari?q=",
"bukti": "Form action /cari memuat input name=q",
}
)
def fase_mengeksploitasi():
print("== Fase 3: mengeksploitasi ==")
muatan = "<b>uji</b>"
target = "/cari?q=" + urllib.parse.quote(muatan)
status, isi = ambil(target)
print(f" GET {target} -> HTTP {status}")
if muatan in isi:
baris = [b for b in isi.split("\n") if muatan in b][0].strip()
print(f" Muatan dipantulkan mentah pada: {baris}")
print(" Kesimpulan: input dipantulkan tanpa pengodean HTML")
TEMUAN.append(
{
"tingkat": "tinggi",
"judul": "XSS terpantul pada parameter q endpoint /cari",
"lokasi": "/cari?q=<b>uji</b>",
"bukti": 'Respons memuat <h1>Hasil pencarian: <b>uji</b></h1> tanpa pengodean',
}
)
else:
print(" Muatan tidak dipantulkan mentah, tidak ada temuan")
def fase_mendokumentasikan():
print("== Fase 4: mendokumentasikan ==")
print(f"{len(TEMUAN)} temuan tercatat:")
for t in TEMUAN:
print(f" [{t['tingkat']:6}] {t['judul']}")
print(f" lokasi: {t['lokasi']}")
print(f" bukti : {t['bukti']}")
def main():
server = HTTPServer(("127.0.0.1", PORT), PenanganLab)
threading.Thread(target=server.serve_forever, daemon=True).start()
try:
tautan = fase_memetakan()
fase_menjelajah(tautan)
fase_mengeksploitasi()
fase_mendokumentasikan()
finally:
server.shutdown()
server.server_close()
if __name__ == "__main__":
main()== Fase 1: memetakan ==
Halaman utama: HTTP 200, 2 tautan ditemukan
tautan : /tentang
tautan : /produk
Formulir menuju /cari dengan parameter q
== Fase 2: menjelajah ==
GET /tentang HTTP 200 49 byte
GET /produk HTTP 200 59 byte
== Fase 3: mengeksploitasi ==
GET /cari?q=%3Cb%3Euji%3C/b%3E -> HTTP 200
Muatan dipantulkan mentah pada: <h1>Hasil pencarian: <b>uji</b></h1>
Kesimpulan: input dipantulkan tanpa pengodean HTML
== Fase 4: mendokumentasikan ==
2 temuan tercatat:
[info ] Endpoint /cari menerima parameter q dari formulir halaman utama
lokasi: /cari?q=
bukti : Form action /cari memuat input name=q
[tinggi] XSS terpantul pada parameter q endpoint /cari
lokasi: /cari?q=<b>uji</b>
bukti : Respons memuat <h1>Hasil pencarian: <b>uji</b></h1> tanpa pengodeanKeluaran di atas memperlihatkan temuan yang berangkat dari peta, bukan dari tebakan. Parameter q baru diuji setelah fase memetakan menemukan formulirnya, dan kesimpulan kerentanan hanya dinyatakan setelah muatan terbukti dipantulkan mentah. Catatan pada fase mendokumentasikan berupa data terstruktur yang berisi tingkat, lokasi, dan bukti, sehingga catatan yang sama dapat disalin menjadi draf laporan tanpa menulis ulang.
Struktur skripnya sengaja dibuat sederhana agar mudah ditiru. Server lab didefinisikan sebagai handler yang melayani beberapa jalur, thread menjalankannya di latar belakang, dan setiap fase berupa fungsi yang dipanggil berurutan. Untuk berlatih lebih lanjut, halaman lab ditambah atau perilakunya diubah, kemudian fase menjelajah dan mengeksploitasi diperluas mengikuti permukaan barunya. Skrip yang sama juga berfungsi sebagai catatan pelaksanaan, karena urutan permintaan yang dikirim terbaca langsung dari kodenya.
Kesalahan umum#
Empat kesalahan berikut paling sering muncul ketika pengujian manual baru dimulai.
- Melompat ke eksploitasi tanpa peta. Percobaan tanpa pemahaman permukaan aplikasi menghasilkan tebakan acak, dan perbaikannya adalah menyelesaikan fase memetakan serta menjelajah terlebih dahulu.
- Mencatat temuan pada jendela terminal sementara. Detail permintaan hilang pada sesi berikutnya, sehingga catatan perlu ditulis pada berkas yang sama dengan eksperimennya.
- Menguji tanpa kriteria keberhasilan. Setiap hipotesis perlu disertai tanda keberhasilan yang jelas, misalnya muatan yang dipantulkan mentah, agar kesimpulan tidak ditarik dari perasaan.
- Mengulang pengujian yang sama pada sesi berikutnya karena catatan sebelumnya tidak lengkap. Skrip dan catatan dari sesi lama menjadi titik awal yang lebih cepat.
Kesalahan-kesalahan tersebut berpangkal pada anggapan yang sama, yaitu pengujian manual sebagai rangkaian percobaan spontan. Metodologi menegaskan kebalikannya, sebab nilai seorang penguji terletak pada catatan yang dapat diperiksa ulang, bukan pada jumlah percobaan yang dilakukan. Catatan yang rapi juga membuat pengujian ulang pascaperbaikan menjadi cepat, karena langkah yang sama dapat dijalankan dari titik yang tercatat.
Ringkasan#
- Pengujian manual berjalan sebagai siklus empat fase, yaitu memetakan, menjelajah, mengeksploitasi, dan mendokumentasikan, yang diulang dengan peta serta hipotesis yang makin lengkap.
- Eksploitasi dilakukan hanya setelah permukaan dan perilaku aplikasi dipahami, dan setiap hipotesis diuji dengan kriteria keberhasilan yang jelas.
- Temuan disimpan sebagai data terstruktur berisi tingkat, lokasi, dan bukti agar laporan dapat disusun tanpa rekonstruksi ingatan.
Referensi#
- OWASP Web Security Testing Guide — OWASP Foundation — Panduan resmi OWASP yang menaungi disiplin pengujian keamanan aplikasi web.
- Web Application Security Testing — OWASP Foundation — Bagian isi WSTG yang merinci pengujian per area aplikasi web.
- Web Security Academy — PortSwigger — Materi pengujian manual gratis per kategori kerentanan beserta lab latihannya.