Node.js如何创建一个只能访问SNS主题的API端点?

Node.js如何创建一个只能访问SNS主题的API端点?,node.js,amazon-web-services,Node.js,Amazon Web Services,我想从SNS向Node.js服务器上托管的公共API端点发送HTTP请求。但是,我想将该API配置为只接受来自该SNS主题的POST请求,而不接受其他任何请求。我可以在SNS消息中插入令牌,但我不能控制SNS消息。它来自SES,以防邮件被退回。是否可以查看请求的域并仅允许来自受信任域(本例中为AWS)?您不能将端点的可访问性限制为“仅SNS”-即使您知道SNS的IP地址范围,这也是有限的,因为任何人都可以使用SNS。这将是一种虚假的安全感 然而,SNS消息的设计方式应该是不需要通过IP地址限制端

我想从SNS向Node.js服务器上托管的公共API端点发送HTTP请求。但是,我想将该API配置为只接受来自该SNS主题的POST请求,而不接受其他任何请求。我可以在SNS消息中插入令牌,但我不能控制SNS消息。它来自SES,以防邮件被退回。是否可以查看请求的域并仅允许来自受信任域(本例中为AWS)?

您不能将端点的可访问性限制为“仅SNS”-即使您知道SNS的IP地址范围,这也是有限的,因为任何人都可以使用SNS。这将是一种虚假的安全感

然而,SNS消息的设计方式应该是不需要通过IP地址限制端点的可访问性。无论如何,你应该这样做

您应该验证亚马逊SNS发送的通知、订阅确认或取消订阅确认消息的真实性。使用Amazon SNS消息中包含的信息,您的端点可以重新创建要签名的字符串和签名,这样您就可以通过将您从消息内容中重新创建的签名与Amazon SNS随消息发送的签名相匹配来验证消息的内容

首先,HTTP请求头
x-amz-sns-topic-arn
标识主题。如果这不是您期望的主题,请不要处理该消息。如果此值与消息本身中的
TopicArn
不一致,请不要处理消息

接下来,消息正文包含一个
SigningCertURL
。这是您的代码获取SNS用于对消息签名的证书的URL。如果此URL的方案不是
https
,主机名不是
sns.[region].amazonaws.com
,则不下载证书,也不处理消息

否则,从提供的URL获取证书,并将其本地缓存在内存或磁盘中,这样您就不必在处理每一条消息时都获取证书(您通常会看到重复使用相同的证书)。确保您的用户代理未配置为不根据信任存储和请求主机名验证目标服务器的证书。在此配置中,您可以保证证书本身确实来自SNS,因为您的用户代理不会与具有不受信任证书的系统协商SSL,并且您已经验证了主机名是由AWS控制的

接下来,生成消息的规范散列,并根据消息提供的
签名对其进行验证,如上面链接中所述


如果消息确实来自SNS,那么签名将正确验证,并且消息应该被处理。否则,不应处理它。

您可以看到给定HTTP请求来自哪个IP地址。如果你能建立一个IP地址范围来表示来自SNS的请求的可能地址,那么你可以根据这个范围进行过滤。传入的请求不会告诉你它来自哪个域。您可以对IP地址进行反向查找,以尝试确定谁拥有该IP地址。谢谢您的建议,但我认为我可能需要更具体的内容。因为任何人都可以通过从AWS EC2服务器发送curl请求来利用此漏洞。我应该看看如何限制它只能从SNS服务访问。因为SNS通知只能在HTTP端点已订阅主题的情况下发送,所以我可以采用SNS将消息发送到SQS队列的替代方法,然后我可以将API更改为定期从SQS读取。我不需要它是实时的,所以这种方法应该有效。实际上,您可以从EC2实例中过滤出请求。以JSON格式的官方AWS IP范围为例,它包括EC2 IP范围:请阅读您的答案。实际上,我在查询参数中为我们订阅SNS的HTTP端点添加了一个令牌。但是您的方法更加健壮,我将改变我的实现。谢谢你的详细解释