当前位置:   article > 正文

node JS 中安全和防范之 sql 注入、XSS攻击 和 密码加密_node.js需要防sql注入吗

node.js需要防sql注入吗
一、安全
  1. 对于安全,如下所示:
  • sql 注入:窃取数据库内容
  • XSS 攻击:窃取前端的 cookie 内容
  • 密码加密:保障用户信息安全
  • server 端攻击方式非常多,预防手段也非常多
  • nodejs 可以通过 web server 层面预防
  • 有些攻击需要硬件和服务来支持,需要 OP 支持,如 DDOS
二、sql 注入
  1. sql 注入,如下所示:
  • 最原始、最简单的攻击,从有了 web2.0 就有了 sql 注入攻击
  • 攻击方式:输入一个 sql 片段,最终拼接成一段攻击代码
  • 预防措施:使用 MySQLescape 函数处理输入内容即可
  1. sql 注入在 nodeJS 项目中的应用,如下所示:
  • db.js,代码如下所示:
const env = process.env.NODE_ENV // 环境参数

// 配置
let MYSQL_CONF
let REDIS_CONF

if (env === 'dev') {
  // mysql
  MYSQL_CONF = {
    host: 'localhost',
    user: 'root',
    password: '123456',
    port: '3306',
    database: 'nodeblog'
  }

  // redis
  REDIS_CONF = {
    port: 6379,
    host: '127.0.0.1'
  }
}

if (env === 'product') {
  // mysql
  MYSQL_CONF = {
    host: 'localhost',
    user: 'root',
    password: '123456',
    port: '3306',
    database: 'nodeblog'
  }

  // redis
  REDIS_CONF = {
    port: 6379,
    host: '127.0.0.1'
  }
}

module.exports = {
  MYSQL_CONF,
  REDIS_CONF
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • mysql.js,代码如下所示:
const mysql = require('mysql')
const { MYSQL_CONF } = require('../config/db')

// 创建连接对象
const con = mysql.createConnection(MYSQL_CONF)

// 开始连接
con.connect()

// 统一执行的 sql 的函数
function exec (sql) {
  // 返回 promise 对象
  const promise = new Promise((resolve, reject) => {
    con.query(sql, (err, result) => {
      if (err) {
        // console.error(err)
        reject(err)
        return
      }
      // console.log(result)
      resolve(result)
    })
  })

  return promise
  
}

module.exports = {
  exec,
  escape: mysql.escape
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • user.js,代码如下所示:
const { exec, escape } = require('../db/mysql')

const login = (username, password) => {

  username = escape(username)
  password = escape(password)

  const sql = `select username, realname from users where username=${username} and password=${password};`
  
  return exec(sql).then(rows => {
    return rows[0] || {}
  })
}

module.exports = {
  login
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
三、XSS 攻击
  1. XSS 攻击,如下所示:
  • 攻击方式:在页面展示内容中掺杂 js 代码,以获取网页信息
  • 预防措施:转换生成 js 的特殊字符
  1. XSS 攻击在 nodeJS 项目的应用,如下所示:
  • 通过 npm i xss --save 命令下载 xss 模块
  • blog.js 中,代码如下所示:
const xss = require('xss')
const title = xss(blogData.title)

  • 1
  • 2
  • 3
  • 完整 blog.js,代码如下所示:
// controller 只关心数据
const { exec } = require('../db/mysql')
const xss = require('xss')

const getList = (author, keyword) => {
  // 先返回假数据,格式是正确的
  let sql = `select * from blogs where 1=1 `
  if (author) {
    sql += `and author='${author}' `
  }
  if (keyword) {
    sql += `and title like '%${keyword}%' `
  }
  sql += `order by createtime desc;`

  // 返回 promise
  return exec(sql)
}


const getDetail = (id) => {
  // 先返回的数据
  const sql = `select * from blogs where id='${id}'`
  return exec(sql).then(rows => {
    return rows[0]
  })
}


const newBlog = (blogData = {}) => {
  // blogData 是一个博客对象,包含 title、content 属性
  // console.log('newBlog blogData...', blogData)

  const title = xss(blogData.title)
  const content = xss(blogData.content)
  const author = blogData.author
  const createtime = Date.now()

  const sql = `insert into blogs (title, content, createtime, author)
              values ('${title}', '${content}', ${createtime}, '${author}');`
  
  return exec(sql).then(insertData => {
    console.log('insertData is ', insertData)
    return {
      id: insertData.insertId
    }
  })

}


const updateBlog = (id, blogData = {}) => {
  // id 就是要更新博客的 id
  // blogData 是一个博客对象,包含 title、content 属性
  
  const title = xss(blogData.title)
  const content = xss(blogData.content)

  const sql = `update blogs set title='${title}', content='${content}' where id=${id}`

  return exec(sql).then(updateData => {
    console.log('updateData is', updateData)
    if (updateData.affectedRows > 0) {
      return true
    }
    return false
  })
}


const deleteBlog = (id, author) => {
  // id 就是要更新博客的 id
  const sql = `delete from blogs where id=${id} and author='${author}';`

  return exec(sql).then(delData => {
    if (delData.affectedRows > 0) {
      return true
    }
    return false
  })
}


module.exports = {
  getList,
  getDetail,
  newBlog,
  updateBlog,
  deleteBlog
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
四、密码加密
  1. 密码加密,如下所示:
  • 万一数据库被用户攻破,最不该泄露的就是用户信息
  • 攻击方式:获取用户名和密码,再去尝试登陆其他系统
  • 预防措施:将密码加密,即便拿到密码也不知道明文
  1. 密码加密在 nodeJS 项目中的应用,如下所示:
  • cryp.js,代码如下所示:
const crypto = require('crypto')

// 密钥
const SECRET_KEY = 'Wzs_sd274#'

// md5 加密
function md5(content) {
  let md5 = crypto.createHash('md5')
  return md5.update(content).digest('hex')
}

// 加密函数
function genPassword(password) {
  const str = `password=${password}&key=${SECRET_KEY}`
  return md5(str)
}

// const result = genPassword('123')
// console.log(result)

module.exports = {
  genPassword
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • user.js,代码如下所示:
const { exec, escape } = require('../db/mysql')
const { genPassword } = require('../utils/cryp')

const login = (username, password) => {
  // 先使用假数据
  // if (username === 'zhangsan' && password === '123') {
  //   return true
  // }
  // return false

  username = escape(username)
  
  // 生成加密密码
  password = genPassword(password)
  password = escape(password)

  const sql = `select username, realname from users where username=${username} and password=${password};`
  
  return exec(sql).then(rows => {
    return rows[0] || {}
  })
}

module.exports = {
  login
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/582928
推荐阅读
相关标签
  

闽ICP备14008679号