Key Content of This Lesson#
Security issues are very common and can harm
- Users
- Companies
- Programmers (sacrificed QAQ)
Two Perspectives on Web Security#
If you are a hacker - Attack#
Cross-Site Scripting (XSS)#
Injecting malicious scripts to complete attacks, consequences: leaking user privacy, etc.
XSS mainly exploits developers' blind trust in user-submitted content.
Characteristics
- Usually difficult to perceive from the UI (scripts are generally executed in the background)
- Stealing user information (cookie/token)
- Rendering UI (such as pop-ups) to trick users into clicking/filling out forms
For example
public async submit(ctx) {
const {content, id} = ctx.request.body;
await db.save({
content, // No filtering on content!!
id
});
}
public async render(ctx) {
const { content } = await db.query({
id: ctx.query.id
});
// No filtering on content!!
ctx.body = `<div>${content}</div>`;
}
As seen in the code above, there is no filtering on the user-inputted content. At this point, one could submit a <script>alert('xss');</script>
script to carry out an attack.
XSS attacks can be categorized into several types: Stored XSS, Reflected XSS, DOM-based XSS, Mutation-based XSS.
Stored XSS#
- The submitted malicious script is stored in the database
- Accessing the page -> reading data == being attacked
- Most harmful, visible to all users
- For example: On a video website, a malicious script uploaded is stored in the database, leading to the creation of a video-sharing account on an e-commerce site.
Reflected XSS#
-
Does not involve the database
-
Attacks from the URL, carrying the script in the URL
DOM-based XSS#
-
Does not require server involvement
-
The initiation and execution of the malicious attack occur entirely in the browser
-
The place where the script is injected comes from the browser, which distinguishes it from Reflected XSS.
Mutation-based XSS#
-
A clever attack method that exploits browser features
If the rich text content provided by the user enters the innerHTML property through JavaScript code, some unexpected changes may cause this assumption to no longer hold: the browser's rendering engine may render originally harmless HTML code into potentially dangerous XSS attack code.
-
Clever and one of the hardest methods to defend against; attackers understand browsers very well.
Cross-Site Request Forgery (CSRF)#
-
Occurs without the user's knowledge
-
Exploits user permissions (cookie)
-
Constructs specific HTTP requests to steal or modify sensitive user information
A user visits a malicious page, which sends a transfer request to the bank; ServerA is the bank's server and finds that the request carries the user's cookie, thus succeeding.
CSRF exploits requests disguised as coming from trusted users to leverage trusted websites. Compared to XSS attacks, CSRF attacks are often less common (thus resources for prevention are also relatively scarce) and harder to defend against, making them considered more dangerous than XSS.
Injection#
-
SQL Injection: Injecting through SQL parameters
Example: Reading request fields and directly concatenating SQL statements as strings.
public async rederForm(ctx) { const {username, form_id } = ctx.query; const result = await sql.query(` SELECT a, b, c FROM table WHERE username = ${username} AND form_id = ${form_id} `); ctx.body = renderForm(result); }
An attacker could input a userName:
any; DROP TABLE table;
, thus achieving the goal of deleting the database. -
Command line injection, etc.
-
Reading + modifying traffic attacks
Denial of Service (DoS) Attack#
-
By some means (constructing specific requests), significantly consuming server resources,
-
Unable to respond to more requests in time, leading to request congestion and a cascading effect.
-
Extension: Regular expressions - greedy mode
- When matching repeatedly,
?
/no ?
: satisfies "one is enough" / "as many as possible"
- When matching repeatedly,
-
Example: ReDoS: DoS based on regular expressions
-
Greedy: if n times doesn't work, try n-1 times? - backtracking
-
Distributed DoS (DDoS)
-
In a short time, requests from a large number of zombie devices, the server cannot complete all requests in time, leading to request accumulation and a cascading effect, unable to respond to new requests. (Just a large volume is enough)
-
Characteristics:
-
Directly access IP
-
Any API
-
Consume a large amount of bandwidth (exhaustion)
-
-
Man-in-the-Middle Attack (Transport Layer)#
-
Plain text transmission
-
Information tampering is undetectable
-
Counterpart identity is unverified
If you are a developer - Defense#
Defending Against XSS Attacks#
-
Never trust user submitted content
- Do not directly convert user-submitted content into DOM
-
Ready-made tools
- Mainstream frameworks default to defend against XSS (like React)
- google-closure-library
- Server-side: DOMPurify
-
User needs: Must dynamically generate DOM?
-
new DOMParser();
-
SVG: also needs scanning, as it can also insert script tags
-
Do not allow user-defined redirect links (or filter them well)!
<a href="javascript:alert('xss')"></a>
-
-
Custom styles should also be noted!
Same-Origin Policy (CSP)#
- Protocol
- Domain name
- Port
Any one of these being different means cross-origin ×
Browser Same-Origin Policy - Web Security | MDN (mozilla.org)
Generally, same-origin requests are fine, while cross-origin ones are not; CSP allows developers to define
- Which sources (domain names) are considered safe
- Scripts from safe sources can be executed; otherwise, an error is thrown
- Directly reject eval + inline scripts
- Set
- Server response headers
Content-Security-Policy: script-src 'self'; // Same-origin Content-Security-Policy: script-src 'self' https://domain.com
- Browser response headers
<meta http-equiv="Content-Security-Policy" content="script-src self">
Defending Against CSRF Attacks#
-
Origin + Referrer
-
Other methods to determine if the request comes from a legitimate source
- Page first, then request
- if the request comes from a legitimate page
- then the server has accepted the page request
- then the server can identify
- Page first, then request
-
-
iframe attacks: Restricting Origin, right? Then I can make same-origin requests.
-
Avoid GET + POST requests together; attackers can achieve two goals with one stone!
// Do not place update + fetch logic in the same GET interface like below public async getAndUpdate(ctx) { const { update, id } = ctx.query; if (update) { await this.update(update); } ctx.body = await this.get(id); }
-
SameSite Cookie
-
Restrict Cookie domain
-
Check if the page domain matches
-
What about third-party services relying on cookies?
Embedding a player from site X, unable to recognize user login status, cannot send bullet comments.
Set-Cookie: SameSite=None; Secure ;
-
-
SameSite vs CORS (Cross-Origin Resource Sharing)
With so many methods to defend against CSRF, what is the correct posture for defending against CSRF? Write a middleware specifically for this defense.
Defending Against Injection#
-
Find the places in the project where SQL queries are made.
-
Use prepared statements.
PREPARE q FROM 'SELECT user FROM users WHERE gender = ?'; SET @gender = 'female'; EXECUTE q USING @gender; DEALLOCATE PREPARE q;
-
Principle of least privilege
- Do not use sudo || root for all commands ×
-
Establish an allowlist + filtering
- rm is strictly prohibited.
-
Restrict protocol, domain name, IP, etc., for URL-type parameters.
- Prevent attackers from accessing the internal network.
Defending Against DoS#
- Code Review (avoid greedy matching, etc.)
- Code scanning + regex performance testing
- Avoid using regex provided by users.
Defending Against DDoS#
Transport Layer - Defending Against Man-in-the-Middle#
Utilize the renowned HTTPS.
- Reliability: Encryption
- Integrity: MAC verification
- Non-repudiation: Digital signature
-
Extension: Digital signature
-
Private key (keep it safe)
-
Public key (publicly visible)
-
CA: Certificate Authority
-
Digital signature, browser built-in CA public key
-
- When the signature algorithm is not robust enough: it can be brute-forced (which is now relatively well-established).
HTTP Strict-Transport-Security (HSTS)
- Actively upgrade HTTP to HTTPS.
Static resources being hijacked or tampered with? Compare hashes.
Conclusion#
- Security is no small matter.
- Dependencies used (npm packages, even NodeJS) may become the weakest link.
- Maintain a learning mindset.
Summary and Reflections#
In this lesson, the teacher vividly explained many knowledge points related to web security, which was very interesting, including types of web attacks, defense methods, etc.
Most of the content cited in this article comes from Teacher Liu Yuchen's class, MDN, and external blog references: This time, thoroughly understanding XSS attacks, A Brief Discussion on CSRF