Selenium请求的HTTP标头中缺少引荐来源

fin*_*oot 10 python testing http-referer selenium http-headers

我正在用Selenium编写一些测试,并注意到,Referer标头中缺少该测试。我编写了以下最小示例,以使用https://httpbin.org/headers进行测试:

import selenium.webdriver

options = selenium.webdriver.FirefoxOptions()
options.add_argument('--headless')

profile = selenium.webdriver.FirefoxProfile()
profile.set_preference('devtools.jsonview.enabled', False)

driver = selenium.webdriver.Firefox(firefox_options=options, firefox_profile=profile)
wait = selenium.webdriver.support.ui.WebDriverWait(driver, 10)

driver.get('http://www.python.org')
assert 'Python' in driver.title

url = 'https://httpbin.org/headers'
driver.execute_script('window.location.href = "{}";'.format(url))
wait.until(lambda driver: driver.current_url == url)
print(driver.page_source)

driver.close()
Run Code Online (Sandbox Code Playgroud)

哪些打印:

<html><head><link rel="alternate stylesheet" type="text/css" href="resource://content-accessible/plaintext.css" title="Wrap Long Lines"></head><body><pre>{
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 
    "Accept-Encoding": "gzip, deflate, br", 
    "Accept-Language": "en-US,en;q=0.5", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "Upgrade-Insecure-Requests": "1", 
    "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0"
  }
}
</pre></body></html>
Run Code Online (Sandbox Code Playgroud)

所以没有Referer。但是,如果我浏览到任何页面并手动执行

window.location.href = "https://httpbin.org/headers"
Run Code Online (Sandbox Code Playgroud)

在Firefox控制台中,Referer 确实出现了预期的情况。


如以下评论中所指出的,使用时

driver.get("javascript: window.location.href = '{}'".format(url))
Run Code Online (Sandbox Code Playgroud)

代替

driver.execute_script("window.location.href = '{}';".format(url))
Run Code Online (Sandbox Code Playgroud)

该请求确实包含Referer。另外,当使用Chrome而不是Firefox时,两种方法都包括Referer

因此,主要问题仍然存在:Referer如上所述使用Firefox发送请求时,为什么请求中缺少它?

Deb*_*anB 6

Referer 根据 MDN 文档

Referer请求头中包含以前的web页面,从中当前请求页面的链接,随后的地址。该Referer头允许服务器,以确定那里的人们探访他们,并可以用来分析,记录,或优化的缓存数据,例如。

重要提示:尽管此标头有许多无害的用途,但它可能会对用户安全和隐私产生不良后果。

来源:https : //developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer


然而:

在以下情况下,浏览器不会发送 Referer 标头:

  • 引用资源是本地“文件”或“数据”URI。
  • 使用了不安全的 HTTP 请求,并且使用安全协议 (HTTPS) 接收了引用页面。

来源:https : //developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer


隐私和安全问题

RefererHTTP 标头存在一些隐私和安全风险:

Referer标头包含前一个网页,从中当前所请求的页面的链接之后,其可以进一步用于分析,记录,或优化高速缓存的地址。

来源:https : //developer.mozilla.org/en-US/docs/Web/Security/Referer_header : _privacy_and_security_concerns#The_referrer_problem


解决安全问题

Referer标题的角度来看,大多数安全风险可以通过以下步骤来缓解:

  • Referrer-Policy:使用Referrer-Policy服务器上的标头来控制通过 Referer 标头发送的信息。同样, no-referrer 指令将完全省略 Referer 标头。
  • referrerpolicy有泄露此类信息危险的 HTML 元素上的属性(例如<img><a>)。例如,这可以设置为no-referrer完全停止Referer发送标头。
  • 在有泄露此类信息危险的 HTML 元素(例如和)上rel设置为的属性。noreferrer<img><a>
  • 退出页面重定向技术:这是只应该在目前的工作没有缺陷的方法是有一个退出页面,你不介意具有内部referer头。许多网站都采用这种方法,包括 Google 和 Facebook。如果正确实施,它不会让引荐来源数据显示私人信息,而是仅显示用户来自的网站。http://example.com/user/foobar新的引用数据将显示为 ,而不是引用数据显示为http://example.com/exit?url=http%3A%2F%2Fexample.com。该方法的工作方式是将您网站上的所有外部链接转到中间页面,然后重定向到最终页面。下面我们有一个指向网站的链接example.com,我们对完整 URL 进行 URL 编码并将其添加到url退出页面的参数中。

资料来源:


这个用例

我已经通过 GeckoDriver/Firefox 和 ChromeDriver/Chrome 组合执行了您的代码:

代码块:

driver.get('http://www.python.org')
assert 'Python' in driver.title

url = 'https://httpbin.org/headers'
driver.execute_script('window.location.href = "{}";'.format(url))
WebDriverWait(driver, 10).until(lambda driver: driver.current_url == url)
print(driver.page_source)
Run Code Online (Sandbox Code Playgroud)

观察:

  • 使用 GeckoDriver/FirefoxReferer: "https://www.python.org/"标头丢失如下:

        {
          "headers": {
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", 
            "Accept-Encoding": "gzip, deflate, br", 
            "Accept-Language": "en-US,en;q=0.5", 
            "Host": "httpbin.org", 
            "Upgrade-Insecure-Requests": "1", 
            "User-Agent": "Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0"
          }
        }
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用ChromeDriver /铬Referer: "https://www.python.org/"头是如下:

        {
          "headers": {
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", 
            "Accept-Encoding": "gzip, deflate, br", 
            "Accept-Language": "en-US,en;q=0.9", 
            "Host": "httpbin.org", 
            "Referer": "https://www.python.org/", 
            "Upgrade-Insecure-Requests": "1", 
            "User-Agent": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36"
          }
        }
    
    Run Code Online (Sandbox Code Playgroud)

结论:

GeckoDriver/Firefox 在处理Referer标头时似乎存在问题。


奥特罗

推荐人政策

  • `execute_script` 的当前实现只是无法添加 `Referer` 标头。它与从您提到的转换中检索标题无关。 (4认同)
  • 根据您的结论,“Referer”的唯一方法是通过“execute_script”? (2认同)
  • BrowserMob 代理没有得到积极维护,并且已经 3 年没有发布了。我可以建议 BrowserUp 代理 http://browserup.com/blog/announcement-an-actively-maintained-fork-of-the-browsermob-proxy/ 它是 BrowserMob 代理的替代品,但添加了 HTTP/ 2、Brotli 支持,最高支持 Java 11(BrowserMob 只到 8),Modern Dependencies 和积极的维护者。 (2认同)