Blog/Webfejlesztés
Nuxt-alkalmazás megerősítése: CSP, fejlécek és korlátok a Nuxt Security-val
A Nuxt Security modul a gyakorlatban: biztonságos alapértékek, a szigorú mód kompromisszumai, nonce-CSP SSR-ben és SSG-ben, útvonalszabályok.
Balázs Csorba··11 perc olvasás
- Nuxt
- Content Security Policy
- HTTP security headers
- Rate limiting
- Nitro

A lényeg röviden
- A Nuxt Security hasznos alapértelmezett réteg a fejlécekhez és a kérésekhez, de a dokumentált funkciókészlet nem tartalmaz hitelesítést, jogosultságkezelést, SSRF-védelmet és webalkalmazási tűzfalat.
- Az alapértékek a szokásos alkalmazást működőképesen tartják. A szigorú mód más irányelv, ezért a töréseket jelentésmódban javítsa, mielőtt kényszerítené.
- A nonce-CSP szerveroldali renderelést igényel. A statikus buildek build-időben számolt hashokat használnak egy meta-elemben, ezért minden oldaltípust külön tesztelje.
- A beépített sebességkorlátozó alkalmazásszintű lassító. A brute force elleni védelem az infrastruktúrás rétegbe tartozik.
- Jelentésmódban vezesse be, a valódi fejléceket végponttól végpontig tesztelje, és a kivételeket útvonalanként adja meg, ne lazítsa az egész oldalt.
A Nuxt Security egy modul, amely megerősítő réteget ad a Nuxt-alkalmazáshoz. Biztonsági válaszfejléceket állít be, köztük a Content Security Policy (CSP) irányelvet, kérésméret- és gyakoriságkorlátokat ad hozzá, a bemeneteket ellenőrzi a cross-site scripting ellen, kezeli a CORS-t, és eltávolít néhány keretrendszer-nyomot. 2026 októberétől a legújabb kiadás a 2.6.0, amely 2026. május 12-én jelent meg, a modul pedig a Nuxt 3.x és újabb verziókkal, köztük a 4.x-szel működik. Az alapértékek úgy vannak tervezve, hogy a szokásos alkalmazást biztonságban tartsák anélkül, hogy megtörnék. Ez hasznos, de nem a teljes történet: egyes védelmek attól függnek, hogy az oldal szerveren renderelődik-e vagy statikus fájlként készül el, egyesek harmadik féltől származó widgeteket törnek, a sebességkorlátozó pedig kifejezetten nem összetett éles alkalmazásoknak készült.
Ez a cikk a modult működtetési rétegnek tekinti, nem funkciólistának. Elmagyarázza, mit garantálnak az alapértékek és mit változtat a szigorú mód, hogyan különbözik a nonce-alapú CSP a szerveres renderelés és a statikus generálás között, hogyan írhatók felül a szabályok útvonalanként, miért sebességgátló a beépített sebességkorlátozó, és nem szolgáltatásmegtagadás elleni védelem, valamint mikor jobb a kézzel írt Nitro-köztes réteg. Minden szám a modul dokumentációjából vagy forráskódjából származik, az október 2026-os állapot szerint ellenőrizve.
Mit fed le a Nuxt Security, és mit hagy ki?
A Nuxt Security a HTTP-réteget fedi le: biztonsági válaszfejlécek, köztük a CSP a statikus oldalakhoz, kérésméret- és sebességkorlátok, XSS-ellenőrzés GET és POST kéréseknél, CORS, az X-Powered-By fejléc elrejtése és a konzolnaplózó segédfüggvények eltávolítása. Az engedélyezett HTTP-metódusok, az alap hitelesítés és a CSRF-védelem opcionális. A modul README-je ezt sorolja fel funkciókészletként, és a Nuxt 3.x-et és az újabbakat, köztük a 4.x-et nevezi meg támogatottként.
A hiányosságok ugyanolyan fontosak, mint a lista. A dokumentált funkciókészlet nem tartalmaz SSRF-védelmet, hitelesítést vagy jogosultságkezelést, és webalkalmazási tűzfalat sem. Ha az alkalmazás a felhasználók által megadott címeket kér le, vagy bejelentkezés mögött privát adatokat szolgál ki, a modul ezt a munkát nem végzi el Ön helyett. Az XSS-validátort a bejövő kérésadatok egyik szűrőjeként kezelje, amely a js-xss könyvtárra épül. A kimenet escape-elése a komponensekben az Ön felelőssége marad.
Mit garantálnak az alapértékek, és mit változtat a szigorú mód?
Az alapértékek olyan irányelvet adnak, amely egy szokásos alkalmazással működik. A szkriptek a saját originből és https: forrásokból jöhetnek, a stílusok használhatnak inline CSS-t, a szkriptirányelv pedig a nonce-t és a 'strict-dynamic' értéket nevezi meg. A nonce-t értő böngészők figyelmen kívül hagyják az unsafe-inline tartalékot, ha van nonce. A további alapértékek: nonce: true, sri: true, éles környezetben credentialless Cross-Origin-Embedder-Policy, 15 552 000 másodperces max-age-ű HSTS includeSubdomains-szal, no-referrer referrer-policy és SAMEORIGIN X-Frame-Options. A sebességkorlátok, a kéréseméret-korlátok és a CORS be vannak kapcsolva, a basic auth és a CSRF ki.
A szigorú mód más irányelv, nem ugyanazon értékek szigorúbb változata. A strict: true a default-src értékét 'none'-ra állítja, eltávolítja az unsafe-inline értéket a szkriptekből, a stílusokat csak nonce-szal engedi, a keretek és a worker-ek forrását 'self'-re korlátozza, a COEP-t require-corp-ra állítja, a HSTS-t egy évre emeli preload-dal, az X-Frame-Options értékét DENY-re változtatja, és alapértelmezés szerint megtagad minden Permissions Policy funkciót. A dokumentáció fokozatos utat ír le: kezdje az alapértékekkel, javítsa a töréseket, majd váltson szigorú módra.
| Funkció | Alapérték | Útvonalanként | Az első buktató |
|---|---|---|---|
| CSP SSR-hez | nonce és strict-dynamic | igen, a security alatt | statikus buildnél a nonce figyelmen kívül marad |
| CSP SSG-hez | build-időben számolt hashek meta-elemben | útvonalanként nincs dokumentálva | az inline kódot hashelni kell |
| Sebességkorlátozó | 150 requests per 300,000 ms per IP | igen, a security alatt | az LRU-állapot minden folyamatban külön él |
| Kérésméret | 2,000,000 bytes, 8,000,000 for uploads | igen, a security alatt | 413 a túl nagy kéréseknél |
| XSS-validátor | GET és POST esetén aktív | igen, a security alatt | 400, ha veszélyes kód szerepel |
| CORS | az origin a szerver URL-je | igen, a security alatt | a useRegExp mintaként kezeli az originöket |
| CSRF | kikapcsolva | kivétel a csurf: false beállítással | nuxt-csurf-on keresztül kapcsolható be |
| Subresource Integrity | bekapcsolva, build-időben számolt hashek | útvonalanként nincs dokumentálva | a hoszt utólagos módosítása eltöri a hasheket |
| COEP | credentialless éles környezetben | igen, a security alatt | a felugró bejelentkezéseket lazítani kell |
Hogyan működik a nonce-CSP SSR, SSG és hibrid alkalmazásokban?
Szerveres renderelésnél a modul válaszonként nonce-t hoz létre, beleteszi a CSP-fejlécbe, és hozzáadja a renderelt HTML script-, link- és style-elemeihez. Statikus generálásnál ez nem működhet, mert egy fájl minden látogatót kiszolgál. A modul build-időben számolja a hasheket, és az irányelvet <meta http-equiv> elemben szállítja. A dokumentáció egyértelmű: a nonce opció és a 'nonce-{{nonce}}' helyőrzők figyelmen kívül maradnak, ha SSG-re nuxi generate paranccsal épít.
Az átírás a renderelési folyamatban történik, ezért az alkalmazáskódnak ritkán kell ismernie a nonce-okat. A modul az inline elemeket és a külső erőforrásokat is feldolgozza. Ha a saját kódjának nonce-ra van szüksége, például egy általa létrehozott inline szkripthez, a useNonce() visszaadja az értéket a szerveres kontextusból:
<script setup lang="ts">
const nonce = useNonce() // set during SSR; empty on a static build
useHead({
script: [{ children: 'window.dataLayer = window.dataLayer || []', nonce }],
})
</script>A statikus buildben nincs kérés, ezért ott az érték üres, és az előre renderelt oldalon futó inline kódhoz hash kell. A hibrid eset okozza a legtöbb zavart. A hibrid alkalmazás szerveresen renderelt és előre renderelt útvonalakat vegyít, így a két választípus eltérő irányelvet hordozhat, és az egyik útvonal fejlécellenőrzése a másikról semmit sem mond. Mindkét oldaltípust ellenőrizze.
Három törés ismétlődik. A harmadik féltől származó kód, amely futás közben hoz létre script-elemeket, gyakran olyan elemeket termel, amelyeket az irányelv nem ismer. A modul GYIK-je szerint a <NuxtImg> és a <NuxtPicture> inline hibakezelő szkriptjei ütköznek a csak nonce-os irányelvvel SSR-ben. A hosztoló szolgáltatók, amelyek a build után utólag módosítják a csomagot, érvénytelenítik a subresource integrity hasheket.
Hogyan erősítsen meg egyes útvonalakat?
A modult útvonalanként írja felül a routeRules alatt, a security mezővel. Minden köztes réteg és fejléc itt beállítható, így egy költséges API-útvonalnak szigorúbb sebességkorlátja lehet, mint a marketingoldalaknak, külön szerver nélkül.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-security'],
security: {
strict: true,
contentSecurityPolicyReportOnly: true,
rateLimiter: { tokensPerInterval: 150, interval: 300000 },
},
routeRules: {
// illustrative values: a tighter limit for one expensive endpoint
'/api/generate/**': { security: { rateLimiter: { tokensPerInterval: 30, interval: 60000 } } },
},
})Két részlet szokott megbotlasztani az embereket. Először: a biztonsági fejlécek csak a security mezőbe tartoznak. A dokumentáció nem javasolja, hogy a natív routeRules.headers opcióval állítsa be őket, és ha mindkettő ugyanazt a fejlécet definiálja, a security mező nyer. Másodszor: egyes értékeknek egyáltalán nem szabad a repóban lakniuk. A nuxt-security:routeRules Nitro-hook a szerver újraindításakor fut, és az egész szabályhalmazt módosíthatja, ami jól illik egy titokkezelőből lekért, engedélyezett connect-src originök listájához. Build-időbeli párja, a nuxt-security:prerenderedHeaders a statikus hostingot fedi le.
Itt nő a irányelv egy LLM-funkciókat tartalmazó alkalmazásban. A streamelt válaszoknak az originjük kell a connect-src alá, és minden szállítói widgetnek kell egy bejegyzés a script-src alá. Az útvonalankénti security mező minden kivételt ahhoz az útvonalhoz tart, amelyiknek szüksége van rá, ahelyett hogy az egész oldalt lazítaná. Ugyanezt a streamelő beállítást a Nuxt LLM streamelésről szóló cikk írja le, és pontosan az ilyen végpontoknál szokott becsúszni a túl tág kivétel.
Mit védenek valójában a méret- és gyakoriságkorlátok?
Lelassítják azt az egy klienst, amely túl sok kérést vagy túl nagy törzset küld egy futó példánynak. Az alapérték IP-nként 150 kérést enged 300 000 ms-os (öt perces) ablakon belül, LRU-gyorsítótárban követve, a limit feletti kérésekre pedig 429 Too Many Requests válasz jár. A kérésméret-korlátozó GET, POST és DELETE kéréseknél 2 000 000 bájtot érvényesít, a nagyobbakra 413 Payload Too Large választ ad; a feltöltési útvonalak 8 000 000 bájtot kapnak.
A modul dokumentációja megnevezi ennek a megközelítésnek a határát. A beépített sebességkorlátozó „nem alkalmas összetett éles alkalmazásokhoz”, egyszerűbb alkalmazásoknak készült a brute force kezelésére, éles környezetben pedig „az infrastruktúra rétegén működő megoldásokat kell használni, nem az alkalmazás rétegén”. Ezt munkaszabályként értelmezem: a beépített korlátozó sebességgátló, nem szolgáltatásmegtagadás elleni védelem. Egy CDN, terheléselosztó vagy webalkalmazási tűzfal a Node-folyamat előtt látja a forgalmat, és olyan költséggel utasíthatja el, amelyet az alkalmazás soha nem fizet meg. Ez a korlátozó az a vékony alkalmazásszintű védelem, amelyet a denial-of-wallet cikk egy drága végpontra ír le.
Ebből két gyakorlati pont következik. Az LRU-alapérték egyetlen folyamaton belül él, ezért több példány esetén, vagy olyan szerver nélküli függvényeknél, amelyek nem osztoznak memórián, minden példány külön számol, és a tényleges korlát megszorzódik. Ez a modell általam olvasott értelmezése, nem idézett állítás, és egy kétpéldányos teszt megerősítheti. Az unstorage-meghajtó megoszott tárolóba helyezheti a számlálókat, például a dokumentáció által bemutatott vercelKv meghajtóval. Másodszor: proxy mögött a kliens címe a proxy címe lesz, hacsak nem állítja be az ipHeader opciót, például cf-connecting-ip-re. Csak akkor állítsa be, ha az alkalmazás kizárólag ezen a proxyn keresztül érhető el, különben a kliens maga is küldhet ilyen fejlécet.
Hogyan viselkedik a CORS és a CSRF az API-útvonalakon?
A CORS globálisan be van kapcsolva, és alapértelmezés szerint a saját szerver-URL-jét engedi originként. A CSRF-védelem ki van kapcsolva, amíg be nem kapcsolja; a nuxt-csurf integrációjából származik. A CORS-kezelő a H3 beépített CORS-funkcióira épül. Beállíthatók a methods, allowHeaders, exposeHeaders, credentials és maxAge opciók, a preflight válasz állapotkódja alapértelmezés szerint 204. A useRegExp bekapcsolásakor minden origin-karakterlánc kis- és nagybetű-érzéketlen reguláris kifejezéssé alakul. Ez kényelmes az előnézeti telepítéseknél, és veszélyes, ha egy minta túl laza, ezért ahol lehet, tartsa a listát kifejezettnek. A CORS-kezelő dokumentációja mutatja a teljes opciólistát.
A CSRF választható. Állítsa be a csrf: true értéket, az egyes útvonalakat a külön csurf: false útvonalszabállyal mentesítse, a kliensoldalon pedig használja az automatikusan importált useCsrfFetch és useCsrf() összetevőket. A dokumentáció azt is mutatja, hogyan küldhető a token csrf-token fejlécben egy tRPC-kliensnek. A basic auth szintén választható. A modul a hitelesítő adatait a runtimeConfig.private.basicAuth alá helyezi, így azok nem kerülnek a kliens csomagjába. Ez a megfelelő hely, de így is egy közös jelszóról van szó, ezért nyilvános termék bejelentkezéseként nem használnám.
Hogyan vezesse be és tesztelje a fejlécrétegét?
Vezessen be egy irányelvet jelentésmódban, olvassa a jelentéseket, és csak utána kényszerítse ki. Állítsa be a contentSecurityPolicyReportOnly: true értéket, ekkor a válasz a kényszerítő fejléc helyett a Content-Security-Policy-Report-Only fejlécet hordozza. A CSP-opciók elfogadják a report-uri és a report-to értéket, globálisan és útvonalanként is. A jelentésmódot a 2.6.0 kiadás vezette be, amely azt is megváltoztatta, hogyan számolódnak a CSP-hashek: most a renderelési hookban kapott végleges HTML-ből. Ezeket a kiadási megjegyzéseket olvassa el, mielőtt egy statikus oldalt frissít.
Egy üzemelő oldal egyszeri értékeléséhez a MDN HTTP Observatory gyorsan ellenőrzi a fejléceket. Azt értékeli, amit lát, de nem mondja meg, működnek-e még az oldalai, ezért a böngészős tesztelést egészíti ki, nem helyettesíti. A visszaesést elkapó ellenőrzés egy végpontok közötti teszt állítása. A Playwright Response osztálya hozzáfér a válaszfejlécekhez, így a teszt meghiúsulhat, ha egy telepítés eltávolítja az irányelvet:
import { test, expect } from '@playwright/test'
test('the home page sends the security headers', async ({ page }) => {
const response = await page.goto('/')
const headers = response!.headers()
expect(headers['content-security-policy'] ?? headers['content-security-policy-report-only']).toContain("script-src 'self'")
expect(headers['strict-transport-security']).toContain('max-age=')
})A vizsgálatot futtassa egy szerveresen renderelt és egy előre renderelt oldalon is, mert eltérő irányelvet adnak. Az a Playwright-beállítás, amelyet már a Playwright MCP-n keresztül használok, minden telepítésnél futtathatja, így a fejlécvisszaesés ugyanott jelenik meg, mint egy törött oldal. Ugyanazt a szokást, a döntés előtti mérést alkalmazom a Core Web Vitals cikkben is, csak itt a mérőszám egy válaszfejléc.
Mikor jobb a kézzel írt Nitro-köztes réteg?
A modult akkor használja, ha szeretné, hogy a nonce-átírást, a hashelést és a fejlécbeállításokat karbantartsák Önnek. Kézzel írja a server/middleware réteget, ha minden válasz felett pontos kontrollra van szüksége, és nincs kedve konvenciókat kerülgetni. A modul olyan dolgokat ad, amelyeket nehéz jól megépíteni. A nonce beillesztése a renderelési folyamatban történik, így eléri a keretrendszer által létrehozott elemeket is. A statikus buildek hasheit a végleges HTML-ből számolja. A fejlécbeállítások erőforrástípusonként eltérnek: a HTML teljes irányelvet kap, más eszközök szűkebb készletet, az útvonalankénti szabályok pedig összefésülődnek a globális konfigurációval. Ezeket a részeket nem írnám át.
A kézzel írt köztes réteg máshol nyer. Néhány fejléc és egy kis engedélyezőlista a server/middleware alatt könnyen olvasható, nem igényel modulkonvenciókat és nem ad hozzá függőséget. Ha csak HSTS-re, referrer-policy-ra és keretopciókra van szüksége, ezt a három fejlécet írja meg maga.
A nonce-CSP kézi újraírása a legrosszabb kiindulópont. A nonce-nak el kell érnie minden szkriptet, linket és stílust, amelyet a renderelés kiad, ugyanannak az értéknek meg kell egyeznie a fejlécben, a statikus buildeknek pedig teljesen más mechanizmus kell. A hibák nem egységtesztben jelennek meg, hanem üres oldalként egyetlen böngészőben. Javaslatom: a modult az irányelvre használja, a kivételeket pedig maga írja meg.
Hogyan néz ki egy éles üzembe helyezési ellenőrzőlista?
Mielőtt egy irányelvet kikényszerítene egy éles alkalmazásban, ebben a sorrendben dolgozném fel ezeket a pontokat:
- Futtassa az alapértékeket minden oldaltípuson, és javítsa azt, amit a böngésző konzolja szabálysértésként jelez.
- Kapcsolja be a
contentSecurityPolicyReportOnlyopciótreport-urivagyreport-tovégponttal, és olvassa a jelentéseket egy teljes kiadási cikluson át. - Ellenőrizze, mely útvonalak szerveresen renderelődnek és melyek előre renderelődnek, és nézze meg az elkészült HTML-ben a nonce-t vagy a hashelt meta-elemet.
- Harmadik féltől származó szkripteket
useScript-tel (Nuxt 3.11 vagy újabb) töltsön be, ne kézzel szúrjon be tageket. - A külső képhostokat vegye fel az
img-src, minden API-originöt pedig aconnect-srcalá, az LLM-végpontokat is beleértve. - Ellenőrizze, hogy a hosztoló nem írja-e át a csomagokat a build után, különben az integritási hashek meghiúsulnak.
- A brute force és a forgalmi volumen elleni védelmet a szél rétegbe tegye, a beépített korlátozót pedig második rétegnek tekintse.
- Az eredeti fejléceket végponttól végpontig tesztelő teszttel ellenőrizze egy szerveresen renderelt és egy előre renderelt oldalon.
A modul jó alapértelmezett réteg, a hátralévő munka pedig ugyanaz, mint korábban: tudni, mely szkripteket töltenek be az oldalai, és mely originöket hívja az alkalmazása. Ha látni szeretné, milyen Nuxt-munka áll e cikk mögött, a Vue- és Nuxt-projektjeim jó kiindulópontot adnak.
Források
- Nuxt Security README (main branch)
- Nuxt Security default configuration (src/defaultConfig.ts)
- Nuxt Security docs: Content Security Policy
- Nuxt Security docs: rate limiter
- Nuxt Security docs: CORS handler
- Nuxt Security docs: CSRF
- Nuxt Security docs: hooks
- Nuxt Security docs: security headers
- Nuxt Security docs: improving security
- Nuxt Security release v2.6.0 (12 May 2026)
- MDN: HTTP Observatory
- Playwright: Response class
Gyakori kérdések
Védi a Nuxt Security az SSRF ellen?
A dokumentált funkciókészlet nem tartalmaz SSRF-védelmet, a modul hitelesítést vagy jogosultságkezelést sem ad hozzá. A kimenő címeket a saját kódjában ellenőrizze, és mielőtt egy konkrét verzióra vonatkozó állításra támaszkodik, nézze át a kiadási megjegyzéseket.
Elég a Nuxt Security alapértelmezett CSP-je éles környezetben?
Az alapértékeket úgy tervezték, hogy ne törjenek egy szokásos alkalmazást, de ezek kiindulópontok. Tartalékként megtartják az unsafe-inline értéket, és a szkriptekhez https: forrásokat engedélyeznek. Ellenőrizze az irányelvet a kész buildben, javítsa a töréseket, majd váltson szigorú módra vagy szigorúbb, saját irányelvre.
Miért nem működik a nonce-CSP statikus oldalon?
A nonce válaszonként jön létre, a statikus fájl viszont minden látogatónak ugyanaz. A Nuxt Security figyelmen kívül hagyja a nonce opciót a nuxi generate futtatásakor, helyette build-időben számolt hasheket használ, amelyeket meta-elemben szállít.
Megállítja a sebességkorlátozó a szolgáltatásmegtagadásos támadásokat?
Nem. A dokumentáció egyszerűbb alkalmazásokhoz javasolja, a brute force elleni védelemhez pedig infrastruktúrás megoldásokat ajánl. A forgalmi volumen kezelésére tegyen eléje CDN-t, terheléselosztót vagy webalkalmazási tűzfalat, az alkalmazásszintű korlátot pedig tartsa második rétegként.
Hogyan ellenőrizhetem, hogy a fejlécek egy telepítés után is megvannak?
Írjon egy végpontok közötti tesztet, amely egy szerveroldalon renderelt és egy előre renderelt oldal válaszfejléceit olvassa, és meghiúsul, ha a Content-Security-Policy vagy a Strict-Transport-Security fejléc hiányzik.