MST

星途 面试题库

面试题:Node.js HTTP 服务针对常见 Web 攻击的防护策略

假设你负责维护一个基于 Node.js 的 HTTP 服务,阐述如何防范诸如 SQL 注入、XSS(跨站脚本攻击)和 CSRF(跨站请求伪造)等常见的 Web 攻击,每个攻击类型至少说明一种有效的防范措施及其在 Node.js 环境中的实现方式。
14.4万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

SQL 注入防范

  1. 使用参数化查询
    • 防范原理:参数化查询将 SQL 语句中的变量部分与 SQL 代码分离,数据库会将参数视为数据而不是可执行的 SQL 代码,从而避免恶意 SQL 代码的注入。
    • Node.js 实现方式:以使用 mysql2 库为例,假设连接到 MySQL 数据库。
const mysql = require('mysql2');

// 创建连接池
const pool = mysql.createPool({
  host: 'localhost',
  user: 'your_user',
  password: 'your_password',
  database: 'your_database'
});

const userId = 1; // 假设这是从用户输入获取的值
pool.query('SELECT * FROM users WHERE id =?', [userId], (err, results, fields) => {
  if (err) throw err;
  console.log(results);
});

在上述代码中,? 是参数占位符,[userId] 是实际参数值,这样可以防止用户输入恶意 SQL 代码改变查询逻辑。

XSS 防范

  1. 对用户输入进行转义
    • 防范原理:XSS 攻击利用的是在网页中注入恶意脚本,通过对用户输入进行转义,将特殊字符转换为无害的 HTML 实体,使得恶意脚本无法执行。
    • Node.js 实现方式:在 Express 框架中,可以使用 DOMPurify 库。首先安装 DOMPurifynpm install dompurify
const express = require('express');
const DOMPurify = require('dompurify');
const app = express();

app.use(express.urlencoded({ extended: true }));

app.post('/submit', (req, res) => {
  const userInput = req.body.input;
  const sanitizedInput = DOMPurify.sanitize(userInput);
  // 将 sanitizedInput 用于后续处理,如存储到数据库或显示在页面上
  res.send('Input received and sanitized:'+ sanitizedInput);
});

const port = 3000;
app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

在上述代码中,DOMPurify.sanitize 方法对用户输入进行了净化,去除了可能的恶意脚本。

CSRF 防范

  1. 使用 CSRF 令牌
    • 防范原理:CSRF 攻击是利用用户已登录的会话,伪造跨站请求。CSRF 令牌是一个随机生成的字符串,在用户登录时生成并存储在服务器端和用户的会话中。每次用户提交表单或发起请求时,服务器会验证请求中的 CSRF 令牌是否与会话中的令牌一致,不一致则拒绝请求。
    • Node.js 实现方式:在 Express 框架中,可以使用 csurf 库。首先安装 csurfnpm install csurf
const express = require('express');
const csrf = require('csurf');

const csrfProtection = csrf({ cookie: true });
const app = express();

app.use(express.urlencoded({ extended: true }));
app.use(csrfProtection);

app.get('/form', (req, res) => {
  res.send(`
    <form action="/submit" method="post">
      <input type="hidden" name="_csrf" value="${req.csrfToken()}">
      <input type="submit" value="Submit">
    </form>
  `);
});

app.post('/submit', csrfProtection, (req, res) => {
  res.send('Form submitted successfully');
});

const port = 3000;
app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

在上述代码中,csurf 中间件生成了 CSRF 令牌,在 HTML 表单中通过 req.csrfToken() 获取令牌并添加到隐藏输入字段中。在服务器端,csrfProtection 中间件验证请求中的 CSRF 令牌。