问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Microsoft Azure Web App - Error 404

创作时间:
作者:
@小白创作中心

Microsoft Azure Web App - Error 404

引用
CSDN
1.
https://blog.csdn.net/2404_88048702/article/details/144493810

本文深入探讨了HTTP请求头中的"Host"字段,从其基本概念到安全风险,再到具体的防护措施,为读者提供了一篇全面的技术指南。

什么是Host字段

在HTTP请求头中,"Host"字段是一个至关重要的部分。它告诉服务器,我们访问的目标域名是什么。这在共享IP地址的服务器上尤其重要,因为同一台服务器上可能托管了多个不同的网站。

Host字段的基本用法

当我们在浏览器中输入一个网址并发出请求时,Host字段指明了目标服务器的域名。例如,对于网址http://www.example.com/page1.html,HTTP请求会是这样的:

GET /page1.html HTTP/1.1
Host: www.example.com

这一行告诉服务器,我们请求的是www.example.com这个站点的page1.html页面。

虚拟主机的使用

在现代服务器配置中,虚拟主机允许在同一台服务器上托管多个网站。例如:

  • site-a.example.com
  • site-b.example.com

这两个站点共享同一个IP地址,但通过Host头来区分请求。

访问site-a.example.com时:

GET /page1.html HTTP/1.1
Host: site-a.example.com

访问site-b.example.com时:

GET /page1.html HTTP/1.1
Host: site-b.example.com

即使请求的路径相同,服务器依然能够通过不同的Host头来区分、解析正确的站点并返回相应内容。

安全风险:HTTP主机头攻击

"Host"字段使用不当可能导致安全风险,最常见的是HTTP主机头攻击(Host Header Injection)。这种攻击通过篡改Host头,使服务器误认为请求来自可信的域名,从而进行一系列恶意行为。

攻击示例

假如我们访问http://site-a.example.com/page1.html,但伪造Host头为site-b.example.com

GET /page1.html HTTP/1.1
Host: site-b.example.com

如果服务器未对Host头进行验证,可能会将请求错误地路由到site-b.example.com站点,带来安全隐患。

REST/OData服务案例

@odata.context相关的风险

@odata.context是OData响应中的一个特殊字段,用于说明返回数据的结构和上下文。它通常包含一个指向元数据文档的URL。如果Host头被篡改,这个字段中的URL可能会指向错误或者恶意的主机名。

OData响应示例

假设我们有一个正常的OData响应:

{
  "@odata.context": "https://trusted.com/odata/$metadata#Products",
  "value": [
    {
      "ProductID": 1,
      "ProductName": "Chai",
      "Category": "Beverages",
      "Price": 18.00
    },
    {
      "ProductID": 2,
      "ProductName": "Chang",
      "Category": "Beverages",
      "Price": 19.00
    }
  ]
}

如果被攻击者篡改了Host头,响应可能变成:

{
  "@odata.context": "https://evil.com/odata/$metadata#Products",
  "value": [
    {
      "ProductID": 1,
      "ProductName": "Chai",
      "Category": "Beverages",
      "Price": 18.00
    },
    {
      "ProductID": 2,
      "ProductName": "Chang",
      "Category": "Beverages",
      "Price": 19.00
    }
  ]
}

这种情况下,@odata.context的值被篡改成了https://evil.com/odata/$metadata#Products,这可能导致客户端使用错误的元数据URI,从而带来安全问题。

我们来测试一下OData官网的service,将HOST篡改成abc,如下:

curl 'https://services.odata.org/V4/Northwind/Northwind.svc/Customers?$format=json' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
  -H 'Accept-Language: en-US,en;q=0.9' \
  -H 'Cache-Control: max-age=0' \
  -H 'Connection: keep-alive' \
  -H 'HOST: abc' \
  -H 'Sec-Fetch-Dest: document' \
  -H 'Sec-Fetch-Mode: navigate' \
  -H 'Sec-Fetch-Site: none' \
  -H 'Sec-Fetch-User: ?1' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' \
  -H 'sec-ch-ua: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "macOS"'

服务返回:

<title>Microsoft Azure Web App - Error 404</title>

由此可见,这个OData服务还是对HOST做了一定的检测和防范的。

缓解措施

  1. 验证Host头:确保服务器配置中严格验证Host头,只接受合法的域名。例如,在Nginx中如下配置:
server {
    listen 80;
    server_name site-a.example.com;
    if ($host !~ ^(site-a\.example\.com|site-b\.example\.com)$ ) {
        return 444;  # 立即终止连接
    }
    location / {
        root /var/www/site-a;
    }
}
  1. 使用https和hsts:强制所有请求通过HTTPS进行传输,防止传输过程中篡改请求头信息。
  2. 配置WAF:使用Web应用防火墙(WAF),如AWS WAF、Cloudflare WAF来检测并防御伪造的Host头攻击。
  3. 反向代理的验证:在反向代理服务器中进行Host头的过滤和验证。

示例 - 在Flask中验证Host头

我们可以像这样在Flask应用中进行Host头的验证:

from flask import Flask, request, abort
app = Flask(__name__)
trusted_hosts = ['site-a.example.com', 'site-b.example.com']
@app.before_request
def verify_host():
    if request.host not in trusted_hosts:
        abort(400)  # 拒绝不合法的请求
@app.route('/page1.html')
def page1():
    return "This is the content of page1.html"
if __name__ == "__main__":
    app.run()

在Apache HTTPD中缓解Host Header攻击

要在Apache HTTPD中防止Host Header攻击,可以使用以下几种方法:

  1. 使用虚拟主机配置:确保所有虚拟主机都明确设置ServerName和ServerAlias。
<VirtualHost *:80>
    ServerName site-a.example.com
    ServerAlias www.site-a.example.com
    DocumentRoot /var/www/site-a
    <Directory /var/www/site-a>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
<VirtualHost *:80>
    ServerName site-b.example.com
    ServerAlias www.site-b.example.com
    DocumentRoot /var/www/site-b
    <Directory /var/www/site-b>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
  1. 使用mod_rewrite模块:检查并验证Host头,如果不匹配预期的域名,则拒绝请求。
<VirtualHost *:80>
    ServerName site-a.example.com
    DocumentRoot /var/www/site-a
    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^site-a\.example\.com$ [NC]
    RewriteRule ^ - [F]
</VirtualHost>
<VirtualHost *:80>
    ServerName site-b.example.com
    DocumentRoot /var/www/site-b
    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^site-b\.example\.com$ [NC]
    RewriteRule ^ - [F]
</VirtualHost>
  1. 使用mod_headers模块:强制设置Host头,确保其始终匹配预期的域名。
<VirtualHost *:80>
    ServerName site-a.example.com
    DocumentRoot /var/www/site-a
    <IfModule mod_headers.c>
        RequestHeader set Host "site-a.example.com"
    </IfModule>
</VirtualHost>
<VirtualHost *:80>
    ServerName site-b.example.com
    DocumentRoot /var/www/site-b
    <IfModule mod_headers.c>
        RequestHeader set Host "site-b.example.com"
    </IfModule>
</VirtualHost>

通过这些配置,可以有效地防止HTTP主机头攻击,确保服务器的稳定性和安全性。

总结

"Host"字段在HTTP请求中有着重要作用,并在虚拟主机、代理服务器和安全访问等多个场景中得到广泛应用。然而,使用不当也可能带来安全风险,如HTTP主机头攻击。通过严格验证Host头、使用HTTPS和HSTS、配置WAF以及反向代理验证等多种手段,可以有效防范此类攻击,保障应用安全。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号