云计算百科
云计算领域专业知识百科平台

C++后端编程 构建高性能后端的数据库、API 与 Web 服务器 10 保护你的 C++后端安全

后端安全概述

在后端开发中,安全性至关重要。 它有助于保护敏感数据,并确保应用程序持续正常运行。 在数据泄露和网络攻击日益普遍的当今时代,后端开发人员在保障应用安全方面扮演着前所未有的重要角色。 应用程序的后端是保护用户数据和维护系统完整性的首要防线。 后端安全漏洞可能造成毁灭性影响,对用户而言会导致身份盗用和欺诈,对企业则会造成经济损失和不可挽回的声誉损害。 这些影响对双方都可能是灾难性的。 因此,确保应用程序后端安全应当成为每个组织的首要任务。

在网络安全领域,保密性、完整性和可用性这三个概念通常被统称为 CIA 三要素。 这三个基本方面构成了后端安全的核心。 保密性承诺确保敏感信息仅限获得授权的人员查看。 完整性保证数据在其整个生命周期内始终保持真实可靠。 可用性则确保系统能在用户需要时随时可供访问。

数据库构成了后端安全系统中最基础的组成部分之一。 后端开发人员需要以正确的方式实现访问控制,以限制谁可以查看或修改数据。SQL 注入是一种常见的攻击形式,攻击者通过操纵输入来执行任意 SQL 命令。 主要针对终端用户但可能对后端系统造成严重后果的跨站脚本(XSS)和跨站请求伪造(CSRF)攻击,也是另一个需要关注的问题。

认证与授权同样是后端安全的关键组成部分。 认证是确认用户身份的过程,而授权则是决定已认证用户允许执行哪些操作的过程。 如果认证和授权实施不当,未经授权的用户可能会获取敏感数据和功能权限。

后端开发还涉及另一个重要关注点,即 API 安全性。 不安全的应用程序编程接口(API)可能导致数据泄露以及未经授权访问后端系统。 为确保应用程序编程接口(API)的安全,开发人员应采用加密通信协议(如 HTTPS),对 API 请求进行身份验证和授权,并验证和清理输入数据。

服务器的安全性也至关重要。 这包括确保服务器配置安全、保持软件最新版本以及监控任何异常活动。

必须仔细考虑整个后端的安全问题,从数据库到服务器。 后端开发人员在实施这些安全措施过程中发挥着重要作用,这不仅确保应用程序正常运行,也保障用户的福祉和对产品的持续信任。

数据库安全

数据库安全是一个广泛而复杂的领域,是后端应用程序开发的关键组成部分。 强大的数据库安全的重要性怎么强调都不为过,因为它保护着现代企业最有价值的资产:数据。 由于数据库通常存储着敏感和专有信息——客户资料、交易记录、财务信息——它们成为网络犯罪分子极具吸引力的目标。 如果数据库遭到入侵,后果可能包括数据丢失、法律追责,甚至对公司声誉造成无法挽回的损害。

数据库安全面临诸多威胁。 未经授权的访问是一个重大问题,攻击形式包括拥有过多权限的内部员工和突破外围防御的外部黑客。 这可能导致数据被盗、损坏甚至记录被完全删除。 注入攻击(如 SQL 注入)构成另一严重风险。 恶意构造的用户输入被用来操纵数据库查询,从而实现未经授权的数据查看或篡改。

数据库还可能面临加密不足的问题。 如果数据未正确加密或完全未加密,任何获取访问权限的人都能读取数据。 这对于传输中或备份存储的数据尤为危险。 数据库安全的另一风险是数据泄露。 配置不当的数据库可能无意间将敏感信息暴露在互联网上,使其成为网络犯罪分子的易得目标。 甚至数据库所在的硬件也可能成为安全隐患。 物理攻击、自然灾害和硬件故障都可能导致数据丢失。 虽然这些问题看似与"网络"关系不大,但仍属于广义的数据库安全范畴,需要采取物理安全措施和定期数据备份等防范手段。 除上述威胁外,软件过时也会使数据库变得脆弱。 旧版数据库管理系统可能存在已知安全漏洞,可能被攻击者利用。 定期打补丁和更新对降低此类风险至关重要。

在 GDPR 和 CCPA 等法规时代,数据库安全还具有法律意义。 未能充分保护用户数据可能导致巨额罚款和法律制裁,这使得数据库安全也成为合规性问题。 因此,需要采用多层面的数据库安全方法。 这包括严格的访问控制、有效的加密、定期软件更新、安全配置、强大的物理安全措施以及遵守相关法律法规。 本质上,必须采取一切措施将数据库从潜在的安全弱点转变为应用程序防御体系中强大且具有弹性的组成部分。

