CANON_foto_1126 CANON_foto_1126 CANON_foto_1126

(Ne)bezpečnosť umelej inteligencie / 7. časť

0

V rámci moderného softvérového inžinierstva s využitím AI generátorov sa čistý kód (Clean Code) stáva bežným štandardom. Jeho čitateľnosť, modularita, no najmä zrozumiteľnosť názvov premenných a elegantná štruktúra sú dnes základným štandardom, ktorý umožňuje neskoršiu udržiavateľnosť a škálovateľnosť aplikácií. Estetická a syntaktická dokonalosť kódu však môže nebezpečne maskovať jeho hlboké bezpečnostné nedostatky. Vývojári dostávajú dokonale naformátovaný, typovo bezpečný a vizuálne príťažlivý kód a podvedome predpokladajú, že je aj bezpečný. Skúsenosti z praxe a bezpečnostné audity však ukazujú pravý opak. Čistota kódu a bezpečnosť aplikácií sú dve úplne odlišné veci.

{{BANNER|SIMPLE_BANNER_HOMEPAGE_2}

Riziká Clean Code generovaného pomocou AI

Nástroje ako Vercel v0 dokážu počas sekúnd vygenerovať moderné komponenty pomocou frameworkov ako Next.js, React a Tailwind CSS. Vygenerovaný kód pôsobí na prvý pohľad mimoriadne profesionálne, využíva najnovšie štandardy, obsahuje definície TypeScript, sémantické značky a čisté asynchrónne funkcie. Modely AI sú však trénované primárne na štýl, vzorce a funkčnosť používateľského rozhrania, nie na hĺbkové modelovanie (threat modeling) a detekciu hrozieb. Výsledkom je kód, ktorý je ukážkovo čistý, spĺňa zadanie vývojárov, no je architektonicky „naivný“ a otvára dvere mnohým zraniteľnostiam.

Praktický príklad Server Action

Predstavme si situáciu, keď od nástroja Vercel v0 požadujeme vytvoriť formulár na aktualizáciu používateľského profilu. Zadáme prompt: „Vytvor moderný formulár na úpravu používateľského profilu v Next.js pomocou Tailwind CSS. Formulár má obsahovať pole na zmenu používateľského mena, ID používateľa (skryté pole) a textové pole na krátku poznámku. Implementuj to celé pomocou Next.js Server Action s názvom updateUserProfile, ktorá spracuje a aktualizuje údaje v databáze.“ V0 vygeneruje úhľadný komponent prepojený s Next.js Server Action, ktorého kód vyzerá na prvý pohľad bezchybne:

export async function updateUserProfile(
  _previousState: ProfileActionState,
  formData: FormData,
): Promise {
  const result = profileSchema.safeParse({
    userId: formData.get('userId'),
    username: formData.get('username'),
    note: formData.get('note'),
  })
  if (!result.success) {
    return { status: 'error', message: result.error.issues[0]?.message ?? 'Skontrolujte údaje vo formulári.' }
  }
  try {
    const updated = await db
      .update(user)
      .set({ name: result.data.username, updatedAt: new Date() })
      .where(eq(user.id, result.data.userId))
      .returning({ id: user.id })
    if (updated.length === 0) {
      return { status: 'error', message: 'Používateľ sa nenašiel.' }
    }
    await db
      .insert(userProfile)
      .values({ userId: result.data.userId, note: result.data.note, updatedAt: new Date() })
      .onConflictDoUpdate({
        target: userProfile.userId,
        set: { note: result.data.note, updatedAt: new Date() },
      })
    return { status: 'success', message: 'Profil bol úspešne aktualizovaný.' }
  } catch {
    return { status: 'error', message: 'Profil sa nepodarilo uložiť. Skúste to znova.' }
  }
}


Obr. 1 Code mód nástroja Vercel v0 s vygenerovaným nezabezpečeným kódom

V0 splní našu požiadavku a nijakým spôsobom nás nebude vystríhať pred nebezpečnosťou použitia skrytého poľa ID používateľa. Pretože náš prompt explicitne požaduje od v0 možnosť odoslať userId cez formulár, v0 ho tam poslušne vloží, čím vytvorí tzv. IDOR (Insecure Direct Object Reference) zraniteľnosť. Ide o známu bezpečnostnú chybu, teda nezabezpečený priamy odkaz, pri ktorom webová aplikácia môže sprístupniť útočníkovi údaje patriace objektu s podvrhnutým identifikátorom. Bežný používateľ síce toto skryté pole nevidí, sofistikovaný útočník však môže hravo zmeniť hodnotu premennej userId na ID iného používateľa vrátane ID administrátora. Zod validácia iba skontroluje, či formulár nejaké ID obsahuje a či má správny formát. Neoverí však, či prihlásený používateľ, ktorý formulár odoslal, má právo upravovať zadané ID.

 

Ako by mal vyzerať správne zabezpečený kód?

Platí tu „zlaté pravidlo bezpečnosti“, a síce: Nikdy nepreberajme ID používateľov z formulára, ale vždy ich získajme zo serverovej (aktívnej) session. V uvedenom kóde by sme vykonali zmeny na vyznačených miestach takto:

 

V úvode doplníme prevzatie userId z aktívnej session

 const session = await auth()

  if (!session || !session.user?.id) {

    return { status: 'error', message: 'Musíte byť prihlásený.' }

  }

  const currentUserId = session.user.id

 

  const result = profileSchema.safeParse({

    username: formData.get('username'),

    note: formData.get('note'),

  })

Pri klauzule WHERE nepoužijeme userId z formulára, ale ID z aktívnej session

.where(eq(user.id, currentUserId))

Rovnaké ID použijeme aj neskôr pri aktualizácii údajov v databáze

.values({ userId: currentUserId, note: result.data.note, updatedAt: new Date() })

 

Analýza skrytých zraniteľností v Clean Code

Hoci kód vygenerovaný pomocou v0 splnil všetky štandardy čistoty (TypeScript typovanie, prehľadná správa stavu, ošetrenie chýb cez try-catch), je zle zabezpečený. Slepo dôveruje hodnote userId, ktorú preberá z formulára. Toto však nie je chyba v0, toto je chyba vývojára, ktorý zadal prompt. Mnohé moderné AI generátory kódu dokážu odhaliť jeho základné syntaktické chyby, ale IDOR nie je syntaktická chyba, ide o chybu na úrovni programovej logiky a architektúry.

Obr. 2 Preview mód nástroja Vercel v0 s vyznačeným skrytým poľom ID

Aby vývojári predišli tejto pasci, musia zmeniť svoj pohľad na spôsob zadávania promptov. V prvom rade nikdy nesmú dôverovať priamym vstupom z klienta. Identita používateľov sa nikdy nesmie čítať z formulárových údajov (FormData), ale výhradne z overenej a šifrovanej aktívnej serverovej session.

Okrem toho je odporúčané, ba priam nevyhnutné vždy používať parametrizované dopyty a ORM (Object-Relational Mapping), ako napr. Prisma či Drizzle, ktoré automaticky eliminujú SQL Injection. Namiesto reťazcových interpolácií treba v SQL používať pripravené príkazy (prepared statements). Každý riadok kódu vygenerovaný AI nástrojmi typu Vercel v0 sa odporúča skontrolovať automatizovaným bezpečnostným skenerom (SAST – Static Application Security Testing) a navyše vykonať manuálny audit vygenerovaného kódu.

Zobrazit Galériu

Marek Sopko

Všetky autorove články

Pridať komentár

Mohlo by vás zaujímať

Mohlo by vás zaujímať