Hapi 框架向外提供 API 时遇到的安全问题

Hapi 是一个 Node.js 服务器框架,用于构建可扩展的网络应用程序。在向外提供 API 的过程中,Hapi 框架相比其他框架有更多的安全性设置。但是,在实际使用中,我们还需要注意一些常见的安全问题。

1. SQL 注入攻击

SQL 注入攻击是指攻击者向 Web 应用程序提交恶意的 SQL 语句,以便在数据库服务器上执行操作。Hapi 框架中针对 SQL 注入攻击的处理方式是使用 ORM 框架 Sequelize 保护数据库安全。在使用 Sequelize 时,需要注意以下内容:

  • 使用 Sequelize 中提供的参数占位符。
  • 不要直接使用用户提供的数据作为 SQL 查询的一部分。
  • 不要将 SQL 查询中的所有参数都传递给 Sequelize,只传递你需要的参数。

以下是使用 Sequelize 时的示例代码:

const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('mysql://user:password@localhost:3306/database');

sequelize.query('SELECT * FROM users WHERE username = :username', {
    replacements: {
        username: 'admin',
    },
    type: Sequelize.QueryTypes.SELECT,
});

2. 跨站脚本攻击(XSS)

跨站脚本攻击是指攻击者向 Web 页面注入恶意脚本,以便在用户的浏览器上执行操作。Hapi 框架中防止跨站脚本攻击的方式是使用视图引擎 Handlebars 和安全插件 crumb。在使用 Handlebars 和 crumb 时,需要注意以下内容:

  • 对用户输入的数据进行验证和过滤。
  • 在使用 Handlebars 渲染视图时,使用 Handlebars 提供的 escape 来转义用户输入的数据。
  • 在使用 crumb 插件时,根据需要配置 crumb 的 secret、key、cookieOptions 等参数。

以下是使用 Handlebars 和 crumb 时的示例代码:

const Hapi = require('@hapi/hapi');

const server = Hapi.server({
    port: 3000,
});

server.register(require('@hapi/vision'));
server.views({
    engines: {
        hbs: require('handlebars'),
    },
    path: __dirname + '/views',
    layout: 'layout',
    layoutPath: __dirname + '/views/layout',
    helpersPath: __dirname + '/views/helpers',
    partialsPath: __dirname + '/views/partials',
    isCached: false,
});

server.register(require('@hapi/crumb'), (err) => {
    if (err) {
        throw err;
    }

    server.views({
        context: {
            csrf: server.plugins.crumb.generate(request, reply),
        },
    });

    server.route({
        method: 'POST',
        path: '/post',
        config: {
            plugins: {
                crumb: true,
            },
            handler: (request, reply) => {
                reply().code(200);
            },
        },
    });
});

3. 跨站请求伪造(CSRF)

跨站请求伪造是指攻击者伪造一个 Web 页面请求,以便在用户的浏览器上执行操作。Hapi 框架中防止跨站请求伪造的方式是使用安全插件 crumb。在使用 crumb 时,需要注意以下内容:

  • 根据需要配置 crumb 的 secret、key、cookieOptions 等参数。
  • 在表单中使用 {{{ crumb.formField }}} 填充 CSRF token。

以下是使用 crumb 防止跨站请求伪造的示例代码:

const Hapi = require('@hapi/hapi');

const server = Hapi.server({
    port: 3000,
});

server.register(require('@hapi/crumb'), (err) => {
    if (err) {
        throw err;
    }

    server.route({
        method: 'POST',
        path: '/post',
        config: {
            plugins: {
                crumb: true,
            },
            handler: (request, reply) => {
                reply().code(200);
            },
        },
    });
});

server.views({
    context: {
        csrf: server.plugins.crumb.generate(request, reply),
    },
});

server.route({
    method: 'GET',
    path: '/form',
    handler: (request, reply) => {
        reply.view('form', {
            csrf: request.server.plugins.crumb.generate(request, reply),
        });
    },
});

server.route({
    method: 'POST',
    path: '/form',
    handler: (request, reply) => {
        reply('OK');
    },
});

4. HTTP 响应拆分攻击

HTTP 响应拆分攻击是指攻击者在一次 HTTP 响应中插入多个独立的 HTTP 响应,从而引起后续可能的攻击。Hapi 框架中的处理方式是使用内置的安全处理方法,例如:

  • 避免使用管道引擎(Pipe engine)。
  • 避免使用 chunked 传输编码(Transfer-Encoding: chunked)。
  • 避免在 HTTP 头中使用换行符号。

以下是在 Hapi 框架中设置 HTTP 响应头的示例代码:

const Hapi = require('@hapi/hapi');

const server = Hapi.server({
    port: 3000,
});

server.ext('onPreResponse', (request, h) => {
    const response = request.response;

    if (response.isBoom) {
        return h.continue;
    }

    response.header('X-Frame-Options', 'SAMEORIGIN');
    response.header('X-Content-Type-Options', 'nosniff');
    response.header('X-XSS-Protection', '1');

    return h.continue;
});

总结

在实际使用 Hapi 框架向外提供 API 的过程中,我们需要注意一些常见的安全问题,例如 SQL 注入攻击、跨站脚本攻击、跨站请求伪造和 HTTP 响应拆分攻击。为了保护 Web 应用程序的安全,我们需要使用相应的技术和工具,例如 ORM 框架 Sequelize、视图引擎 Handlebars 和安全插件 crumb。同时,我们需要遵循一些安全性最佳实践,例如对用户输入的数据进行验证和过滤,以便实现更加安全的 Web 应用程序。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65ac776eadd4f0e0ff60c12e