数据库安全是后端开发的关键环节,涉及保护数据免受从网络攻击到物理灾害等各种威胁。 通过实施强大的数据库安全措施,企业既能保护宝贵数据、维护用户信任并确保业务连续性,同时也能满足法律合规要求。

保护 MongoDB 数据库

保护 MongoDB 数据库需要执行几个关键步骤,这些步骤能显著提升数据安全性。 我们将以博客应用为例演示这些步骤:

启用访问控制

默认情况下,MongoDB 在无访问控制状态下运行,这意味着任何能访问服务器的人都可以操作所有数据库。 我们需要启用访问控制并定义可访问数据库的用户。

图 10.1 在 MongoDB 中启用访问控制

以下是语法:

# Switch to the admin database
> use admin
# Create a new user
> db.createUser(
{
user: "myUserAdmin",
pwd: "abc123",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)

该命令在 admin 数据库中创建用户 myUserAdmin,密码设为 abc123。 该用户被授予 userAdminAnyDatabase 角色,使其能够创建和管理任意数据库上的用户。

下一步,启用访问控制并重启 MongoDB 服务器:

mongod –auth

强制身份验证

启用访问控制后,客户端必须通过身份验证才能连接到您的 MongoDB 服务器。 使用以下命令进行身份验证:

mongo –username myUserAdmin –password abc123 –authenticationDatabase admin

使用 TLS/SSL

配置 MongoDB 对所有进出连接使用传输层安全协议(TLS)或其前身安全套接层(SSL)。 这可以保护"传输中"的数据——即从一个位置移动到另一个位置时的数据安全。 您需要生成(或购买)TLS/SSL 证书,然后使用–tlsMode 和–tlsCertificateKeyFile 选项启动服务器:

mongod –tlsMode requireTLS –tlsCertificateKeyFile /etc/ssl/mongodb.pem

基于角色的访问控制

仅向每个用户提供他们所需的权限。 如果用户只需要读取文档,就不要赋予他们写入数据库的权限。 例如在我们的博客应用中,可以设置具有添加和编辑文章权限的"writer"角色,以及仅能查看文章的"reader"角色。

# Switch to the blog database
> use blog
# Create a writer
> db.createUser(
{
user: "writer",
pwd: "abc123",
roles: [ { role: "readWrite", db: "blog" } ]
}
)
# Create a reader
> db.createUser(
{
user: "reader",
pwd: "abc123",
roles: [ { role: "read", db: "blog" } ]
}
)

加密存储引擎

为确保 MongoDB 数据库的安全性,使用 MongoDB 提供的加密存储引擎至关重要。WiredTiger 存储引擎提供静态数据加密功能,这意味着您的数据在非运行状态下存储于磁盘时会被加密。 但需注意,此功能仅在 MongoDB 企业版中提供。

定期更新

除了使用加密存储外,定期更新 MongoDB 服务器同样重要。 通过定期更新,您可以确保获得最新的安全增强功能和补丁。 定期更新有助于保护数据库免受潜在漏洞和威胁的侵害。

网络暴露

限制网络暴露是 MongoDB 安全体系中另一个关键组成部分。 不建议让您的 MongoDB 服务器直接通过互联网访问。 应当通过防火墙进行保护,仅开放绝对必要的端口。 这有助于防止未经授权的用户访问您的数据库。 您可以通过在 mongodb.conf 配置文件中设置 bindIp 选项,将连接限制为仅允许特定 IP 地址访问。 例如,若将 bindIp 设置为 127.0.0.1,则仅能接受来自本地的连接请求。

net:
bindIp: 127.0.0.1

限制网络暴露是 MongoDB 安全体系中另一个关键组成部分。 不建议让您的 MongoDB 服务器直接通过互联网访问。 应当通过防火墙进行保护,仅开放绝对必要的端口。 这有助于防止未授权用户访问您的数据库。 您可以通过配置 mongodb.conf 文件中的 bindIp 选项,将连接限制在特定 IP 地址范围内。 例如,如果将 bindIp 设置为 127.0.0.1,则仅能接受来自本地主机的连接。

用户认证与授权

保护 gRPC 服务安全涉及多个围绕认证和加密的步骤。 下面我将以我们的 C++博客应用为例,说明如何为 gRPC 添加安全机制。

SSL/TLS 加密

保护 gRPC 的第一步是使用 SSL/TLS 加密。 它能确保客户端与服务器之间传输的数据具有私密性和完整性。 以下是具体实现步骤:

首先,生成证书和私钥文件:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

然后,在服务器端创建一个 grpc::SslServerCredentials 对象,并在启动服务器时使用它:

std::string server_address("0.0.0.0:50051");
grpc::SslServerCredentialsOptions::PemKeyCertPair key_cert_pair = {read_key("key.pem"), read_cert("cert.pem")};
grpc::SslServerCredentialsOptions ssl_options;
ssl_options.pem_key_cert_pairs.push_back(key_cert_pair);
std::shared_ptr<grpc::ServerCredentials> creds = grpc::SslServerCredentials(ssl_options);
BlogServiceImpl service;
grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, creds);
builder.RegisterService(&service);
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());

