了解sql注入、xss攻擊及解決
前言
朋友說:聽說你做了個網站
我說:對啊,趕緊成為我的用戶啦
朋友說:好啊,你知道sql注入、xss攻擊嗎
我說:不知道
朋友明天跟我說,哇,管理員賬戶就是好,有好多權限,真香
我說:你怎么能登錄我管理員賬戶???
朋友說:你都不知道sql注入、xss攻擊,那你肯定沒做這些,我利用sql注入,知道管理員賬戶就可以登錄進去啦
嚇得我趕緊去做一下相關工作,還好朋友告知
下面詳細了解sql注入、xss攻擊及解決
四個方面
1. 什么是sql注入
所謂SQL注入,就是通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。是最原始、最簡單的攻擊,從有了web2.0就有了sql注入攻擊。
2. sql注入例子
用戶登錄,我們需要去查詢用戶表(users),對比用戶名(username)和密碼(password)
SQL語句:
// 正常select * from users WHERE username="zhangsan" and password="524abb53cce35" // sql注入 用戶名寫入:zhangsan'-- select * from users WHERE username='zhangsan'-- ' and password='5245'

上面兩條sql語句都能查詢到用戶的存在,并且第二條語句中密碼校驗的語句已經被注銷了,那么這個時候如果別人知道你的用戶名就能登錄你的賬號,這樣子豈不是很危險??????
我們來看下執行的sql語句,果然是 -- 后面被注釋了~~~
select id, username, realname from users where username='zhangsan '-- ' and password='696'
不必慌,我們來看一下之前的db/mysql.js文件,
const mysql = require('mysql')const { MYSQL_CONF } = require('../conf/db')
// 創建鏈接對象const con = mysql.createConnection(MYSQL_CONF)
// 開始鏈接con.connect()
// 統一執行 sql 的函數function exec(sql) { const promise = new Promise((resolve, reject) => { con.query(sql, (err, result) => { if (err) { reject(err) return } resolve(result) }) }) return promise}
module.exports = { exec, escape: mysql.escape // 防止sql注入 編碼特殊字符}
看到這段關鍵代碼了嗎???
escape: mysql.escape // 防止sql注入 編碼特殊字符
我們來改動一下之前的controller/users.js login方法:
const { exec, escape } = require('../db/mysql')const { genPassword } = require('../utils/cryp')
const register = async (username, password) => { ...}const userNameFilter = async (username) => { ...}
const login = async (username, password) => { username = escape(username) // 格式化 預防sql注入 password = genPassword(password) // 生成加密密碼 password = escape(password) // 格式化 預防sql注入
const sql = ` select id, username, realname from users where username=${username} and password=${password} ` // console.log('sql is', sql)
const rows = await exec(sql) return rows[0] || ''}
const userInfo = async (id) => { ...}
module.exports = { login, register, userNameFilter, userInfo}
我們再來登錄一下,發現登錄果然失敗了
格式化之后執行的sql語句:
select id, username, realname from users where username='zhangsan \'-- ' and password='6996'
從上面對比我們可以知道,escape 就是對一下能對sql語句有影響的特殊字符進行格式化,預防拼接sql語句。
所以為了預防萬一,我們需要把能拼接成sql語句的變量都要加上escape!
3. 什么是xss攻擊
XSS攻擊通常指的是通過利用網頁開發時留下的漏洞,通過巧妙的方法注入惡意指令代碼到網頁,使用戶加載并執行攻擊者惡意制造的網頁程序。這些惡意網頁程序通常是JavaScript,但實際上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻擊成功后,攻擊者可能得到包括但不限于更高的權限(如執行一些操作)、私密網頁內容、會話和cookie等各種內容。
- 攻擊方式:
盜用cookie,獲取敏感信息。
利用植入Flash,通過crossdomain權限設置進一步獲取更高權限;或者利用Java等得到類似的操作。
利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊)用戶的身份執行一些管理動作,或執行一些一般的如發微博、加好友、發私信等操作。
利用可被攻擊的域受到其他域信任的特點,以受信任來源的身份請求一些平時不允許的操作,如進行不當的投票活動。
在訪問量極大的一些頁面上的XSS可以攻擊一些小型網站,實現DDoS攻擊的效果。
4. nodejs怎么來防范XSS攻擊:
首頁我們安裝一個xss依賴
npm install xss --save-dev
- 下來我們來舉一個簡單的例子吧!看注釋!!
const xss = require('xss') // 引入xssconst { exec } = require('../db/mysql')
const newBlog = async (blogData = {}) => { // blogData 是一個博客對象,包含 title content author 屬性 const title = xss(blogData.title) // 防范xss攻擊 const content = xss(blogData.content) // 防范xss攻擊 const author = blogData.author const createTime = Date.now()
const sql = ` insert into blogs (title, content, createtime, author) values ('${title}', '${content}', ${createTime}, '${author}'); `
const insertData = await exec(sql) return { id: insertData.insertId }}
module.exports = { getList, getDetail, newBlog}
簡明扼要的說一下:防范xss攻擊的方式就是把特殊字符編碼
什么是特殊字符呢?
用戶輸入的數據進行HTML Entity編碼, 也就是對<script>、<a>等標簽的< >進行轉換,然后再保存到后臺數據庫。
例如:
在 input 輸入框 惡意輸入 <script> document.cookie </script>, 就會被轉換為下面的語句并存入數據庫:
<script> document.cookie </script>,已達到無法執行 <script> 的目的!!!!
最后
sql注入:竊取數據庫內容
XSS攻擊:竊取前端的cookie等敏感信息
密碼加密:保障用戶信息安全(重要)
DDOS攻擊:需要硬件和服務來支持(需要OP支持)
原文地址juejin.cn/post/684490…https://juejin.cn/post/6844904179085869063