Biztonság és adatvédelem
A Lexo védelme rétegzett: a belépéstől a widgeten és az AI-on át a kimenő kérésekig.
Ez az oldal leírja, milyen védelmek működnek a Lexóban, és hol vannak a határaik. Egy réteg sem a másikra támaszkodik: ha az egyik hibázna, a többi akkor is véd.
Belépés és jogosultságok
A bejelentkezést a Clerk kezeli. A dashboard összes API-útvonala érvényes Clerk-munkamenetet kér; enélkül a kérés 401-es hibát kap.
A csapattagok szerepkört kapnak (Tulajdonos, Adminisztrátor, Ügynök, Megtekintő), és a szerver minden kérésnél ellenőrzi, hogy a szerepkör megengedi-e a műveletet. Az, hogy egy gomb nem látszik a felületen, csak kényelmi kérdés: a tényleges döntés a szerveren születik. A szerepkörök részletei: Ügynökségi modell.
Adatbázis és elkülönítés
Az adatok Supabase (PostgreSQL) adatbázisban vannak. A Row Level Security (RLS) tiltja a nyilvános kulccsal történő közvetlen adatbázis-hozzáférést: a böngészőből senki nem tudja közvetlenül lekérdezni a chatbotok, beszélgetések vagy szervezetek tábláit.
A szervezetek közötti elkülönítést minden API-útvonal szerveroldali jogosultság-ellenőrzése biztosítja: egy chatbotot csak az a felhasználó érhet el, akinek a szervezetéhez tartozik, és akinek a szerepköre az adott műveletet megengedi.
A widget védelme
A widget nyilvános, belépés nélkül működik, ezért külön védelmet kap:
- Domainellenőrzés: a widget API csak a chatbothoz megadott weboldalról és engedélyezett domainekről érkező kéréseket szolgálja ki.
- Beágyazási szabály chatbotonként: ha a chatbotnak meg van adva a weboldala, a widget oldalát a böngésző csak a chatbot saját domainjein engedi beágyazni (
frame-ancestors). Így ha valaki kimásolja a chatbot azonosítóját, a saját oldalán nem tudja futtatni. - Csak iframe-ben: ha a widget oldalát valaki közvetlenül nyitja meg a böngészőben, 403-as oldalt kap.
- Sebességkorlát: a widget kéréseit percenkénti, óránkénti és napi korlát fogja, chatbotonként és IP-címenként, Redisben számolva.
- Napi tokenkeret chatbotonként: ha egy chatbot elérte a napi AI-keretét, aznap nem indít több AI-hívást. Ez a fiók havi keretén felül véd a hirtelen túlhasználat ellen.
- Üzenethossz: egy látogatói üzenetből legfeljebb 2000 karakter jut el az AI-hoz.
Prompt injekció elleni védelem
A chatbotnak küldött üzeneteket egy szűrő vizsgálja, mielőtt az AI-hoz kerülnek. Az ismert mintákat kivágja az üzenetből, a többi részét változatlanul továbbítja:
- utasítás-felülírás („ignore all previous instructions”, „forget your rules”),
- szerepmanipuláció („you are now a…”, „pretend to be”, „act as”),
- a rendszerprompt kikérése („show me your system prompt”),
- elválasztó jelek (
[INST],<system>,### system), - magyar változatok („hagyd figyelmen kívül”, „felejtsd el az előző…”).
Az érintett üzenetekről a rendszer naplóbejegyzést készít.
Műveletek és rendelések
- Író egyedi akciók: soha nem futnak le a látogató kifejezett „igen” válasza nélkül. A függő műveletet a szerver tárolja, nem a böngésző, így a látogató nem tudja kicserélni sem az akciót, sem a paramétereit. Részletek: Egyedi akciók.
- Rendelés állapota: a chatbot csak akkor mond bármit egy rendelésről, ha a látogató a rendelésszámot és a rendeléshez használt e-mail címet is megadja, és a kettő egyezik. A lekérdezések számát IP-címenként korlátozza, a sikertelen próbálkozásokat pedig e-mail címenként, rendelésszámonként és chatbotonként is számolja. Részletek: Rendelés állapota.
Kimenő kérések (SSRF)
Ahol a Lexo szervere egy általad megadott címet hív meg (egyedi akciók, az időpontfoglalás Google Táblázat-címe), ott a rendszer nem engedi, hogy a kérés belső hálózatra menjen. Tiltott:
localhost,*.local,*.internal- loopback és „ez a hálózat” (
127.0.0.0/8,0.0.0.0/8) - privát tartományok (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16) - link-local, köztük a felhős metaadat-végpontok (
169.254.0.0/16) - szolgáltatói NAT (
100.64.0.0/10), teszthálózat (198.18.0.0/15), multicast és fenntartott címek (224.0.0.0felett) - IPv6: loopback (
::1),::, egyedi helyi (fc00::/7), link-local (fe80::/10), 6to4 (2002::/16), valamint az IPv6-ba csomagolt IPv4-címek (::ffff:…,64:ff9b::…), amelyeket a bennük lévő IPv4-cím alapján ítél meg
Nem csak a megadott nevet nézi: feloldja a domaint, és minden kapott IP-címet ellenőriz, majd a kapcsolódás pillanatában is azt a címet vizsgálja, amelyre ténylegesen csatlakozik. Így egy DNS-trükk (először nyilvános, aztán belső címet visszaadó névszerver) sem jut át. Átirányítást nem követ, a teljes válasznak időkorláton belül kell megérkeznie, és a válasz mérete korlátos.
Más kimenő kéréseknél (például a linkelőnézetnél) a rendszer a megadott hosztnevet szűri a fenti lista alapján, névfeloldás nélkül.
Titkos adatok tárolása
Ezeket a hozzáférési adatokat a Lexo AES-256-GCM titkosítással tárolja az adatbázisban:
- a webshop-kapcsolat hozzáférési adatai (rendelés-lekérdezés),
- a saját e-mail küldéshez megadott SMTP-jelszó,
- az időpontfoglalás Google Táblázat-címe.
Az egyedi akciók hitelesítő adatait (API kulcs, jelszó, fejlécek) a Lexo csak szerveroldalon használja a kéréshez; a látogató böngészőjébe és az AI-hoz nem jutnak el.
Webhook aláírás
Ha egy webhooknak van titkos kulcsa (új webhooknál ez az alapbeállítás), minden kérés X-Webhook-Signature fejlécében ott a törzs HMAC-SHA256 aláírása. A fogadó végpont ezzel ellenőrizheti, hogy a kérés tőlünk jött, és útközben nem módosult. Részletek és ellenőrző kód: Webhookok.
Aláírt linkek az e-mailekben
A leiratkozó link és az időpont-lemondó link aláírt tokent tartalmaz, ezért nem lehet kitalálni vagy másik fiókra, másik foglalásra átírni. A link megnyitása önmagában nem csinál semmit: az oldalon egy gombot kell megnyomni, amely POST kérést küld. Így egy levelezőprogram vagy vírusszűrő, amely előre megnyitja a linkeket, nem iratkoztat le és nem mond le időpontot véletlenül.
Böngészővédelem és hibafigyelés
- A dashboardot és a többi oldalt más oldal nem ágyazhatja be (
X-Frame-Options: SAMEORIGIN,frame-ancestors 'self'), ami a clickjacking ellen véd. - További fejlécek:
X-Content-Type-Options: nosniff,Referrer-Policy: strict-origin-when-cross-origin, és egyPermissions-Policy, amely tiltja a kamerát, a helymeghatározást, a fizetési és USB-hozzáférést (a mikrofon csak a saját oldalunkon, a hangbevitelhez engedélyezett). - A hibákat a Sentry gyűjti, az EU-s régiójában. Személyes adatot nem küldünk neki: nincs felhasználói azonosító, süti, kéréstörzs (a látogató üzenete), és nincs AI-prompt vagy -válasz sem.
Adatvédelem
- Látogatói adatok: a beszélgetések a látogató nevének vagy e-mail címének ismerete nélkül is működnek. Személyes adat akkor kerül tárolásra, ha a látogató megadja: a lead űrlapon, beszélgetés közben (ha e-mail címet vagy telefonszámot ír, a chatbot leadként rögzíti), időpontfoglaláskor (név, e-mail, telefonszám, megjegyzés), vagy ha élő átadást, jegyet kér. A beszélgetések szövegét is tároljuk, hogy az Előzmények oldalon visszanézhesd őket.
- Rendelés-lekérdezés: a webshopból lekért rendelésadatot a Lexo nem menti külön. A chatbot válasza a beszélgetés része lesz, mint bármely más üzenet. A korlátozáshoz használt számlálók az e-mail címet és a rendelésszámot csak hash-elve tárolják, legfeljebb egy óráig.
- Törlés: egy chatbot törlésekor a tudásbázisa a vektoros adatbázisból is törlődik, és vele együtt törlődnek a beszélgetései, leadjei és időpontjai is.