在客户端,创建一个 grpc::SslCredentials 对象并在创建存根时使用它:

std::shared_ptr<grpc::ChannelCredentials> creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
auto channel = grpc::CreateChannel("localhost:50051", creds);
auto stub = BlogService::NewStub(channel);

基于令牌的身份验证

基于令牌的身份验证(如 JWT(JSON Web Tokens)或 OAuth)是后端安全的关键部分。 这种验证方法使服务器能够验证客户端身份,确保只有授权用户才能访问特定资源。

流程始于客户端登录,通常通过基于 HTTP 的登录 API 完成。 当客户端凭证验证通过后,服务器会返回一个令牌。 该令牌是代表客户端会话的唯一字符串。 客户端随后在每个后续 gRPC 调用的元数据中包含此令牌,从而在每个请求中有效证明其身份。

以下是客户端实现的一个示例:

grpc::ClientContext context;
context.AddMetadata("authorization", "Bearer " + token);

这段代码中,客户端创建了一个新的 gRPC 上下文,并将令牌添加到上下文的元数据中。 键名"authorization"用于表明该值是一个授权令牌。

在服务器端,您可以拦截传入的调用以检查令牌。 以下是一个示例展示如何实现:

class AuthInterceptor : public grpc::experimental::Interceptor {
public:
void Intercept(grpc::experimental::InterceptorContext* context) override {
auto metadata = context->client_metadata();
auto it = metadata.find("authorization");
if (it == metadata.end()) {
context->Finish(grpc::StatusCode::UNAUTHENTICATED, "No token provided");
return;
}
std::string token = it->second;
// Validate the token…
}
};

在此代码片段中,服务器拦截传入调用并检查客户端元数据中的授权令牌。 如果未找到令牌,服务器将以"UNAUTHENTICATED"状态码结束上下文,并返回提示未提供令牌的消息。

如果找到令牌,服务器随后会验证该令牌。 这通常包括检查令牌签名和过期时间,以确保其有效且未过期。 若令牌有效,服务器便可处理客户端请求。 若令牌无效或已过期,服务器可拒绝请求并返回相应的错误信息。

需注意的是,基于令牌的身份验证并不能替代 SSL/TLS。SSL/TLS 是用于加密网络连接的协议,对于确保令牌及其他敏感数据在传输过程中不被泄露至关重要。 即使采用基于令牌的身份验证,仍应使用 SSL/TLS 来保护连接安全并保障数据安全。

网络安全

网络安全是后端安全中不可忽视的关键环节。 它涉及实施各种措施来防止未经授权的访问、滥用、修改或拒绝网络可访问资源。 这对于暴露在互联网上的服务器尤为重要,因为它们往往是网络攻击的主要目标。

网络安全最基本且有效的措施之一就是使用防火墙。 防火墙是一种基于预设安全规则监控和控制进出网络流量的网络安全系统。 它在可信的内部网络与不可信的外部网络(如互联网)之间建立了一道屏障。 通过阻止未经授权的访问,防火墙能有效保护服务器及其存储的数据。 但仅部署防火墙并不足够。 确保服务器仅开放必要端口同样至关重要。 每个开放端口都可能成为攻击者的潜在入口点,因此减少开放端口数量能显著降低服务器的安全风险。

除了控制开放的端口外,您还应将服务器配置为仅接受来自可信 IP 地址的连接。 这可以通过 IP 白名单实现,该安全功能常用于限制并控制仅允许可信用户访问。IP 白名单允许您创建可信 IP 地址或 IP 范围列表,用户只能通过这些地址访问您的服务器。

以下示例展示了如何配置服务器仅接受特定 IP 地址的连接:

net:
bindIp: 192.0.2.1,203.0.113.1

在上述示例程序中,服务器被配置为仅接受来自 IP 地址 192.0.2.1 和 203.0.113.1 的连接。 来自其他 IP 地址的连接尝试都将被拒绝。 需要注意的是,网络安全是一个广泛领域,其范围远超 gRPC 或 C++范畴。 它涉及包括入侵检测系统(IDS)、入侵防御系统(IPS)和安全网络架构在内的多种实践与技术。

