@adagursoy; proje güzel fakat bir kaç noktada dikkatimi çeken birşey oldu olumlu olumsuz yorum olarak ben ikisinide tercih ediyorum olumlu tarafı güzel fikir güzel çalışma olumsuz tarafa gelirsek
backend/app.py dosyasına bir göz gezdirdim VNC açığı tespit ettim kritiklik seviyesi yüksek çünkü dış erişim
POST /api/auth/login (viewer hesabı)
burda jwt alır GET /api/vms (Authorization: Bearer JWT) gibi require_role yok sadece require_auth geldigi için wss://host:8006/ws/vnc/<BAŞKA_VM_UUID>?token=<JWT> gibi oluşturup vnc_ws_middleware sızıntı yapar ve decode_token rahatlıkla geçer çünkü vm yetki kontrolu yok vm_id = libvirt içerdesin
fonksiyon _vnc_ws_middleware bu
const wsProto = (location.protocol === "https:") ? "wss" : "ws";
const wsUrl = `${wsProto}://${location.host}/ws/vnc/${_vmId}?token=${encodeURIComponent(_token)}`;
sunucu asla bunu sorgulamadan kabul ediyor

/vnc_console/aaaaaaaa-bbbb gibi
decode_token(token) imza ve süre tamamsa geç identity kullanıcı adı sorulmuyor vm_id geliyor fakat kimin oldugu sorulmuyor geçerli JWT + geçerli vm_id = o VMin konsolu başka kullanıcıya ait olsa da aynı

vm uid /api/vms ile yetki kontrol edilmeden alınıyor herhangi UUID ile VNC portu öğrenilebilir const wsUrl = `${wsProto}://${location.host}/ws/vnc/${_vmId}?token=${encodeURIComponent(_token)}`; yani doğru kontrol bir endpointte var asıl vnc tünelinde yok

POST https://192.168.1.10:8006/api/auth/login
Content-Type: application/json
{"username": "izleyici", "password": "Izleyici123!"}
Yanıt örneği:
{"status": "ok", "token": "eyJhbGciOiJIUzI1NiIs...", "username": "izleyici"}
Tüm VM UUID’leri
GET https://192.168.1.10:8006/api/vms
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
örnek:
{
"status": "ok",
"vms": [
{"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "musteri-db", "state": "running"},
{"id": "f9e8d7c6-b5a4-3210-fedc-ba0987654321", "name": "ic-erp", "state": "running"}
]
}
örnek verdigim izleyici bu VMlere sahip değil yine de listelenir
başkasının vmsine VNC
tarayıcıda veya wscat ile
wss://192.168.1.10:8006/ws/vnc/a1b2c3d4-e5f6-7890-abcd-ef1234567890?token=eyJhbGciOiJIUzI1NiIs...
veya UI:
https://192.168.1.10:8006/vnc_consol...d-ef1234567890
(localStorage’da oxware_token = izleyici JWT ise sayfa açılır ve WS bağlanır)

kısaca rol fark etmiyor tek şart geçerli JWT anahtar kelime JWT
geçerli JWTsi olan her kullanıcı URLdeki herhangi bir vm_id ile /ws/vnc/<vm_id> üzerinden o sanal makinenin vnc oturumuna tam erişim alır sunucu kullanıcı–VM eşlemesini hiç kontrol etmez

zafiyet no: OMERATI-2026-001
cvss:
9.4/10
önem derecesi KRİTİK

İlgili Kod satırı
    # ── Auth ──
    try:
        with app.app_context():
            from flask_jwt_extended import decode_token
            decode_token(token)
    except Exception as _e:
        log.warning("VNC WS: auth failed vm=%s: %s", vm_id, _e)
        start_response("401 Unauthorized", [("Content-Type", "text/plain")])
        return [b"Unauthorized"]
----
 # ── VNC port from libvirt XML ──
  try:
      import libvirt as _lv_vnc
      ...
      _dom  = _conn.lookupByUUIDString(vm_id)
      ...
      vnc_port = int(_vnc_el.get("port", -1)) if _vnc_el is not None else -1
      ...
  try:
      tcp = _egreen_socket.create_connection(("127.0.0.1", vnc_port), timeout=5)