mirror of
https://github.com/espressif/esp-idf.git
synced 2026-05-28 16:46:31 +03:00
fix(esp_http_client): require https->https for cross-scheme redirects
esp_http_client_set_redirection() now rejects any redirect target whose scheme is not https:// when the origin is HTTPS. This catches http, ftp, ws and any other scheme before client state is mutated. Same-host / https-to-https redirects are unaffected. Apps that intentionally want mixed-scheme redirects can set disable_auto_redirect=true and handle HTTP_EVENT_REDIRECT.
This commit is contained in:
@@ -682,6 +682,10 @@ static const esp_err_msg_t esp_err_msg_table[] = {
|
||||
# ifdef ESP_ERR_HTTP_INCOMPLETE_DATA
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_INCOMPLETE_DATA), /* 28684 0x700c Incomplete data received, less than
|
||||
Content-Length or last chunk */
|
||||
# endif
|
||||
# ifdef ESP_ERR_HTTP_REDIRECT_DOWNGRADE
|
||||
ERR_TBL_IT(ESP_ERR_HTTP_REDIRECT_DOWNGRADE), /* 28685 0x700d HTTPS origin redirected to a non-HTTPS
|
||||
scheme (downgrade blocked) */
|
||||
# endif
|
||||
// components/esp-tls/esp_tls_errors.h
|
||||
# ifdef ESP_ERR_ESP_TLS_BASE
|
||||
|
||||
@@ -1151,6 +1151,19 @@ esp_err_t esp_http_client_set_redirection(esp_http_client_handle_t client)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ESP_LOGD(TAG, "Redirect to %s", client->location);
|
||||
|
||||
/* On an HTTPS origin, only allow https:// redirect targets. Any other
|
||||
* scheme (http, ftp, ws, ...) is rejected before client state is
|
||||
* modified to prevent transport-layer downgrade attacks. */
|
||||
if (client->connection_info.scheme != NULL &&
|
||||
strcasecmp(client->connection_info.scheme, "https") == 0 &&
|
||||
strncasecmp(client->location, "https://", 8) != 0) {
|
||||
ESP_LOGE(TAG, "HTTPS origin can only redirect to https:// targets (got %s). "
|
||||
"Set disable_auto_redirect and handle manually if intended.",
|
||||
client->location);
|
||||
return ESP_ERR_HTTP_REDIRECT_DOWNGRADE;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_http_client_set_url(client, client->location);
|
||||
if (err == ESP_OK) {
|
||||
client->redirect_counter ++;
|
||||
@@ -1187,9 +1200,10 @@ static esp_err_t esp_http_check_response(esp_http_client_handle_t client)
|
||||
if (client->disable_auto_redirect) {
|
||||
http_dispatch_event(client, HTTP_EVENT_REDIRECT, NULL, 0);
|
||||
} else {
|
||||
if (esp_http_client_set_redirection(client) != ESP_OK){
|
||||
return ESP_FAIL;
|
||||
};
|
||||
esp_err_t redir_err = esp_http_client_set_redirection(client);
|
||||
if (redir_err != ESP_OK) {
|
||||
return redir_err;
|
||||
}
|
||||
}
|
||||
esp_http_client_redirect_event_data_t evt_data = {
|
||||
.status_code = client->response->status_code,
|
||||
|
||||
@@ -297,6 +297,7 @@ typedef enum {
|
||||
#define ESP_ERR_HTTP_RANGE_NOT_SATISFIABLE (ESP_ERR_HTTP_BASE + 10) /*!< HTTP 416 Range Not Satisfiable, requested range in header is incorrect */
|
||||
#define ESP_ERR_HTTP_READ_TIMEOUT (ESP_ERR_HTTP_BASE + 11) /*!< HTTP data read timeout */
|
||||
#define ESP_ERR_HTTP_INCOMPLETE_DATA (ESP_ERR_HTTP_BASE + 12) /*!< Incomplete data received, less than Content-Length or last chunk */
|
||||
#define ESP_ERR_HTTP_REDIRECT_DOWNGRADE (ESP_ERR_HTTP_BASE + 13) /*!< HTTPS origin redirected to a non-HTTPS scheme (downgrade blocked) */
|
||||
|
||||
/**
|
||||
* @brief Start a HTTP session
|
||||
|
||||
Reference in New Issue
Block a user