隐藏API URL并防止暴力攻击

时间:2015-12-16 15:00:59

标签: angularjs node.js api security

我刚刚在节点中构建了一个API。

我在我的角应用程序中调用此API来执行登录和注册等基础知识,例如:

self.register = function(username, password) {
  return $http.post(API + '/auth/register', {
      username: username,
      password: password
    })
}

所以我的问题是,任何人都可以看到API网址,所以最终阻止他们“抨击”它来创建用户。 (注意API是我的JS文件中的常量)。 登录也是如此,是什么阻止某人蛮力地尝试数以百万计的用户名和密码组合。

你有什么建议来确保这个?

感谢。

4 个答案:

答案 0 :(得分:4)

您可以使用一些DDoS保护,例如将nginx代理放在您的nodejs API前面并使用例如limit_req模块:http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

对于蛮力,您可以实施一些锁定逻辑,在错误数量将阻止帐户一段时间后,例如15-30分钟甚至需要管理员行动。

对于需要登录的API,您可以使用令牌保护。调用身份验证API时应发出令牌,并通过仅响应的HTTP安全cookie进行设置。然后,您可以在API请求标头中传递此标记,并在nodejs中执行每个受保护的API之前检查它是否有效,如果不是,则拒绝该呼叫。

答案 1 :(得分:1)

在scareddragon上+1。

如果您居住在云端,那么使用nginx有一个更好的,基于云的替代方案 - 使用云WAF(Web应用程序防火墙)作为DDoS缓解层。例如,查看Incapsula和CloudFlare。

如果DDoS是您的一个严重问题,并且您愿意支付防御费用,那么我绝对会向专家提出这个问题。

答案 2 :(得分:1)

您正在询问注册滥用和登录保护,基本上是:

  1. 如何减少帐户创建自动化?
  2. 如何减轻用户/密码猜测?
  3. 值得庆幸的是,这些问题主要解决了。

    为避免注册“抨击”,您需要中断自动化。这可以通过各种方法实现,从松散到严格:

    1. 如果API仅供特定应用/浏览器访问,则可以过滤掉所有其他访问者
    2. 按会话/ IP进行的速率限制注册
    3. 要求传递CAPTCHA
    4. 验证电子邮件地址
    5. 要求提供私人敏感信息作为身份证明(例如,电话号码,信用卡)
    6. 这有什么好处,1-3是可以轻松卸载到现代Web Application Firewall的任务,无需任何额外的服务器端编码或额外负载。

      对于“登录保护”,除了上述方法1-3之外,还有两个建议:

      1. Two-Factor Authentication(2FA) - 这基本上意味着除了“常规”密码之外,用户还需要输入另一个身份验证令牌。此令牌可以由TOTP(请参阅Google身份验证器)生成,也可以由服务器通过短信,电子邮件,电话等发送的代码生成。

      2. API Keys - 这被认为更安全,因为API密钥通常是非常长的唯一字符串,具有非常好的熵(与用户/密码组合相比)。有关API密钥here的更多信息。

      3. 在我走之前,一句小话:我之前看过一些关于DDoS的评论,我不能强调这一点 - 你不能自己减轻DDOS。但这是针对不同的主题。

        祝你好运!

答案 3 :(得分:0)

最好通过IP限制反向代理,负载均衡器或任何其他入口点的速率。

如果您希望在nodejs中执行此操作,建议使用rate-limiter-flexible

const { RateLimiterRedis } = require('rate-limiter-flexible');
const Redis = require('ioredis');

const redisClient = new Redis({
  options: {
    enableOfflineQueue: false
  }
});

const opts = {
  redis: redisClient,
  points: 5, // 5 points
  duration: 15 * 60, // Per 15 minutes
  blockDuration: 15 * 60, // block for 15 minutes if more than points consumed 
};

const rateLimiter = new RateLimiterRedis(opts);

self.register = async function(username, password) {
  let blocked = false;
  try {
    await rateLimiter.consume(clientIP, 1);
  } catch() {
    blocked = true;
  }

  if (blocked) {
    return false;
  }

  return $http.post(API + '/auth/register', {
      username: username,
      password: password
    })
}
相关问题