面试题答案
一键面试SQL注入
- 服务器端:
- 使用参数化查询:在Node.js中,对于MySQL数据库,使用
mysql
模块时可以这样做。例如:
- 使用参数化查询:在Node.js中,对于MySQL数据库,使用
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test'
});
const username = 'testUser';
const query = 'SELECT * FROM users WHERE username =?';
connection.query(query, [username], (error, results, fields) => {
if (error) throw error;
console.log(results);
});
connection.end();
- **输入验证**:使用`express-validator`库验证输入。例如:
const { check, validationResult } = require('express-validator');
const express = require('express');
const app = express();
app.post('/login', [
check('username').isLength({ min: 3 }),
check('password').isLength({ min: 6 })
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
// 处理登录逻辑
});
- 客户端:客户端一般不直接与数据库交互,主要是通过向服务器发送经过验证的数据。确保在发送数据前,数据已经按照服务器要求的格式进行了处理,比如在表单提交前,使用JavaScript验证输入格式。例如:
<!DOCTYPE html>
<html>
<head>
<title>Form Validation</title>
</head>
<body>
<form id="loginForm">
<label for="username">Username:</label>
<input type="text" id="username" name="username" />
<br />
<label for="password">Password:</label>
<input type="password" id="password" name="password" />
<br />
<input type="submit" value="Submit" />
</form>
<script>
document.getElementById('loginForm').addEventListener('submit', function (e) {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
if (username.length < 3) {
alert('Username must be at least 3 characters long');
e.preventDefault();
}
if (password.length < 6) {
alert('Password must be at least 6 characters long');
e.preventDefault();
}
});
</script>
</body>
</html>
XSS(跨站脚本攻击)
- 服务器端:
- 输出编码:在Node.js的Express应用中,使用
DOMPurify
库对输出到客户端的数据进行净化。例如:
- 输出编码:在Node.js的Express应用中,使用
const express = require('express');
const DOMPurify = require('dompurify');
const app = express();
app.get('/user/:username', (req, res) => {
const username = req.params.username;
const cleanUsername = DOMPurify.sanitize(username);
res.send(`Welcome, ${cleanUsername}`);
});
- 客户端:
- 设置HTTP - Only Cookies:在Node.js的Express应用中,可以设置
cookie-parser
中间件来设置HTTP - Only Cookies。例如:
- 设置HTTP - Only Cookies:在Node.js的Express应用中,可以设置
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser());
app.get('/setCookie', (req, res) => {
res.cookie('sessionId', '1234567890', { httpOnly: true });
res.send('Cookie set');
});
- **输入验证和过滤**:在客户端使用正则表达式等方法对输入进行验证。例如,验证输入是否为合法的URL:
function isValidURL(str) {
const pattern = new RegExp('^(https?:\\/\\/)?' + // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
'(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator
return pattern.test(str);
}
CSRF(跨站请求伪造)
- 服务器端:
- 使用CSRF令牌:在Node.js的Express应用中,使用
csurf
中间件。例如:
- 使用CSRF令牌:在Node.js的Express应用中,使用
const express = require('express');
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });
const app = express();
app.use(csrfProtection);
app.get('/form', (req, res) => {
res.render('form', { csrfToken: req.csrfToken() });
});
app.post('/submit', csrfProtection, (req, res) => {
// 处理表单提交
res.send('Form submitted successfully');
});
在HTML表单中需要包含CSRF令牌:
<!DOCTYPE html>
<html>
<head>
<title>CSRF Protected Form</title>
</head>
<body>
<form action="/submit" method="post">
<input type="hidden" name="_csrf" value="{{csrfToken}}">
<input type="submit" value="Submit">
</form>
</body>
</html>
- 客户端:确保在每次请求(特别是POST等修改数据的请求)中,携带服务器生成的CSRF令牌。在JavaScript中,从页面中获取CSRF令牌并添加到请求头或请求体中。例如,使用
fetch
:
const csrfToken = document.querySelector('input[name="_csrf"]').value;
fetch('/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify({ data: 'example' })
})
.then(response => response.json())
.then(data => console.log(data));