\section{HTTP Cookies} \begin{frame}[shrink=15]{Mi az a Cookie?} \begin{block}{HTTP Cookie definíció} Kis méretű adat (max 4KB), amit szerver küld böngészőnek, automatikusan visszaküldődik. \end{block} \begin{itemize} \item Session kezelés, preferenciák, tracking \item Beállítható élettartam \end{itemize} \end{frame} \begin{frame}[fragile,shrink=15]{Cookie beállítása Express-ben} \begin{verbatim} // Egyszerű cookie res.cookie('session', 'abc123'); // Opciókkal res.cookie('user', 'john', { maxAge: 900000, // 15 perc ms-ban httpOnly: true, // JS nem fér hozzá secure: true, // csak HTTPS sameSite: 'strict' // CSRF védelem }); \end{verbatim} \end{frame} \begin{frame}[shrink=15]{Cookie attribútumok} \begin{small} \begin{itemize} \item \textbf{Domain}: \texttt{.example.com} - subdomain-ek \item \textbf{Path}: \texttt{/api} - URL path scope \item \textbf{Expires/Max-Age}: Lejárat ideje \item \textbf{HttpOnly}: JS hozzáférés blokkolása (XSS védelem) \item \textbf{Secure}: Csak HTTPS-en küldve \item \textbf{SameSite}: \texttt{Strict|Lax|None} - CSRF védelem \end{itemize} \end{small} \end{frame} \begin{frame}[shrink=15]{Cookie típusok} \begin{enumerate} \item \textbf{Session Cookie}: Nincs Expires/Max-Age, böngésző bezáráskor törlődik \item \textbf{Persistent Cookie}: Van lejárati idő, túléli böngésző bezárást \item \textbf{Secure Cookie}: Csak HTTPS-en \item \textbf{HttpOnly Cookie}: JS nem fér hozzá \item \textbf{SameSite Cookie}: CSRF támadás ellen \item \textbf{Third-party Cookie}: Más domain-ről \end{enumerate} \end{frame} \begin{frame}[shrink=15]{SameSite Cookie attribútum} \begin{description} \item[Strict] Cookie csak saját site kérésekkel küldve. Legjobb CSRF védelem. \item[Lax] GET kéréseknél küldi cross-site. Default modern böngészőkben. \item[None] Mindig küldi (Secure kötelező). Third-party használathoz. \end{description} \begin{alertblock}{CSRF véd} SameSite=Strict/Lax megakadályozza cross-site támadásokat. \end{alertblock} \end{frame} \begin{frame}[shrink=15]{Cookie vs localStorage vs sessionStorage} \begin{tiny} \begin{tabular}{|l|c|c|c|} \hline & \textbf{Cookie} & \textbf{localStorage} & \textbf{sessionStorage} \\ \hline Kapacitás & 4KB & 5-10MB & 5-10MB \\ Lejárat & Beállítható & Nincs & Tab bezárás \\ HTTP-ben & Igen & Nem & Nem \\ XSS véd & HttpOnly & Nem & Nem \\ \hline \end{tabular} \end{tiny} \begin{exampleblock}{Ajánlás} \textbf{Érzékeny:} HttpOnly Cookie, \textbf{Publikus:} localStorage \end{exampleblock} \end{frame} \begin{frame}[fragile,shrink=15]{Cookie olvasása Express-ben} \begin{verbatim} const cookieParser = require('cookie-parser'); app.use(cookieParser()); app.get('/profile', (req, res) => { const sessionId = req.cookies.session; res.json({ sessionId }); }); \end{verbatim} \end{frame} \begin{frame}[fragile,shrink=15]{Cookie törlése} \begin{verbatim} app.post('/logout', (req, res) => { res.clearCookie('session'); res.json({ message: 'Logged out' }); }); \end{verbatim} \end{frame} \begin{frame}[fragile,shrink=15]{Signed Cookies} \begin{block}{Integritás védelem} HMAC aláírással ellátott cookie, megakadályozza manipulációt. \end{block} \begin{verbatim} app.use(cookieParser('secret-key')); app.get('/set', (req, res) => { res.cookie('userId', '123', { signed: true }); res.send('OK'); }); app.get('/get', (req, res) => { const id = req.signedCookies.userId; res.json({ id }); }); \end{verbatim} \end{frame} \begin{frame}[shrink=15]{XSS vs CSRF} \begin{columns} \begin{column}{0.48\textwidth} \textbf{XSS (Cross-Site Scripting)} \begin{itemize} \item JS injection támadás \item Cookie lopás \texttt{document.cookie} \item \textbf{Védelem:} HttpOnly cookie \end{itemize} \end{column} \begin{column}{0.48\textwidth} \textbf{CSRF (Cross-Site Request Forgery)} \begin{itemize} \item Hamis kérés küldés \item Cookie auto-send kihasználása \item \textbf{Védelem:} SameSite, CSRF token \end{itemize} \end{column} \end{columns} \end{frame} \begin{frame}[fragile,shrink=20]{CSRF Token védelem} \begin{verbatim} const csrf = require('csurf'); app.use(csrf({ cookie: true })); app.get('/form', (req, res) => { res.render('form', { csrfToken: req.csrfToken() }); }); app.post('/submit', (req, res) => { res.send('Valid!'); }); \end{verbatim} \end{frame} \begin{frame}[shrink=15]{Cookie Security Best Practices} \begin{enumerate} \item \textbf{HttpOnly}: Érzékeny cookie-khoz mindig \item \textbf{Secure}: Éles környezetben HTTPS-el \item \textbf{SameSite}: Strict vagy Lax CSRF ellen \item \textbf{Short expiration}: Session token-ekhez rövid lejárat \item \textbf{Domain scope}: Csak szükséges domain-hez \item \textbf{Signed cookies}: Integritás ellenőrzéshez \end{enumerate} \end{frame}