Lompat ke konten
dokumentasi.id
Commit 51864a8
v1
Star1,9 rb

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

11

Keamanan, Scope, dan Sanitasi

Guardian memeriksa tiga hal di jalur eksekusi: apakah target boleh disentuh, apakah konten yang masuk ke prompt sudah bersih, dan apakah tool berisiko boleh berjalan. Pemeriksaan pertama dan kedua hidup di utils/, sedangkan yang ketiga menempel pada WorkflowEngine. Karena ketiganya independen, satu lapis yang longgar tidak otomatis membuka lapis lain.

Perjalanan target dari input sampai eksekusi

WorkflowEngine.__init__ membuat satu ScopeValidator untuk seluruh sesi (core/workflow.py:30-38). Validasi dijalankan sebelum workflow dimuat, baik pada run_workflow (core/workflow.py:80-84) maupun pada run_autonomous (core/workflow.py:162-165). Kegagalan berhenti sebagai ValueError(f"Invalid target: {reason}"), sehingga tidak ada tool yang sempat berjalan.

stateDiagram-v2
    [*] --> validate_target
    validate_target --> urlparse : strip lalu urlparse
    urlparse --> _is_blacklisted
    _is_blacklisted --> Blocked : IP literal atau alias localhost
    _is_blacklisted --> _resolve : bukan IP literal
    _resolve --> _is_blacklisted : setiap IP hasil DNS
    _resolve --> Blocked : None berarti fail-closed
    _is_blacklisted --> require_scope_file : lolos blacklist
    require_scope_file --> _is_authorized : bernilai true
    require_scope_file --> Allowed : bernilai false
    _is_authorized --> Allowed : host cocok
    _is_authorized --> Blocked : host tidak cocok
    Allowed --> _confirm_tool
    _confirm_tool --> Blocked : destructive saat safe_mode
    _confirm_tool --> [*] : passive atau --yes atau confirm
    _confirm_tool --> [*] : declined atau tanpa TTY
    Blocked --> [*]
    style validate_target fill:#f59e0b,color:#000
    style urlparse fill:#8b5cf6,color:#fff
    style _is_blacklisted fill:#336791,color:#fff
    style _resolve fill:#8b5cf6,color:#fff
    style _is_authorized fill:#8b5cf6,color:#fff
    style require_scope_file fill:#f59e0b,color:#000
    style _confirm_tool fill:#f59e0b,color:#000
    style Allowed fill:#2d7d46,color:#fff
    style Blocked fill:#dc2626,color:#fff
%% fig: Perjalanan target dari validasi sampai gate eksekusi
%% desc: Target melewati blacklist, resolusi DNS, allowlist opsional, lalu confirmation gate sebelum satu tool dijalankan.
Fig. 1: Perjalanan target dari validasi sampai gate eksekusiTarget melewati blacklist, resolusi DNS, allowlist opsional, lalu confirmation gate sebelum satu tool dijalankan.

validate_target mengembalikan pasangan (bool, Optional[str]); urutan pemeriksaannya tetap dan berhenti pada kegagalan pertama (utils/scope_validator.py:87-115).

UrutanPemeriksaanSumberPerilaku saat gagal
1literal IP atau alias localhost diuji terhadap blacklist_networksutils/scope_validator.py:117-164False + SCOPE_VIOLATION CRITICAL
2hostname di-resolve, setiap IP hasil DNS diujiutils/scope_validator.py:151-163False + SCOPE_VIOLATION CRITICAL
3resolusi DNS gagalutils/scope_validator.py:143-149False — fail-closed
4scope.require_scope_file aktif dan host di luar allowlistutils/scope_validator.py:108-113False + SCOPE_VIOLATION HIGH

Blacklist CIDR berlapis

ScopeValidator selalu menggabungkan CIDR dari config dengan entri _HARDCODED_BLACKLIST_CIDRS; entri config tidak bisa menghapus entri bawaan (utils/scope_validator.py:36-49). Config bawaan hanya mendaftarkan empat CIDR, sehingga enam entri sisanya murni berasal dari kode (config/guardian.yaml:102-115).

CIDRCakupan
127.0.0.0/8loopback IPv4
10.0.0.0/8RFC1918
172.16.0.0/12RFC1918
192.168.0.0/16RFC1918
169.254.0.0/16link-local, termasuk metadata 169.254.169.254
100.64.0.0/10carrier-grade NAT
0.0.0.0/8alamat yang tidak sah sebagai tujuan
::1/128loopback IPv6
fc00::/7unique-local IPv6
fe80::/10link-local IPv6