为 Web 服务器添加安全防护

为 Nginx 等 Web 服务器添加安全防护需要执行多项步骤,以确保通信安全、身份验证、授权机制完善,并防范常见的网络攻击。 以下指南将展示如何为我们的博客应用配置安全的 Nginx 环境:

HTTPS 配置

如前所述,使用 SSL/TLS 配置 HTTPS 是保护 Web 服务器的首要步骤之一。 它能加密客户端与服务器之间的通信流量。 我们已在先前章节中详细介绍了具体配置方法。

HTTP 安全头部

HTTP 安全头部通过帮助缓解攻击和安全漏洞,提供了额外的安全防护层。 一些重要的头部包括:

● X-Content-Type-Options:防止浏览器对声明的 content-type 进行 MIME 嗅探。

● X-Frame-Options:保护访客免受点击劫持攻击。

● X-XSS-Protection: 该响应头用于启用浏览器的跨站脚本攻击(XSS)过滤器。

将这些响应头添加到 Nginx 配置中,通常需要修改配置文件(位置一般为/etc/nginx/nginx.conf 或/etc/nginx/sites-available/default):

server {

add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";

}

请记得重新加载或重启 Nginx 以使更改生效。

速率限制

速率限制是一种限制网络流量的技术。 它设定了客户端在特定时间范围内可以重复特定请求的频率上限。 在 Nginx 中,您可以使用 limit_req 模块来设置速率限制。

以下是示例代码片段:

http {

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

server {

location /login {
limit_req zone=mylimit burst=20 nodelay;

}
}
}

此配置将/login 路径的请求限制为每秒 10 次。 若客户端超出此限制,Nginx 将返回 503 服务不可用错误。

隐藏 Nginx 版本号

默认情况下,Nginx 会在 HTTP 响应头和错误页面中包含其版本号。 这些信息可能被攻击者利用。 要隐藏版本号,请在配置文件中添加以下指令:

server_tokens off;

使用 Web 应用程序防火墙(WAF)

Web 应用程序防火墙(WAF)是任何 Web 服务器安全策略的关键组件。 它在您的 Web 应用程序和互联网之间充当防护盾,通过检查传入流量来阻止任何恶意请求。 这可以保护您的应用程序免受常见网络攻击,如 SQL 注入、跨站脚本(XSS)和跨站请求伪造(CSRF)。

Nginx 提供了一款可直接与服务器集成的商业 WAF 模块。 不过也有免费开源方案可供选择,例如 ModSecurity。ModSecurity 是一款广泛使用的 WAF,可配置用于检测和阻断各类攻击。 但需注意,使用 WAF 仅是整体安全策略的一个环节。 保持服务器及所有相关软件处于最新状态同样至关重要。 定期更新不仅能获得新功能和性能提升,更能修补可能被攻击者利用的安全漏洞。 除此之外,定期监控服务器日志也必不可少。 日志能提供服务器运行状态及潜在安全事件的重要信息。 一旦发生安全事件,快速响应对于控制影响范围和防止损失扩大至关重要。

总结

本章讨论了在后端基础设施各个层级实施安全措施的重要性及必要性。 在概述安全需求后,我们进一步探究了后端系统各层可能存在的潜在漏洞,以及采用多管齐下策略来保护系统的重大意义。

我们深入探讨了数据库安全的重要性,主要以 MongoDB 为例进行说明。 通过学习,我们掌握了如何通过实施用户认证和基于角色的授权机制,防止未经授权的访问 MongoDB 数据库。 此外,我们还强调了定期打补丁和更新、IP 白名单设置以及数据在存储和传输过程中加密的重要性。 接下来的章节重点介绍了 gRPC 安全,我们研究了多种认证和访问控制方法,包括基于令牌的认证、基于角色的访问控制以及用于加密通信的 SSL/TLS 协议。

结论部分着重强调了 Web 服务器安全的重要性,并以 Nginx 为例进行说明。 我们探讨了多种保护 Nginx 服务器安全的方法,包括配置 HTTPS 实现加密通信、添加 HTTP 安全头部防御常见 Web 攻击、实施速率限制防范暴力破解和 DoS 攻击、隐藏 Nginx 版本号避免暴露潜在漏洞,以及使用 Web 应用防火墙(WAF)来抵御各类基于 Web 的威胁。 本章始终强调实施全面安全策略的重要性,包括定期监控日志、更新软件和系统,以及对安全事件做出快速响应。

赞(0)
未经允许不得转载:网硕互联帮助中心 » C++后端编程 构建高性能后端的数据库、API 与 Web 服务器 10 保护你的 C++后端安全
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!