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

  • DENYCannot be nested by any iframe or frame
  • SAMEORIGIN, can only be nested in this site
  • ALLOW-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
  • usenpm auditDetect the risk of dependent packages
  • Sonarqube code review tool, an online scanning service
  • Snyk local scan