CORS, XSS, SQL Injection & CSRF: 4 Web Attacks Explained
Back to Blog
Web SecurityOWASPSecure CodingApplication Security

CORS, XSS, SQL Injection & CSRF: 4 Web Attacks Explained

July 22, 20267 min readBy J33 Tech Team

TL;DR

Four vulnerabilities cause a disproportionate share of real-world web breaches: CORS misconfiguration, Cross-Site Scripting (XSS), SQL Injection, and Cross-Site Request Forgery (CSRF). Each has a well-understood, low-effort fix. This guide walks through how each attack works, a realistic scenario, and the specific controls that stop it.

Every day, millions of people hand web applications their money and their identities. Somewhere in your app right now there is a form or an API endpoint an attacker has a script for.

Most breaches don't need anything more exotic than that. Attackers exploit the same four mistakes, year after year, and the defenses ship free with modern browsers, frameworks, and databases. Here is how each attack works and what stops it.


1. CORS Misconfiguration

CORS (Cross-Origin Resource Sharing) is the browser mechanism that decides whether a page on one origin may read responses from another. Your frontend at shop.example.com calling your API at api.example.com crosses origins, so the browser checks the API's CORS policy before handing over the response.

CORS itself is not the vulnerability. The vulnerability is a server that answers those checks too generously.

The scenario: a banking API that reflects any origin

A bank serves its app from bank.com and its API from api.bank.com. A developer first tries Access-Control-Allow-Origin: *, discovers browsers refuse to combine the wildcard with credentials, and "fixes" it the quick way: the API now echoes back whatever Origin header the request carries. A request from an attacker's page gets:

Access-Control-Allow-Origin: https://evil.example
Access-Control-Allow-Credentials: true

A customer logs in, then opens a malicious site in another tab. That site silently fires a request at api.bank.com from the victim's browser. Because the API explicitly allowed the attacker's origin, with credentials, the browser hands the attacker's page the customer's account data: balances, transactions, personal details. To the server logs it looks like a specific allowlist. In practice it grants every origin on the internet credentialed access.

How to prevent CORS misconfiguration

  • Allow only trusted origins, from an explicit, finite allowlist: Access-Control-Allow-Origin: https://bank.com
  • Never reflect the request's Origin header back without validating it against that allowlist
  • Never combine wildcards or reflected origins with Access-Control-Allow-Credentials: true
  • Allow only the HTTP methods each endpoint actually needs

2. Cross-Site Scripting (XSS)

XSS happens when an application puts untrusted input into a page without encoding or sanitizing it, letting attacker-supplied JavaScript run in other users' browsers. It comes in three flavors: stored (the payload lives in your database), reflected (it bounces off a URL parameter), and DOM-based (it never touches the server, entering through sinks like innerHTML, document.write, or eval).

The scenario: a comment box that renders HTML

A social platform lets users comment on posts. A normal user writes "Great article!". An attacker instead posts a comment containing a script tag. If the application renders comments as raw HTML, that script executes in the browser of every person who views the post. From there it can read page content, fire requests as the victim, rewrite what the victim sees, or redirect them to a fake login page.

One stored payload, thousands of executions. That is what makes stored XSS the most damaging of the three.

How to prevent XSS

  • Encode output for its context (HTML, attribute, URL, JavaScript). This is the primary defense. Modern frameworks like React do this by default; the escape hatches (dangerouslySetInnerHTML and friends) are where the holes reappear
  • Sanitize any HTML you genuinely must accept, with a maintained library, never a homemade regex
  • Set a Content Security Policy (CSP) as a second layer. Configured without unsafe-inline, using nonces or hashes, it stops injected inline scripts from executing
  • Mark session cookies HttpOnly so scripts cannot read them. This limits cookie theft, though injected script can still act as the user while the page is open
  • Validate input on arrival, but never rely on validation alone

3. SQL Injection (SQLi)

SQL Injection is the oldest trick on this list and still ranks in the OWASP Top 10. It occurs when user input is concatenated into a SQL query, letting an attacker change what the query means rather than what it searches for.

The scenario: a login form that builds its own query

An e-commerce site checks logins by gluing the submitted username and password directly into a SQL string. An attacker submits input crafted so the database reads it as part of the query logic instead of as data. The classic payload turns the password check into a condition that is always true. The attacker walks through the login without knowing any password. The same technique, pointed at other queries, dumps customer tables, alters orders, or deletes records outright.

