全面HTTPS化是目前互聯網的共識,基本上目前所有的瀏覽器均已經將使用HTTP協議或者部分HTTPS的站點表示爲了不安全。而且實現全面HTTPS化有一個協議很關鍵,那就是HSTS協議,而HSTS有賴於各個Web服務器和瀏覽器客戶端的支持,本文我們就來說說即將發佈Curl7.74對HSTS的支持。

概述

HSTS(HTTP Strict Transport Security,HTTP嚴格安全傳輸協議,是用於站點的標準HTTP響應標頭,用於告知客戶端在指定時間段內,該主機不接受純HTTP訪問,只使用HTTPS進行訪問。該協議在2012年的RFC 6797中提出。

由於歷史遺留原因或者考慮到兼容性問題,網站可能會同時支持通過HTTP和HTTPS訪問服務器資源,對http請求通過301/302跳轉到https,這樣就無法真正減少中間人攻擊,存在被劫持的風險。

HSTS和瀏覽器預加載

HSTS 主要是通過服務器發送Strict-Transport-Security頭的方式來控制瀏覽器操作:

首先在服務器響應頭中添加 HSTS 響應頭:

Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]

該響應頭只有在 https 訪問才生效,其中[ ]中的參數表示可選;max-age 參數爲設置的時間,建議爲6個月,即15552000秒。

典型一個nginx設置爲

server {

add_header Strict-Transport-Security "max-age=15552000; includeSubDomains; preload";

}

當用戶下次使用 HTTP 訪問,客戶端瀏覽器就會進行內部跳轉307 Redirect Interne,直接訪問HTTPS,而無任何HTTP請求。

開啓 HSTS後網站可以有效防範中間人劫持,無需301/302跳轉也可以調高網站性能和用戶訪問體驗。

HSTS的Strict-Transport-Security HTTP標頭爲流行瀏覽器中預加載列表之一。可以用他們預加載站點的系統設置。首次啓動瀏覽器時就已經知道其站點HSTS狀態。

Curl中HSTS的實現

預計在2020年12月發佈的curl 7.74.0開始,curl開始提供HSTS實驗性支持,默認情況不會啓用,不。

可以通過參數--enable-hsts手動啓動curl HSTS,使用--hsts <filename>來配置HSTS信息加載/保存高速緩存保存到文件,HSTS會被緩存,並在退出時進行更新。如果重複使用同一緩存文件進行調用,通過HSTS標頭,就可以有效地避免使用明文HTTP訪問。

libcurl

libcurl庫也加入了該功能,用來進行HTTP(S)傳輸的應用程序可以使用。使用libcurl,應用程序可以設置文件名以用於加載和保存高速緩存,還提供了一些附加選項,以提供更大的靈活性和功能:

CURLOPT_HSTS:允許設置一個文件名以從/向中讀取/寫入HSTS緩存。

CURL *curl = curl_easy_init();

if(curl) {

curl_easy_setopt(curl, CURLOPT_HSTS, "/home/user/.hsts-cache");

curl_easy_perform(curl);

CURLOPT_HSTS_CTRL:啓用此傳輸的HSTS功能。

CURL *curl = curl_easy_init();

if(curl) {

curl_easy_setopt(curl, CURLOPT_HSTS_CTRL, CURLHSTS_ENABLE);

curl_easy_perform(curl);

}

CURLOPT_HSTSREADFUNCTION:libcurl即將開始傳輸時,由libcurl調用該回調,並允許應用程序預加載HSTS條目,就像它們是通過curl讀取並添加到緩存中一樣。

{

/* set HSTS read callback */

curl_easy_setopt(curl, CURLOPT_HSTSREADFUNCTION, hstsread);

/* pass in suitable argument to the callback */

curl_easy_setopt(curl, CURLOPT_HSTSREADDATA, &hstspreload[0]);

result = curl_easy_perform(curl);

}

: libcurl刷新其內存中的緩存並允許應用程序將緩存保存在某處或類似的地方時,會重複調用此回調。

CURL *curl = curl_easy_init();

struct MyData this;

if(curl) {

curl_easy_setopt(curl, CURLOPT_URL, "127.0.0.1");

/* pass pointer that gets passed in to the

CURLOPT_HSTSREADFUNCTION callback */

curl_easy_setopt(curl, CURLOPT_HSTSREADDATA, &this);

curl_easy_perform(curl);

相關文章