Sepuluh entri itu ada di utils/scope_validator.py:19-30. Perbandingan menyamakan versi alamat lebih dulu lewat ip.version == network.version, jadi entri IPv4 tidak salah menolak alamat IPv6 (utils/scope_validator.py:131-137).

⚠️ Resolusi DNS di-cache per hostname (utils/scope_validator.py:166-182). Saat getaddrinfo gagal, cache diisi daftar kosong dan _resolve mengembalikan None pada panggilan pertama (utils/scope_validator.py:176-179); panggilan berikutnya membaca daftar kosong itu dari _dns_cache sehingga tidak lagi melewati cabang fail-closed (utils/scope_validator.py:143-149). Nilailah hasil validasi pertama, bukan yang kedua, ketika memutuskan satu host.

Allowlist dan scope file

load_scope_file membaca satu target per baris, melewati baris kosong dan komentar #, lalu memisahkan IP/CIDR dari domain (utils/scope_validator.py:59-85). _is_authorized menerima IP, network, domain persis, wildcard *.example.com, dan awalan titik yang mencakup subdomain (utils/scope_validator.py:184-217); aturan wildcard-nya ada di utils/scope_validator.py:200-215.

Kunci configNilai bawaanDibaca di
scope.blacklist4 CIDRutils/scope_validator.py:36-49
scope.require_scope_filefalseutils/scope_validator.py:108-113
scope.max_targets100tidak dirujuk di utils/scope_validator.py

⚠️ Dengan require_scope_file: false (config/guardian.yaml:102-115), pemeriksaan allowlist dilewati sepenuhnya dan hanya blacklist yang aktif. Mengaktifkannya membuat setiap target di luar berkas scope ditolak sebagai SCOPE_VIOLATION HIGH (utils/scope_validator.py:108-113).

add_authorized_target menambah IP, network, atau domain ke daftar izin tanpa memeriksa blacklist lebih dulu (utils/scope_validator.py:230-243).

Validasi ulang host yang ditemukan tool

Tool recon dan prober dapat memunculkan host yang tidak pernah diperiksa di awal. _validate_discovered_hosts mengumpulkan kandidat dari parsed output lalu melewatkan setiap kandidat kembali ke validate_target (core/workflow.py:516-545).

SifatIsi
Kunci kandidatsubdomains, alive_hosts, hosts, live_hosts, found_hosts, results, targets (core/workflow.py:516-519)
Kunci host di dalam objekhost, url, ip, address, subdomain (core/workflow.py:528-530)
Efek penolakanlogger.warning berisi maksimal lima host pertama (core/workflow.py:540-545)
Pembatalan workflowtidak ada — docstring menyebutnya tripwire dan audit log (core/workflow.py:506-511)

Sanitasi konten eksternal

Docstring utils/sanitize.py menyebut tiga akibat bila keluaran tool masuk prompt tanpa dibersihkan: parser regex planner bisa menjalankan NEXT_ACTION pilihan penyerang, instruksi override bisa masuk, dan escape ANSI bisa merusak tampilan console (utils/sanitize.py:4-13).

graph LR
    Raw[tool output eksternal] --> strip_control_chars
    strip_control_chars --> escape_close[escape UNTRUSTED_CLOSE]
    escape_close --> escape_open[escape UNTRUSTED_OPEN]
    escape_open --> wrap_untrusted
    UNTRUSTED_CONTENT_RULE --> Prompt
    wrap_untrusted --> Prompt[blok DATA-ONLY dalam prompt]
    style Raw fill:#dc2626,color:#fff
    style strip_control_chars fill:#2d7d46,color:#fff
    style escape_close fill:#8b5cf6,color:#fff
    style escape_open fill:#8b5cf6,color:#fff
    style wrap_untrusted fill:#2d7d46,color:#fff
    style UNTRUSTED_CONTENT_RULE fill:#f59e0b,color:#000
    style Prompt fill:#336791,color:#fff
