The basic principle of CSRF attack
CSRF (Cross-Site Request Forgery) attack is a type of attack that exploits a user's logged-in identity to perform unintended actions without their knowledge. Attackers induce users to visit malicious pages or click on links, triggering requests to the target site, thereby completing illegal operations with the user's permissions.
Core Mechanism of CSRF Attacks
CSRF attacks rely on the browser's mechanism of automatically carrying user credentials (such as cookies). When a user logs into a website, the browser stores session cookies and automatically attaches these cookies to subsequent requests. Attackers exploit this feature by crafting a malicious request and tricking the user into triggering it while logged in.
Key conditions include:
- The user is logged into the target site and maintains an active session.
- The target site lacks effective CSRF protection measures.
- The user is induced to perform the attacker's predefined action.
Analysis of Typical Attack Scenarios
Bank Transfer Case
Assume a bank website's transfer interface is as follows:
POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: sessionid=user123
Content-Type: application/x-www-form-urlencoded
toAccount=attacker&amount=1000
An attacker can embed the following in their malicious website:
<form action="https://bank.example.com/transfer" method="POST">
<input type="hidden" name="toAccount" value="attacker">
<input type="hidden" name="amount" value="1000">
</form>
<script>
document.forms[0].submit();
</script>
When a user logged into the bank website visits this malicious page, the transfer request is automatically sent with the user's session cookie.
Social Media Profile Modification
A social media site's email update interface:
// Frontend code
fetch('/api/update-email', {
method: 'POST',
body: JSON.stringify({ newEmail: 'attacker@example.com' }),
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.token}`
}
})
An attacker can craft a phishing page:
<a href="https://social.com/api/update-email?newEmail=attacker@example.com">
Click to claim your coupon
</a>
Differences Between CSRF and XSS
Although both involve cross-site scripting, they are fundamentally different:
Feature | CSRF | XSS |
---|---|---|
Attack Target | Exploits user identity to perform actions | Steals user data or sessions |
Dependency | Requires user to be logged in | Requires injection vulnerabilities |
Request Initiator | Browser automatically initiates requests | Malicious scripts actively execute |
Data Flow | Outbound requests from target site | External scripts retrieve site data |
Implementation of Defense Measures
Same-Origin Detection
// Server-side middleware example (Node.js)
app.use((req, res, next) => {
const origin = req.headers.origin || req.headers.referer;
if (!origin || !origin.match(/^https?:\/\/trusted\.com$/)) {
return res.status(403).send('Forbidden');
}
next();
});
CSRF Token Solution
<!-- Server-side rendering injects Token -->
<form action="/transfer" method="POST">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<!-- Other form fields -->
</form>
Server-side validation:
// Express.js using csrf middleware
const csrf = require('csurf');
app.use(csrf({ cookie: true }));
app.post('/transfer', (req, res) => {
// Middleware automatically validates _csrf field
});
SameSite Cookie Attribute
// Set SameSite attribute when setting cookies
res.cookie('sessionid', 'abc123', {
httpOnly: true,
secure: true,
sameSite: 'Strict'
});
Double-Submit Cookie
Frontend code:
// Read CSRF Token from Cookie
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
// Attach Header when sending requests
fetch('/api/transfer', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': getCookie('csrf_token')
}
});
Protection Mechanisms in Modern Frontend Frameworks
React's CSRF Protection
// Add Token in global request interceptor
axios.interceptors.request.use(config => {
config.headers['X-XSRF-TOKEN'] = Cookies.get('XSRF-TOKEN');
return config;
});
Angular's HttpClient
// Enable CSRF protection
import { HttpClientXsrfModule } from '@angular/common/http';
@NgModule({
imports: [
HttpClientXsrfModule.withOptions({
cookieName: 'XSRF-TOKEN',
headerName: 'X-XSRF-TOKEN'
})
]
})
export class AppModule {}
Considerations in Actual Development
- Secondary Verification for Sensitive Operations:
// Critical operations require re-entering password
app.post('/delete-account', (req, res) => {
if (!verifyPassword(req.body.password)) {
return res.status(401).send('Invalid password');
}
// Perform deletion
});
- API Design Principles:
- Enforce POST/PUT/DELETE methods for state-modifying operations.
- Avoid using GET requests for write operations.
- Add version control prefixes for RESTful APIs.
- Log Monitoring:
// Log sensitive operations
app.post('/transfer', (req, res) => {
logAction({
userId: req.user.id,
action: 'TRANSFER',
metadata: {
toAccount: req.body.toAccount,
amount: req.body.amount,
ip: req.ip
}
});
});
Handling Advanced Attack Scenarios
Protection Against AJAX Requests
// Custom Header protection
const csrfToken = generateToken();
localStorage.setItem('csrf-token', csrfToken);
fetch('/api/data', {
headers: {
'X-Custom-CSRF': csrfToken
}
});
CSRF Protection for File Uploads
<!-- Special handling for file upload forms -->
<form id="upload-form">
<input type="file" name="file">
<input type="hidden" name="_csrf" value="token123">
<button onclick="uploadWithProgress()">Upload</button>
</form>
<script>
function uploadWithProgress() {
const formData = new FormData(document.getElementById('upload-form'));
// Ensure Content-Type is not overridden
fetch('/upload', {
method: 'POST',
body: formData,
headers: {
'X-CSRF-Verify': getCSRFToken()
}
});
}
</script>
CSRF Issues Specific to Mobile
Deep Link Attacks
Attackers can craft URLs like:
myapp://transfer?to=attacker&amount=1000
Defense solution:
// Android Intent Filter validation
<intent-filter>
<data android:scheme="https" android:host="verified.domain"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
Protection in WebView
// Configure WebView security policies
webView.settings.javaScriptEnabled = true
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
// Validate URL domain whitelist
if (!isTrustedDomain(request?.url?.host)) {
return true
}
return false
}
}
Evolution of Browser Security Policies
Chrome's SameSite Default Changes
Since Chrome 80, the SameSite attribute for cookies defaults to Lax
:
Strict
: Completely prohibits cross-site sending.Lax
: Allows GET requests for top-level navigation.None
: Allows cross-site sending (requires Secure).
Fetch Metadata Specification
Use Sec-Fetch-*
headers for protection:
# Nginx configuration example
location /api/ {
if ($http_sec_fetch_site != "same-origin") {
return 403;
}
# Other processing logic
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:自动化检测与工具推荐
下一篇:CSRF 攻击的典型场景