NextJS
Reading time: 23 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.
Next.js Uygulamasının Genel Mimarisi
Tipik Dosya Yapısı
Standart bir Next.js projesi, yönlendirme, API uç noktaları ve statik varlık yönetimi gibi özelliklerini kolaylaştıran belirli bir dosya ve dizin yapısını takip eder. İşte tipik bir düzen:
my-nextjs-app/
├── node_modules/
├── public/
│ ├── images/
│ │ └── logo.png
│ └── favicon.ico
├── app/
│ ├── api/
│ │ └── hello/
│ │ └── route.ts
│ ├── layout.tsx
│ ├── page.tsx
│ ├── about/
│ │ └── page.tsx
│ ├── dashboard/
│ │ ├── layout.tsx
│ │ └── page.tsx
│ ├── components/
│ │ ├── Header.tsx
│ │ └── Footer.tsx
│ ├── styles/
│ │ ├── globals.css
│ │ └── Home.module.css
│ └── utils/
│ └── api.ts
├── .env.local
├── next.config.js
├── tsconfig.json
├── package.json
├── README.md
└── yarn.lock / package-lock.json
Temel Dizinler ve Dosyalar
- public/: Görseller, fontlar ve diğer dosyalar gibi statik varlıkları barındırır. Buradaki dosyalar kök yol (
/
) üzerinden erişilebilir. - app/: Uygulamanızın sayfaları, düzenleri, bileşenleri ve API yolları için merkezi dizin. App Router paradigmasını benimser, gelişmiş yönlendirme özellikleri ve sunucu-müşteri bileşen ayrımı sağlar.
- app/layout.tsx: Uygulamanız için kök düzeni tanımlar, tüm sayfaları sarar ve başlıklar, alt bilgiler ve navigasyon çubukları gibi tutarlı UI öğeleri sağlar.
- app/page.tsx: Kök yol
/
için giriş noktası olarak hizmet eder, ana sayfayı render eder. - app/[route]/page.tsx: Statik ve dinamik yolları yönetir.
app/
içindeki her klasör bir yol segmentini temsil eder ve bu klasörlerdekipage.tsx
, yolun bileşenine karşılık gelir. - app/api/: API yollarını içerir, HTTP isteklerini yöneten sunucusuz işlevler oluşturmanıza olanak tanır. Bu yollar geleneksel
pages/api
dizinini değiştirir. - app/components/: Farklı sayfalar ve düzenler arasında kullanılabilecek yeniden kullanılabilir React bileşenlerini barındırır.
- app/styles/: Bileşen kapsamlı stil için global CSS dosyalarını ve CSS Modüllerini içerir.
- app/utils/: Uygulama genelinde paylaşılabilecek yardımcı modüller, yardımcı işlevler ve diğer UI dışı mantıkları içerir.
- .env.local: Yerel geliştirme ortamına özgü ortam değişkenlerini saklar. Bu değişkenler versiyon kontrolüne dahil edilmez.
- next.config.js: Next.js davranışını özelleştirir, webpack yapılandırmaları, ortam değişkenleri ve güvenlik ayarlarını içerir.
- tsconfig.json: Proje için TypeScript ayarlarını yapılandırır, tür kontrolü ve diğer TypeScript özelliklerini etkinleştirir.
- package.json: Proje bağımlılıklarını, betikleri ve meta verileri yönetir.
- README.md: Proje hakkında belgeler ve bilgiler sağlar, kurulum talimatları, kullanım kılavuzları ve diğer ilgili detayları içerir.
- yarn.lock / package-lock.json: Projenin bağımlılıklarını belirli sürümlere kilitler, farklı ortamlar arasında tutarlı kurulumlar sağlar.
Next.js'de İstemci Tarafı
app
Dizininde Dosya Tabanlı Yönlendirme
app
dizini, en son Next.js sürümlerinde yönlendirmenin temel taşıdır. Yolları tanımlamak için dosya sistemini kullanır, bu da yol yönetimini sezgisel ve ölçeklenebilir hale getirir.
Kök Yol / Yönetimi
Dosya Yapısı:
my-nextjs-app/
├── app/
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Ana Dosyalar:
app/page.tsx
: Kök yoluna/
gelen istekleri işler.app/layout.tsx
: Uygulamanın düzenini tanımlar, tüm sayfaların etrafını sarar.
Uygulama:
tsxCopy code// app/page.tsx
export default function HomePage() {
return (
<div>
<h1>Welcome to the Home Page!</h1>
<p>This is the root route.</p>
</div>
);
}
Açıklama:
- Yol Tanımı:
app
dizininin altındakipage.tsx
dosyası/
yoluna karşılık gelir. - Renderlama: Bu bileşen ana sayfa içeriğini renderlar.
- Düzen Entegrasyonu:
HomePage
bileşeni, başlıklar, alt bilgiler ve diğer ortak öğeleri içerebilenlayout.tsx
ile sarılmıştır.
Diğer Statik Yolları Yönetme
Örnek: /about
Yolu
Dosya Yapısı:
arduinoCopy codemy-nextjs-app/
├── app/
│ ├── about/
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Uygulama:
// app/about/page.tsx
export default function AboutPage() {
return (
<div>
<h1>About Us</h1>
<p>Learn more about our mission and values.</p>
</div>
)
}
Açıklama:
- Yol Tanımı:
about
klasörü içindekipage.tsx
dosyası/about
yoluna karşılık gelir. - Renderlama: Bu bileşen, hakkında sayfası için içeriği renderlar.
Dinamik Yollar
Dinamik yollar, değişken segmentlere sahip yolları yönetmeyi sağlar, uygulamaların ID'ler, slug'lar gibi parametrelere dayalı içerik göstermesine olanak tanır.
Örnek: /posts/[id]
Yolu
Dosya Yapısı:
arduinoCopy codemy-nextjs-app/
├── app/
│ ├── posts/
│ │ └── [id]/
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Uygulama:
tsxCopy code// app/posts/[id]/page.tsx
import { useRouter } from 'next/navigation';
interface PostProps {
params: { id: string };
}
export default function PostPage({ params }: PostProps) {
const { id } = params;
// Fetch post data based on 'id'
return (
<div>
<h1>Post #{id}</h1>
<p>This is the content of post {id}.</p>
</div>
);
}
Açıklama:
- Dinamik Segment:
[id]
, URL'denid
parametresini yakalayan bir dinamik segmenti belirtir. - Parametrelere Erişim:
params
nesnesi, bileşen içinde erişilebilen dinamik parametreleri içerir. - Yol Eşleşmesi:
/posts/*
ile eşleşen herhangi bir yol, örneğin/posts/1
,/posts/abc
vb., bu bileşen tarafından işlenecektir.
İç İçe Yollar
Next.js, dizin yapısını yansıtan hiyerarşik yol yapıları için iç içe yönlendirmeyi destekler.
Örnek: /dashboard/settings/profile
Yolu
Dosya Yapısı:
arduinoCopy codemy-nextjs-app/
├── app/
│ ├── dashboard/
│ │ ├── settings/
│ │ │ └── profile/
│ │ │ └── page.tsx
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Uygulama:
tsxCopy code// app/dashboard/settings/profile/page.tsx
export default function ProfileSettingsPage() {
return (
<div>
<h1>Profile Settings</h1>
<p>Manage your profile information here.</p>
</div>
);
}
Açıklama:
- Derin Yerleştirme:
dashboard/settings/profile/
içindekipage.tsx
dosyası,/dashboard/settings/profile
rotasına karşılık gelir. - Hiyerarşi Yansıması: Dizin yapısı, URL yolunu yansıtarak bakım kolaylığı ve netlik sağlar.
Her Şeye Açık Rotalar
Her şeye açık rotalar, birden fazla iç içe segmenti veya bilinmeyen yolları yönetir, rota yönetiminde esneklik sağlar.
Örnek: /*
Rotası
Dosya Yapısı:
my-nextjs-app/
├── app/
│ ├── [..slug]/
│ │ └── page.tsx
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Uygulama:
// app/[...slug]/page.tsx
interface CatchAllProps {
params: { slug: string[] }
}
export default function CatchAllPage({ params }: CatchAllProps) {
const { slug } = params
const fullPath = `/${slug.join("/")}`
return (
<div>
<h1>Catch-All Route</h1>
<p>You have navigated to: {fullPath}</p>
</div>
)
}
Açıklama:
- Catch-All Segment:
[...slug]
kalan tüm yol segmentlerini bir dizi olarak yakalar. - Kullanım: Kullanıcı tarafından oluşturulan yollar, iç içe geçmiş kategoriler gibi dinamik yönlendirme senaryolarını yönetmek için yararlıdır.
- Yol Eşleştirme:
/anything/here
,/foo/bar/baz
gibi yollar bu bileşen tarafından işlenir.
Potansiyel İstemci Tarafı Güvenlik Açıkları
Next.js güvenli bir temel sağlasa da, yanlış kodlama uygulamaları güvenlik açıkları oluşturabilir. Ana istemci tarafı güvenlik açıkları şunlardır:
Cross-Site Scripting (XSS)
XSS saldırıları, kötü niyetli betiklerin güvenilir web sitelerine enjekte edilmesiyle gerçekleşir. Saldırganlar, kullanıcıların tarayıcılarında betikleri çalıştırarak verileri çalabilir veya kullanıcı adına eylemler gerçekleştirebilir.
Güvenlik Açığı Olan Kod Örneği:
// Dangerous: Injecting user input directly into HTML
function Comment({ userInput }) {
return <div dangerouslySetInnerHTML={{ __html: userInput }} />
}
Neden Zayıf: dangerouslySetInnerHTML
'yi güvenilmeyen girdi ile kullanmak, saldırganların kötü niyetli scriptler enjekte etmesine olanak tanır.
İstemci Tarafı Şablon Enjeksiyonu
Kullanıcı girdilerinin şablonlarda yanlış bir şekilde işlenmesi durumunda meydana gelir, bu da saldırganların şablonları veya ifadeleri enjekte edip çalıştırmasına olanak tanır.
Zayıf Kodu Örneği:
import React from "react"
import ejs from "ejs"
function RenderTemplate({ template, data }) {
const html = ejs.render(template, data)
return <div dangerouslySetInnerHTML={{ __html: html }} />
}
Neden Zayıf: Eğer template
veya data
kötü niyetli içerik içeriyorsa, istenmeyen kodun çalıştırılmasına yol açabilir.
Müşteri Yol Geçişi
Bu, saldırganların istemci tarafı yollarını manipüle ederek istenmeyen eylemler gerçekleştirmesine olanak tanıyan bir zayıflıktır; örneğin, Cross-Site Request Forgery (CSRF). Sunucu tarafı yol geçişinin sunucunun dosya sistemini hedef almasının aksine, CSPT, meşru API isteklerini kötü niyetli uç noktalara yönlendirmek için istemci tarafı mekanizmalarını istismar etmeye odaklanır.
Zayıf Kod Örneği:
Bir Next.js uygulaması, kullanıcıların dosya yüklemesine ve indirmesine olanak tanır. İndirme özelliği istemci tarafında uygulanmıştır; burada kullanıcılar indirmek için dosya yolunu belirtebilir.
// pages/download.js
import { useState } from "react"
export default function DownloadPage() {
const [filePath, setFilePath] = useState("")
const handleDownload = () => {
fetch(`/api/files/${filePath}`)
.then((response) => response.blob())
.then((blob) => {
const url = window.URL.createObjectURL(blob)
const a = document.createElement("a")
a.href = url
a.download = filePath
a.click()
})
}
return (
<div>
<h1>Download File</h1>
<input
type="text"
value={filePath}
onChange={(e) => setFilePath(e.target.value)}
placeholder="Enter file path"
/>
<button onClick={handleDownload}>Download</button>
</div>
)
}
Saldırı Senaryosu
- Saldırganın Amacı:
filePath
'ı manipüle ederek kritik bir dosyayı (örneğin,admin/config.json
) silmek için bir CSRF saldırısı gerçekleştirmek. - CSPT'yi Kötüye Kullanma:
- Kötü Amaçlı Girdi: Saldırgan,
filePath
'ı manipüle edilmiş bir URL oluşturur, örneğin../deleteFile/config.json
. - Sonuçlanan API Çağrısı: İstemci tarafındaki kod,
/api/files/../deleteFile/config.json
adresine bir istek gönderir. - Sunucunun İşlemesi: Sunucu
filePath
'ı doğrulamıyorsa, isteği işler ve hassas dosyaları silme veya ifşa etme riski taşır.
- CSRF'yi Gerçekleştirme:
- Hazırlanan Bağlantı: Saldırgan, kurbanına manipüle edilmiş
filePath
ile indirme isteğini tetikleyen bir bağlantı gönderir veya kötü amaçlı bir script gömülü bir şekilde iletir. - Sonuç: Kurban, farkında olmadan işlemi gerçekleştirir ve yetkisiz dosya erişimi veya silme ile sonuçlanır.
Neden Zayıf
- Girdi Doğrulama Eksikliği: İstemci tarafı, keyfi
filePath
girdilerine izin vererek yol geçişine olanak tanır. - İstemci Girdilerine Güvenme: Sunucu tarafındaki API,
filePath
'ı temizlemeden güvenerek işler. - Potansiyel API Eylemleri: Eğer API uç noktası durum değiştiren eylemler gerçekleştiriyorsa (örneğin, dosyaları silme, değiştirme), CSPT aracılığıyla kötüye kullanılabilir.
Next.js'de Sunucu Tarafı
Sunucu Tarafı Render'ı (SSR)
Sayfalar, her istekte sunucuda render edilir ve kullanıcının tamamen render edilmiş HTML almasını sağlar. Bu durumda, istekleri işlemek için kendi özel sunucunuzu oluşturmalısınız.
Kullanım Durumları:
- Sık sık değişen dinamik içerik.
- Arama motorlarının tamamen render edilmiş sayfayı tarayabilmesi nedeniyle SEO optimizasyonu.
Uygulama:
// pages/index.js
export async function getServerSideProps(context) {
const res = await fetch("https://api.example.com/data")
const data = await res.json()
return { props: { data } }
}
function HomePage({ data }) {
return <div>{data.title}</div>
}
export default HomePage
Statik Site Üretimi (SSG)
Sayfalar, inşa zamanında önceden işlenir, bu da daha hızlı yükleme süreleri ve azaltılmış sunucu yükü sağlar.
Kullanım Durumları:
- Sık sık değişmeyen içerikler.
- Bloglar, belgeler, pazarlama sayfaları.
Uygulama:
// pages/index.js
export async function getStaticProps() {
const res = await fetch("https://api.example.com/data")
const data = await res.json()
return { props: { data }, revalidate: 60 } // Revalidate every 60 seconds
}
function HomePage({ data }) {
return <div>{data.title}</div>
}
export default HomePage
Sunucusuz Fonksiyonlar (API Yolları)
Next.js, sunucusuz fonksiyonlar olarak API uç noktalarının oluşturulmasına olanak tanır. Bu fonksiyonlar, özel bir sunucuya ihtiyaç duymadan talep üzerine çalışır.
Kullanım Durumları:
- Form gönderimlerini işleme.
- Veritabanlarıyla etkileşim.
- Verileri işleme veya üçüncü taraf API'lerle entegrasyon.
Uygulama:
Next.js 13'te app
dizininin tanıtılmasıyla, yönlendirme ve API yönetimi daha esnek ve güçlü hale geldi. Bu modern yaklaşım, dosya tabanlı yönlendirme sistemiyle yakından uyumlu olup, sunucu ve istemci bileşenleri desteği gibi geliştirilmiş yetenekler sunar.
Temel Yönlendirme İşleyici
Dosya Yapısı:
my-nextjs-app/
├── app/
│ └── api/
│ └── hello/
│ └── route.js
├── package.json
└── ...
Uygulama:
// app/api/hello/route.js
export async function POST(request) {
return new Response(JSON.stringify({ message: "Hello from App Router!" }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}
// Client-side fetch to access the API endpoint
fetch("/api/submit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "John Doe" }),
})
.then((res) => res.json())
.then((data) => console.log(data))
Açıklama:
- Konum: API yolları
app/api/
dizini altında yer alır. - Dosya İsimlendirme: Her API uç noktası, içinde bir
route.js
veyaroute.ts
dosyası bulunan kendi klasöründe bulunur. - Dışa Aktarılan Fonksiyonlar: Tek bir varsayılan dışa aktarma yerine, belirli HTTP yöntem fonksiyonları (örneğin,
GET
,POST
) dışa aktarılır. - Yanıt Yönetimi: Yanıtları döndürmek için
Response
yapıcısını kullanın, bu da başlıklar ve durum kodları üzerinde daha fazla kontrol sağlar.
Diğer yollar ve yöntemler nasıl yönetilir:
Belirli HTTP Yöntemlerini Yönetme
Next.js 13+ aynı route.js
veya route.ts
dosyası içinde belirli HTTP yöntemleri için işleyiciler tanımlamanıza olanak tanır, bu da daha net ve düzenli bir kodu teşvik eder.
Örnek:
// app/api/users/[id]/route.js
export async function GET(request, { params }) {
const { id } = params
// Fetch user data based on 'id'
return new Response(JSON.stringify({ userId: id, name: "Jane Doe" }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}
export async function PUT(request, { params }) {
const { id } = params
// Update user data based on 'id'
return new Response(JSON.stringify({ message: `User ${id} updated.` }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}
export async function DELETE(request, { params }) {
const { id } = params
// Delete user based on 'id'
return new Response(JSON.stringify({ message: `User ${id} deleted.` }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}
Açıklama:
- Birden Fazla İhracat: Her HTTP yöntemi (
GET
,PUT
,DELETE
) kendi ihraç edilen fonksiyonuna sahiptir. - Parametreler: İkinci argüman,
params
aracılığıyla rota parametrelerine erişim sağlar. - Gelişmiş Yanıtlar: Yanıt nesneleri üzerinde daha fazla kontrol, hassas başlık ve durum kodu yönetimi sağlar.
Catch-All ve İç İçe Rotalar
Next.js 13+ gelişmiş yönlendirme özelliklerini destekler, bu da catch-all rotaları ve iç içe API rotalarını mümkün kılarak daha dinamik ve ölçeklenebilir API yapıları sağlar.
Catch-All Rota Örneği:
// app/api/[...slug]/route.js
export async function GET(request, { params }) {
const { slug } = params
// Handle dynamic nested routes
return new Response(JSON.stringify({ slug }), {
status: 200,
headers: { "Content-Type": "application/json" },
})
}
Açıklama:
- Sözdizimi:
[...]
tüm iç içe geçmiş yolları yakalayan bir kapsayıcı segmenti belirtir. - Kullanım: Farklı yol derinliklerini veya dinamik segmentleri işlemek için gereken API'ler için yararlıdır.
İç İçe Geçmiş Yollar Örneği:
// app/api/posts/[postId]/comments/[commentId]/route.js
export async function GET(request, { params }) {
const { postId, commentId } = params
// Fetch specific comment for a post
return new Response(
JSON.stringify({ postId, commentId, comment: "Great post!" }),
{
status: 200,
headers: { "Content-Type": "application/json" },
}
)
}
Açıklama:
- Derin Yerleştirme: Kaynak ilişkilerini yansıtan hiyerarşik API yapıları için olanak tanır.
- Parametre Erişimi:
params
nesnesi aracılığıyla birden fazla rota parametresine kolayca erişim sağlar.
Next.js 12 ve Öncesinde API Rotalarını Yönetme
pages
Dizini İçindeki API Rotaları (Next.js 12 ve Öncesi)
Next.js 13, app
dizinini tanıttıktan ve yönlendirme yeteneklerini geliştirdikten önce, API rotaları esasen pages
dizini içinde tanımlanıyordu. Bu yaklaşım hala yaygın olarak kullanılmakta ve Next.js 12 ve önceki sürümlerde desteklenmektedir.
Temel API Rotası
Dosya Yapısı:
goCopy codemy-nextjs-app/
├── pages/
│ └── api/
│ └── hello.js
├── package.json
└── ...
Uygulama:
javascriptCopy code// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ message: 'Hello, World!' });
}
Açıklama:
- Konum: API yolları
pages/api/
dizini altında bulunur. - İhracat: İşlev tanımlamak için
export default
kullanın. - Fonksiyon İmzası: İşlev,
req
(HTTP isteği) veres
(HTTP yanıtı) nesnelerini alır. - Yönlendirme: Dosya adı (
hello.js
),/api/hello
uç noktasına karşılık gelir.
Dinamik API Yolları
Dosya Yapısı:
bashCopy codemy-nextjs-app/
├── pages/
│ └── api/
│ └── users/
│ └── [id].js
├── package.json
└── ...
Uygulama:
javascriptCopy code// pages/api/users/[id].js
export default function handler(req, res) {
const {
query: { id },
method,
} = req;
switch (method) {
case 'GET':
// Fetch user data based on 'id'
res.status(200).json({ userId: id, name: 'John Doe' });
break;
case 'PUT':
// Update user data based on 'id'
res.status(200).json({ message: `User ${id} updated.` });
break;
case 'DELETE':
// Delete user based on 'id'
res.status(200).json({ message: `User ${id} deleted.` });
break;
default:
res.setHeader('Allow', ['GET', 'PUT', 'DELETE']);
res.status(405).end(`Method ${method} Not Allowed`);
}
}
Açıklama:
- Dinamik Segmentler: Kare parantezler (
[id].js
) dinamik rota segmentlerini belirtir. - Parametrelere Erişim: Dinamik parametreye erişmek için
req.query.id
kullanın. - Yöntemleri Yönetme: Farklı HTTP yöntemlerini (
GET
,PUT
,DELETE
, vb.) yönetmek için koşullu mantık kullanın.
Farklı HTTP Yöntemlerini Yönetme
Temel API rota örneği tüm HTTP yöntemlerini tek bir fonksiyon içinde yönetirken, kodunuzu her yöntemi açıkça yönetmek için yapılandırabilirsiniz, bu da daha iyi bir netlik ve sürdürülebilirlik sağlar.
Örnek:
javascriptCopy code// pages/api/posts.js
export default async function handler(req, res) {
const { method } = req;
switch (method) {
case 'GET':
// Handle GET request
res.status(200).json({ message: 'Fetching posts.' });
break;
case 'POST':
// Handle POST request
res.status(201).json({ message: 'Post created.' });
break;
default:
res.setHeader('Allow', ['GET', 'POST']);
res.status(405).end(`Method ${method} Not Allowed`);
}
}
En İyi Uygulamalar:
- Endişelerin Ayrılması: Farklı HTTP yöntemleri için mantığı net bir şekilde ayırın.
- Yanıt Tutarlılığı: İstemci tarafında işleme kolaylığı için tutarlı yanıt yapıları sağlayın.
- Hata Yönetimi: Desteklenmeyen yöntemleri ve beklenmeyen hataları nazikçe yönetin.
CORS Yapılandırması
API rotalarınıza hangi kökenlerin erişebileceğini kontrol edin, Cross-Origin Resource Sharing (CORS) zafiyetlerini azaltın.
Kötü Yapılandırma Örneği:
// app/api/data/route.js
export async function GET(request) {
return new Response(JSON.stringify({ data: "Public Data" }), {
status: 200,
headers: {
"Access-Control-Allow-Origin": "*", // Allows any origin
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE",
},
})
}
Not edin ki CORS, tüm API yollarında da yapılandırılabilir middleware.ts
dosyası içinde:
// app/middleware.ts
import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"
export function middleware(request: NextRequest) {
const allowedOrigins = [
"https://yourdomain.com",
"https://sub.yourdomain.com",
]
const origin = request.headers.get("Origin")
const response = NextResponse.next()
if (allowedOrigins.includes(origin || "")) {
response.headers.set("Access-Control-Allow-Origin", origin || "")
response.headers.set(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS"
)
response.headers.set(
"Access-Control-Allow-Headers",
"Content-Type, Authorization"
)
// If credentials are needed:
// response.headers.set('Access-Control-Allow-Credentials', 'true');
}
// Handle preflight requests
if (request.method === "OPTIONS") {
return new Response(null, {
status: 204,
headers: response.headers,
})
}
return response
}
export const config = {
matcher: "/api/:path*", // Apply to all API routes
}
Problem:
Access-Control-Allow-Origin: '*'
: Herhangi bir web sitesinin API'ye erişmesine izin verir, bu da kötü niyetli sitelerin API'nizle sınırsız etkileşimde bulunmasına olanak tanıyabilir.- Geniş Yöntem İzni: Tüm yöntemlere izin vermek, saldırganların istenmeyen eylemler gerçekleştirmesine olanak tanıyabilir.
Saldırganların bunu nasıl kullandığı:
Saldırganlar, API'nize isteklerde bulunan kötü niyetli web siteleri oluşturabilir, bu da veri alma, veri manipülasyonu veya kimlik doğrulaması yapılmış kullanıcılar adına istenmeyen eylemleri tetikleme gibi işlevleri kötüye kullanmalarına neden olabilir.
CORS - Misconfigurations & Bypass
Sunucu kodunun İstemci Tarafında Açığa Çıkması
Sunucu tarafından kullanılan kodun istemci tarafında da kullanılmasını sağlamak kolaydır, bir kod dosyasının istemci tarafında asla açığa çıkmadığından emin olmanın en iyi yolu, dosyanın başında bu import'u kullanmaktır:
import "server-only"
Ana Dosyalar ve Rolleri
middleware.ts
/ middleware.js
Konum: Projenin kökünde veya src/
içinde.
Amaç: Bir isteğin işlenmesinden önce sunucu tarafında sunucusuz işlevde kodu çalıştırarak kimlik doğrulama, yönlendirmeler veya yanıtları değiştirme gibi görevleri yerine getirir.
İşlem Akışı:
- Gelen İstek: Middleware isteği yakalar.
- İşleme: İsteğe bağlı olarak işlemler gerçekleştirir (örneğin, kimlik doğrulama kontrolü).
- Yanıt Değişikliği: Yanıtı değiştirebilir veya kontrolü bir sonraki işleyiciye geçirebilir.
Örnek Kullanım Durumları:
- Kimliği doğrulanmamış kullanıcıları yönlendirme.
- Özel başlıklar ekleme.
- İstekleri günlüğe kaydetme.
Örnek Konfigürasyon:
// middleware.ts
import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"
export function middleware(req: NextRequest) {
const url = req.nextUrl.clone()
if (!req.cookies.has("token")) {
url.pathname = "/login"
return NextResponse.redirect(url)
}
return NextResponse.next()
}
export const config = {
matcher: ["/protected/:path*"],
}
next.config.js
Konum: Projenin kökü.
Amaç: Next.js davranışını yapılandırır, özellikleri etkinleştirir veya devre dışı bırakır, webpack yapılandırmalarını özelleştirir, ortam değişkenlerini ayarlar ve çeşitli güvenlik özelliklerini yapılandırır.
Ana Güvenlik Yapılandırmaları:
Güvenlik Başlıkları
Güvenlik başlıkları, tarayıcılara içeriği nasıl işleyecekleri konusunda talimat vererek uygulamanızın güvenliğini artırır. Cross-Site Scripting (XSS), Clickjacking ve MIME türü sniffing gibi çeşitli saldırıları azaltmaya yardımcı olurlar:
- Content Security Policy (CSP)
- X-Frame-Options
- X-Content-Type-Options
- Strict-Transport-Security (HSTS)
- Referrer Policy
Örnekler:
// next.config.js
module.exports = {
async headers() {
return [
{
source: "/(.*)", // Apply to all routes
headers: [
{
key: "X-Frame-Options",
value: "DENY",
},
{
key: "Content-Security-Policy",
value:
"default-src *; script-src 'self' 'unsafe-inline' 'unsafe-eval';",
},
{
key: "X-Content-Type-Options",
value: "nosniff",
},
{
key: "Strict-Transport-Security",
value: "max-age=63072000; includeSubDomains; preload", // Enforces HTTPS
},
{
key: "Referrer-Policy",
value: "no-referrer", // Completely hides referrer
},
// Additional headers...
],
},
]
},
}
Görüntü Optimizasyonu Ayarları
Next.js, performans için görüntüleri optimize eder, ancak yanlış yapılandırmalar güvenlik açıklarına yol açabilir, örneğin, güvenilmeyen kaynakların kötü niyetli içerik enjekte etmesine izin vermek.
Kötü Yapılandırma Örneği:
// next.config.js
module.exports = {
images: {
domains: ["*"], // Allows images from any domain
},
}
Sorun:
'*'
: Resimlerin herhangi bir dış kaynaktan, güvenilmeyen veya kötü niyetli alanlardan yüklenmesine izin verir. Saldırganlar, kötü niyetli yükler veya kullanıcıları yanıltan içerikler içeren resimleri barındırabilir.- Başka bir sorun, herkesin bir resim yükleyebileceği bir alanın izin verilmesidir (örneğin
raw.githubusercontent.com
).
Saldırganların bunu nasıl kötüye kullandığı:
Kötü niyetli kaynaklardan resimler enjekte ederek, saldırganlar kimlik avı saldırıları gerçekleştirebilir, yanıltıcı bilgiler gösterebilir veya resim işleme kütüphanelerindeki zafiyetleri istismar edebilir.
Ortam Değişkenlerinin Açığa Çıkması
API anahtarları ve veritabanı kimlik bilgileri gibi hassas bilgileri, istemciye açığa çıkarmadan güvenli bir şekilde yönetin.
a. Hassas Değişkenlerin Açığa Çıkması
Kötü Yapılandırma Örneği:
// next.config.js
module.exports = {
env: {
SECRET_API_KEY: process.env.SECRET_API_KEY, // Exposed to the client
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL, // Correctly prefixed for client
},
}
Problem:
SECRET_API_KEY
:NEXT_PUBLIC_
ön eki olmadan, Next.js değişkenleri istemciye açmaz. Ancak, yanlışlıkla ön ek verilirse (örneğin,NEXT_PUBLIC_SECRET_API_KEY
), istemci tarafında erişilebilir hale gelir.
How attackers abuse it:
Eğer hassas değişkenler istemciye açılırsa, saldırganlar bunları istemci tarafı kodunu veya ağ isteklerini inceleyerek alabilir, API'lere, veritabanlarına veya diğer hizmetlere yetkisiz erişim kazanabilirler.
Redirects
Uygulamanız içinde URL yönlendirmelerini ve yeniden yazmalarını yönetin, kullanıcıların uygun şekilde yönlendirilmesini sağlayın ve açık yönlendirme güvenlik açıkları oluşturmaktan kaçının.
a. Open Redirect Vulnerability
Bad Configuration Example:
// next.config.js
module.exports = {
async redirects() {
return [
{
source: "/redirect",
destination: (req) => req.query.url, // Dynamically redirects based on query parameter
permanent: false,
},
]
},
}
Sorun:
- Dinamik Hedef: Kullanıcıların herhangi bir URL belirtmesine izin verir, bu da açık yönlendirme saldırılarına olanak tanır.
- Kullanıcı Girdisine Güvenme: Kullanıcılar tarafından sağlanan URL'lere doğrulama olmadan yönlendirme yapmak, kimlik avı, kötü amaçlı yazılım dağıtımı veya kimlik bilgisi hırsızlığına yol açabilir.
Saldırganların bunu nasıl kötüye kullandığı:
Saldırganlar, sizin alan adınızdan geliyormuş gibi görünen URL'ler oluşturabilir, ancak kullanıcıları kötü amaçlı sitelere yönlendirebilir. Örneğin:
https://yourdomain.com/redirect?url=https://malicious-site.com
Kullanıcılar, orijinal alan adına güvenerek, farkında olmadan zararlı web sitelerine gidebilirler.
Webpack Yapılandırması
Next.js uygulamanız için Webpack yapılandırmalarını özelleştirin; bu, dikkatli bir şekilde ele alınmadığında güvenlik açıkları oluşturabilir.
a. Hassas Modülleri Açığa Çıkarma
Kötü Yapılandırma Örneği:
// next.config.js
module.exports = {
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.alias["@sensitive"] = path.join(__dirname, "secret-folder")
}
return config
},
}
Sorun:
- Hassas Yolları Açığa Çıkarma: Hassas dizinlerin takma adını vermek ve istemci tarafı erişimine izin vermek, gizli bilgilerin sızmasına neden olabilir.
- Sırları Paketleme: Hassas dosyalar istemci için paketlenirse, içerikleri kaynak haritaları veya istemci tarafı kodunu inceleyerek erişilebilir hale gelir.
Saldırganların bunu nasıl kötüye kullandığı:
Saldırganlar, uygulamanın dizin yapısına erişebilir veya bunu yeniden oluşturabilir, bu da hassas dosyaları veya verileri bulup istismar etmelerini sağlayabilir.
pages/_app.js
ve pages/_document.js
pages/_app.js
Amaç: Varsayılan App bileşenini geçersiz kılar, global durum, stiller ve düzen bileşenleri için olanak tanır.
Kullanım Durumları:
- Global CSS ekleme.
- Düzen sarmalayıcıları ekleme.
- Durum yönetim kütüphanelerini entegre etme.
Örnek:
// pages/_app.js
import "../styles/globals.css"
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp
pages/_document.js
Amaç: Varsayılan Belgeyi geçersiz kılar, HTML ve Body etiketlerinin özelleştirilmesine olanak tanır.
Kullanım Durumları:
<html>
veya<body>
etiketlerini değiştirme.- Meta etiketleri veya özel betikler ekleme.
- Üçüncü taraf yazı tiplerini entegre etme.
Örnek:
// pages/_document.js
import Document, { Html, Head, Main, NextScript } from "next/document"
class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>{/* Custom fonts or meta tags */}</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
Özel Sunucu (İsteğe Bağlı)
Amaç: Next.js yerleşik bir sunucu ile birlikte gelse de, özel yönlendirme veya mevcut arka uç hizmetleri ile entegrasyon gibi gelişmiş kullanım senaryoları için özel bir sunucu oluşturabilirsiniz.
Not: Özel bir sunucu kullanmak, özellikle Next.js'in yerleşik sunucusu için optimize edilen Vercel gibi platformlarda dağıtım seçeneklerini sınırlayabilir.
Örnek:
// server.js
const express = require("express")
const next = require("next")
const dev = process.env.NODE_ENV !== "production"
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
// Custom route
server.get("/a", (req, res) => {
return app.render(req, res, "/a")
})
// Default handler
server.all("*", (req, res) => {
return handle(req, res)
})
server.listen(3000, (err) => {
if (err) throw err
console.log("> Ready on http://localhost:3000")
})
})
Ek Mimari ve Güvenlik Dikkatleri
Ortam Değişkenleri ve Konfigürasyon
Amaç: Hassas bilgileri ve konfigürasyon ayarlarını kod tabanının dışında yönetmek.
En İyi Uygulamalar:
.env
Dosyalarını Kullanın: API anahtarları gibi değişkenleri.env.local
içinde saklayın (versiyon kontrolünden hariç).- Değişkenlere Güvenli Erişim: Ortam değişkenlerine erişmek için
process.env.VARIABLE_NAME
kullanın. - Gizli Bilgileri İstemci Tarafında Asla Açığa Çıkarmayın: Hassas değişkenlerin yalnızca sunucu tarafında kullanıldığından emin olun.
Örnek:
// next.config.js
module.exports = {
env: {
API_KEY: process.env.API_KEY, // Accessible on both client and server
SECRET_KEY: process.env.SECRET_KEY, // Be cautious if accessible on the client
},
}
Not: Değişkenleri yalnızca sunucu tarafında kısıtlamak için, env
nesnesinden çıkarın veya istemciye maruz kalma için NEXT_PUBLIC_
ile öne ekleyin.
Kimlik Doğrulama ve Yetkilendirme
Yaklaşım:
- Oturum Tabanlı Kimlik Doğrulama: Kullanıcı oturumlarını yönetmek için çerezleri kullanın.
- Token Tabanlı Kimlik Doğrulama: Durumsuz kimlik doğrulama için JWT'leri uygulayın.
- Üçüncü Taraf Sağlayıcılar:
next-auth
gibi kütüphaneler kullanarak OAuth sağlayıcılarıyla (örn., Google, GitHub) entegre edin.
Güvenlik Uygulamaları:
- Güvenli Çerezler:
HttpOnly
,Secure
veSameSite
niteliklerini ayarlayın. - Şifre Hashleme: Şifreleri saklamadan önce her zaman hashleyin.
- Girdi Doğrulama: Girdi doğrulama ve temizleme ile enjeksiyon saldırılarını önleyin.
Örnek:
// pages/api/login.js
import { sign } from "jsonwebtoken"
import { serialize } from "cookie"
export default async function handler(req, res) {
const { username, password } = req.body
// Validate user credentials
if (username === "admin" && password === "password") {
const token = sign({ username }, process.env.JWT_SECRET, {
expiresIn: "1h",
})
res.setHeader(
"Set-Cookie",
serialize("auth", token, {
path: "/",
httpOnly: true,
secure: true,
sameSite: "strict",
})
)
res.status(200).json({ message: "Logged in" })
} else {
res.status(401).json({ error: "Invalid credentials" })
}
}
Performans Optimizasyonu
Stratejiler:
- Görüntü Optimizasyonu: Otomatik görüntü optimizasyonu için Next.js'in
next/image
bileşenini kullanın. - Kod Bölme: Dinamik içe aktarmaları kullanarak kodu bölün ve başlangıç yükleme sürelerini azaltın.
- Önbellekleme: API yanıtları ve statik varlıklar için önbellekleme stratejileri uygulayın.
- Tembel Yükleme: Bileşenleri veya varlıkları yalnızca ihtiyaç duyulduğunda yükleyin.
Örnek:
// Dynamic Import with Code Splitting
import dynamic from "next/dynamic"
const HeavyComponent = dynamic(() => import("../components/HeavyComponent"), {
loading: () => <p>Loading...</p>,
})
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- Bize katılın 💬 Discord grubuna veya telegram grubuna veya bizi takip edin Twitter'da 🐦 @hacktricks_live.
- Hacking ipuçlarını paylaşın, HackTricks ve HackTricks Cloud github reposuna PR göndererek.