%% fig: Dua primitif sanitasi sebelum data masuk prompt
%% desc: Keluaran tool dibersihkan, tag penutup dan pembuka dinetralkan, lalu payload dibungkus bersama aturan DATA-ONLY.
Fig. 2: Dua primitif sanitasi sebelum data masuk promptKeluaran tool dibersihkan, tag penutup dan pembuka dinetralkan, lalu payload dibungkus bersama aturan DATA-ONLY.
SimbolPerilakuSumber
strip_control_charshapus escape ANSI serta C0/C1, pertahankan tab, newline, dan carriage returnutils/sanitize.py:53-63
wrap_untrustedbersihkan lalu bungkus dengan tag pembuka dan penutuputils/sanitize.py:66-81
UNTRUSTED_OPEN, UNTRUSTED_CLOSEliteral <UNTRUSTED_TOOL_OUTPUT> dan penutupnyautils/sanitize.py:49-50
UNTRUSTED_CONTENT_RULEteks aturan DATA-ONLY untuk system promptutils/sanitize.py:85-95

wrap_untrusted menetralkan upaya keluar dari kotak dengan mengganti tag yang disisipkan penyerang menjadi entitas HTML sebelum membungkus payload (utils/sanitize.py:78-80). Test mengunci bahwa hasil akhir hanya memuat satu tag penutup (tests/test_sanitize.py:56-62), dan seluruh perilaku wrap_untrusted diuji di tests/test_sanitize.py:44-68.

UNTRUSTED_CONTENT_RULE benar-benar dipakai: template planner menyisipkannya ke system prompt (ai/prompt_templates/planner.py:19), dan PlannerAgent membungkus findings, attack surface, serta technologies sebelum masuk prompt (core/planner.py:48-52).

Pembersihan karakter kontrol diuji untuk ANSI CSI, OSC, C0, DEL, dan C1, termasuk sifat idempoten (tests/test_sanitize.py:13-41).

Confirmation gate

_execute_step memanggil _confirm_tool sebelum tool dijalankan dan menandai step selesai bila permintaan ditolak (core/workflow.py:224-238). Risiko tool diambil dari TOOL_RISK_CLASS dengan nilai default active untuk tool yang tidak terdaftar (core/workflow.py:444-496).

Risikosafe_moderequire_confirmation--yesHasil
passiveapa punapa punapa punlangsung jalan
destructivetrueapa punapa punskip tanpa prompt
destructivefalsetruefalseprompt typer.confirm
activeapa punfalseapa punlangsung jalan
activeapa puntruetruelangsung jalan
activeapa puntruefalseprompt typer.confirm

Bawaan config adalah safe_mode: true dan require_confirmation: true (config/guardian.yaml:72-86).

⚠️ Tool destructive diblokir di safe_mode meskipun --yes diberikan; satu-satunya jalan adalah mengubah pentest.safe_mode menjadi false (core/workflow.py:444-496).

Bila prompt tidak bisa dijalankan, misalnya karena tidak ada TTY, _confirm_tool memilih skip dan menyarankan --yes untuk eksekusi tanpa pengawasan (core/workflow.py:444-496). Perilaku scope di balik gate ini dikunci test: skenario DNS bypass diuji di tests/test_scope_validator.py:59-95 dan blokir IP literal di tests/test_scope_validator.py:20-56.

Kredensial dan audit trail

log_tool_execution menulis arguments apa adanya dan result_preview sepanjang 200 karakter pertama ke log (utils/logger.py:133-143). Tool yang menerima kredensial sebagai parameter wajib memask sendiri: tools/kerbrute.py:59 menulis "password": "***" dan tools/crackmapexec.py:76 menulis "secret": "***".

LokasiPerlakuan kredensial
configapi_key: null, nilai diambil dari environment variable (config/guardian.yaml:10-17)
guardian initPrompt.ask(..., password=True) lalu ditulis ke .env (cli/commands/init.py:50-58)
log tooldimask oleh tool itu sendiri dengan *** (tools/kerbrute.py:59)

log_security_event memetakan severity ke level logging: CRITICAL ke critical, HIGH ke error, MEDIUM ke warning, sisanya info (utils/logger.py:145-162). Berkas log utama berotasi pada 10 MB dengan 5 generasi, sehingga plafon sekitar 50 MB (utils/logger.py:16-19).

Perilaku di halaman ini dikunci oleh test; lihat Pengujian dan Evaluasi. Opsi --yes dan alur perintahnya dijelaskan di Referensi Perintah CLI.