在应用程序中存储主机和端口数据是否会使服务器容易受到攻击?

Does storing host and port data in an app make the server vulnerable?

我最近开始开发并且很纳闷。 每个前端应用程序都需要一个主机地址和服务端口来连接到后端服务器和数据库。 例如,当您在 React 中使用 fetch 时,您无法避免对服务器进行寻址,这可能会留下暴露的许多重要内部服务的痕迹,这些痕迹可以从源代码中提取。

这不会 使系统(后端服务器)暴露在外并容易受到攻击吗? 防止这种情况发生的最佳做法是什么?

我们公开的每个端点都容易受到攻击,但我们使用工具和技术来防止不同类型的攻击得逞。 关于 APIs,我们使用的一些技术是:

  • 监控和管理来自自动化脚本(机器人)的 API 调用
  • 放弃原始身份验证
  • 采取措施防止 API 复杂的类人机器人访问
  • 强加密
  • 部署基于令牌的速率限制 配备了根据 IP、会话和令牌数量限制API访问的功能
  • 在端点上实施强大的安全性

几乎所有网络技术都提供了客户端-服务器通信的安全实现,但是我们仍然需要监控并使用一些工具来帮助我们完成这个过程。

Shift of focus: The frontend doesn't matter

I think there is one essential misconception here: You do not expose the endpoint when you distribute sourcecode that contains its address. You expose your endpoint the moment you make it accessible.

Even if you never publish any app or any other kind of frontend that uses your endpoint: If your endpoint is reachable from any network where you could potentially have attackers, you should act as if these attackers existed.

It does not matter if you published your react app containing the hostname and port or not, the endpoint should have been secured the moment it was made accessible.

Example: SSH - remote access to servers

As a small example, take remote access to servers that can be done through SSH. If you've ever started a SSH server, you probably know that instantaneously, you will be target of hundreds up to thousands of login attempts per minute. This is just people "scanning" random IP addresses on the default SSH port and trying simple username/password combinations. They hope that they might find an insecure server they can take control over.

In this case - we haven't even announced or in any other way made public our address or port, and still we're experiencing these attacks.

Security by obscurity and Kerckhoff's Principle

Hoping that just because you didn't publicly say where people can access your database, noone will find out, is security through obscurity. You actually want to not do this. Instead, you want to follow Kerkhoff's Principle. The security of your system should not be dependant on you hiding where it can be accessed or similar attributes.

What to do

Usually, under these circumstances, you still want to protected a subset of these three attributes:

  • Confidentiality: You might want to keep certain data secret
  • Integrity: You do not want anybody to be able to manipulate your database
  • Availability: You want your backend to be available to real users, even when attackers are present

And now is the point where we can start thinking actual techniques to achieve this:

  • For confidentiality, we usually deploy encryption and authentication/authorization. Note that encryption on its own does not protect confidentiality: If the attacker starts an encrypted conversation with us, and we tell them our data, the encryption doesn't help.
  • For integrity, we usually want to limit write access to our resources. Here, we usually require authentication and authorization to change data in our database. For example, I might change my user profile here on Whosebug, but you can't. Note that this explicitly means one thing: You can not, under any circumstance, have database credentials in your frontend, be it an app or a website or whatever. You shouldn't have direct database access over the internet available, anyway. Instead, users should communicate with a backend endpoint that verifies the requested change, checks if the user is authorized to make the change, and only then pushes the change to the database.
  • For availability, it is critical that we usually have limited resources, and attackers can easily exhaust them using flooding attacks (example: SYN flooding). You usually want to set up some kind of rate limiting here. For the SSH example, there are programs like fail2ban. For your custom API endpoint, you probably want to have a reverse proxy in place that is configured to have rate limiting per IP address, or maybe even issue API tokens that users have to use and that allow you to identify and rate-limit users across IP addresses.

Bots and detecting them

To what Indrit wrote, I'd like to add: You can not distinguish proper users from bots. You can try, but you're on the disadvantageus side of this battle, and they can, from your point of view, look exactly the same as human users, so I'd advise you to not even try, and instead use mechanisms where you do not need to detect bots at all -- for example using API tokens to employ rate limiting (as Indrit already suggested), or proof of work.