How to prevent SQL injection

  • Use parameterized queries (prepared statements) everywhere: WHERE username = ? with the value bound separately, never spliced into the string. This habit eliminates the class for data values
  • Allowlist anything that cannot be parameterized, such as column names in ORDER BY clauses
  • Prefer an ORM, which parameterizes by default
  • Run application database accounts with the minimum permissions they need, so a successful injection cannot drop tables
  • Validate input for shape and length as defense in depth

4. Cross-Site Request Forgery (CSRF)

CSRF exploits the fact that browsers historically attached your cookies to every request sent to a site, no matter which page triggered it, and still do wherever SameSite restrictions don't apply. An attacker cannot read the response, but they can make your browser send a request you never intended, and the server sees a fully authenticated call. The attack only works against cookie-based (ambient) authentication: apps that send tokens in an Authorization header are largely immune, because nothing attaches the token automatically.

The scenario: a money transfer you never made

A customer logs into online banking, then, without logging out, visits an attacker-controlled page. That page contains a hidden form that auto-submits a transfer request to the bank. The browser dutifully attaches the customer's session cookie. Unless the bank verifies the request actually came from its own pages, the transfer goes through. The same trick works for password changes, email changes, and any other state-changing action.

How to prevent CSRF

  • Include a CSRF token in every state-changing form and verify it server-side. Most frameworks do this out of the box
  • Set session cookies to SameSite=Lax or Strict so the browser stops attaching them to cross-site requests
  • Verify Origin and Referer headers on sensitive endpoints
  • Require re-authentication for high-value actions like transfers and password changes

Key Insight

SQL Injection and XSS share one root cause: the application let data become instructions. Parameterized queries keep user input out of SQL logic; output encoding keeps it out of page markup. The other two are failures of trust. CSRF happens when the server trusts the browser's ambient credentials as proof of intent, and CORS misconfiguration happens when the server trusts the wrong origins. Fix the separation and the trust, and the attack class disappears.


The Four at a Glance

VulnerabilityWhat it targetsImpactPrimary defense
CORS misconfigurationBrowser same-origin policyCross-origin data exposureExplicit origin allowlist
XSSUser's browserScript execution as the victimOutput encoding + CSP
SQL InjectionDatabaseData theft, tampering, auth bypassParameterized queries
CSRFAuthenticated sessionActions forged on the user's behalfCSRF tokens + SameSite cookies

None of these fixes is a project. Most are a config header, a middleware flag, or a query API you should already be using. Put an automated scanner (Snyk, OWASP ZAP, or your platform's built-in tools) in CI to catch regressions, and re-test after every architectural change. A check that ran once in 2024 protects nothing today.


Frequently Asked Questions

What is the difference between XSS and CSRF?

XSS runs the attacker's code inside your page, so the attacker can read and do anything the page can. CSRF never runs code and never reads responses; it only tricks the browser into sending an authenticated request. XSS is generally more severe, and an XSS hole usually defeats CSRF protections too.

Does using an ORM make SQL injection impossible?

It removes the common cases because ORMs parameterize queries by default. But raw-query escape hatches, string-built filters, and unsafe ORDER BY clauses can reintroduce the flaw. Treat the ORM as a strong default, not a guarantee.

Is Access-Control-Allow-Origin: * always dangerous?

No. For genuinely public, unauthenticated data (a public CDN, an open dataset) a wildcard is fine. It becomes dangerous on endpoints whose data is guarded by something other than explicit credentials, such as network position or IP allowlists, and when developers work around the wildcard-plus-credentials block by reflecting the request's origin.

Do SameSite cookies make CSRF tokens unnecessary?

SameSite=Lax (the default in Chromium-based browsers since 2020) blocks most CSRF vectors, but edge cases remain in other browsers, older clients, and some cross-site GET flows. Defense in depth is cheap here: keep tokens on state-changing endpoints and let SameSite be the second layer.

How do I find these vulnerabilities in my own application?

Combine automated scanning (Snyk, OWASP ZAP, dependency and SAST scanners in CI) with periodic manual testing. Automated tools catch the known patterns cheaply on every commit; a human tester finds the logic flaws tools miss.


Further Reading


About J33.AI

At J33.AI, we build systems where security is part of the architecture, not an afterthought. With over 15 years of experience in digital transformation, we design cloud and security architecture for applications that handle real users and real money.

Need a Security Review of Your Application?

From CORS policies to CI-integrated scanning, we help teams find and fix vulnerabilities before attackers do. Read how OAuth 2.0 secures modern login flows, or explore more guides from our engineering team.

Contact Us