XSS (Cross-site Scripting)
By injecting malicious scripts into target websites, users can obtain sensitive information such as cookies and sessions by using these malicious scripts
Hazards caused by XSS
- Obtain Cookie, Session, and Storage of the user
- The key to go fishing
- Hijack front-end logic
- Send the request
- .
DOM XSS
<div id="app">
<p v-html="text"></p>
</div>
Copy the code
Vue.createApp({
data() {
return {
text: ' hahahahahahaha
'.script:''
}
}
}).mount('#app')
Copy the code
Reflective XSS
Construct malicious urls such as http://xxx.com?a=
Type stored XSS
Malicious code is submitted to the database such as JS code snippets
// Back end returns data,
{
"data": [{
content: }}]// Malicious code is executed when data returned from the back end is displayed on the page
Copy the code
XSS injection point
- HTML embedded text, injected with script tags
- In inline javascript, splicing data breaks the original rules
- Href, SRC, etc
- Onload, onError, onclick
- .
defense
- Handle escapes and so on at output time
- Pure front-end rendering
- Specify that you want to set text, properties, styles, and so on
- Properties and events such as images are handled
- Use innerHTML as little as possible
- Content security policy (CSP), X-XSS-protection (early Chrome, Safari), etc
Third party libraries such as JS-XSS can be used for processing
Cross-site request forgery (CSRF or XSRF)
process
- The user logs in to website A
- The attacker lures the user to site B and sends A request to site A
- Website A receives the request (which it thinks is sent by user A) and performs the operation XXX
- The attack is complete, and the attacker’s actions are executed without the user’s knowledge
CSRF case
Install dependencies
npm i koa @koa-router koa-bodyparser koa-session koa-static @koa/cors
Copy the code
The back-end code
const Koa = require('koa')
const Router = require('@koa/router')
const bodyParser = require('koa-bodyparser')
const cors = require('@koa/cors')
const session = require('koa-session')
const static = require('koa-static')
const app = new Koa()
const router = new Router()
app.keys = ['some secret hurr']
const CONFIG = {
key: 'koa.sess'.maxAge: 86400000.autoCommit: true.overwrite: true.httpOnly: true.signed: true.rolling: false.renew: false.secure: false.sameSite: null,
}
app.use(static('. '));
app.use(session(CONFIG, app))
app.use(bodyParser())
app.use(cors({
credentials: true
}))
router.get('/user'.async (ctx) => {
if (ctx.session.user) {
ctx.body = ctx.session.user
return
}
ctx.body = {
code: 1
}
})
router.post('/pay'.async (ctx) => {
const {
count
} = ctx.request.body
const user = ctx.session.user
if (user && count) {
ctx.body = {
code: 0.msg: ` user${user.username}pay${count}Yuan successful `
}
}
})
router.post('/login'.async (ctx) => {
const user = ctx.request.body
if (user.username === 'shibin' && user.password === '123456') {
ctx.session.user = {
username: 'shibin'.id: 'sdsadsasd12132'
}
ctx.body = {
code: 0}}else {
ctx.body = {
code: 1
}
}
})
app.use(router.allowedMethods())
.use(router.routes())
app.listen(3000.() = > {
console.log('serve listen http://localhost:3000')})Copy the code
Open A service randomly, A website access, login user name shibin password 123456
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
<div>
<div>User name:<input id="username"></div>
<div>Password:<input id="password" type="password"></div>
<button id="button">The login</button>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<script>
document.getElementById('button').addEventListener('click'.() = > {
axios.post('http://localhost:3000/login', {
username: document.getElementById('username').value,
password: document.getElementById('password').value
}).then(res= > {
if(res.data.code ! = =0) {
alert('Wrong username or password')}else {
alert('Login successful')
}
}).catch(e= > {
console.log(e)
})
})
</script>
Copy the code
Before starting another service, visit site B (think of it as going to a phishing site from somewhere else)
<! -- B website, can also be a hidden form submission, even if the backend restrictions can be cross-domain submission -->
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
<h1>CSRF attacks</h1>
<h1>Cash out</h1>
</body>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<script>
const request = axios.create({
withCredentials: true
})
request.post('http://localhost:3000/pay', {
count: 100000000
}).then(res= > {
alert(res.data.msg)
})
</script>
</html>
Copy the code
Users may do some harmful operations such as transfer money when they visit B’s website without their knowledge
Protection strategy
- Origin Header
- Referer Header
- CSRF Token
Setting the request Source
app.use(cors({
credentials: true.origin: [xxx]
}))
Copy the code
Libraries such as back-end render KOA-CSRF are also available
Click hijacking (disguised websites)
An attacker creates a fake website, introduces another website to hide on the page (iframe transparency), and when operating on the attacker’s website, it will operate on the content of the normal website. If bank website waits
case
Attacker’s website
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
<style>
iframe{
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
</style>
</head>
<body>
<div>
<button>Click to give you a million</button>
</div>
<iframe src="http://localhost:3000/b.html"></iframe>
</body>
</html>
Copy the code
Bank website
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<title>Document</title>
</head>
<body>
<div>
<button id="btn">Click to transfer $1 million to someone else</button>
</div>
</body>
<script>
document.getElementById('btn').addEventListener('click'.() = >{
// xxx
alert('Transfer successful')})</script>
</html>
Copy the code
When a user operates on an attacker’s website, it is as if he were operating on a bank’s website
Protection strategy
Blocking top-level navigation
Determines the top-level browser window object of the current window with window.top
// In some newer browsers the jump is blocked
if(top.location ! = =window.location) {
top.location = window.location
}
Copy the code
But this approach is easy to crack
window.onbeforeunload = function() {
return false;
}
Copy the code
Sandbox, sandboxed iframe cannot change top.location
<iframe sandbox="allow-scripts allow-forms" src="facebook.html"></iframe>
Copy the code
X-FRAME-OPTIONS
Setting the total X-frame-options of the HTTP header indicates whether the browser should load the three x-frame-options forms of the IFrame page
DENY
Cannot be nested by any iframe or frameSAMEORIGIN
, can only be nested in this siteALLOW-FROM url
, specifying sources that can be nested
Nginx configuration
add_header X-Frame-Options SAMEORIGIN;
Copy the code
HTTP Secure Transport
The disadvantage of HTTP
- Clear legend
- Do not verify the identity of the communicating party and may encounter camouflage
- The integrity of the packet cannot be proved and may be tampered with
The solution
- Transfer using HTTPS
Third-party dependency security issues
- Third-party dependencies, try to use a mature third-party dependency package
- use
npm audit
Detect the risk of dependent packages - Sonarqube code review tool, an online scanning service
- Snyk local scan