|
|
@@ -835,7 +835,8 @@ static CurlResponse performHttpRequest(
|
|
|
const nlohmann::json& headers,
|
|
|
const std::string& body,
|
|
|
long timeout_ms,
|
|
|
- bool follow_redirects
|
|
|
+ bool follow_redirects,
|
|
|
+ bool skip_tls_verify
|
|
|
) {
|
|
|
CurlResponse response;
|
|
|
|
|
|
@@ -850,6 +851,18 @@ static CurlResponse performHttpRequest(
|
|
|
// Set URL
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
|
|
|
|
+ // Certificate verification. Verify by default: CURLOPT_SSL_VERIFYPEER
|
|
|
+ // checks the chain and expiry, CURLOPT_SSL_VERIFYHOST checks the hostname
|
|
|
+ // in the certificate against the one being connected to. When a caller
|
|
|
+ // opts in to skipping verification we turn off only VERIFYPEER - the
|
|
|
+ // failure this exists for (an expired certificate) is a chain/expiry
|
|
|
+ // problem, not a wrong-host problem, and the hostname still being checked
|
|
|
+ // means the option cannot be used to quietly accept a certificate for a
|
|
|
+ // completely different site. Turning off VERIFYHOST as well would be the
|
|
|
+ // blunt instrument the request is deliberately not building.
|
|
|
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, skip_tls_verify ? 0L : 1L);
|
|
|
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
|
|
|
+
|
|
|
// Set method
|
|
|
if (method == "POST") {
|
|
|
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
|
|
@@ -1189,6 +1202,24 @@ static JSValue js_http_request(JSContext* ctx, JSValue this_val, int argc, JSVal
|
|
|
}
|
|
|
JS_FreeValue(ctx, follow_val);
|
|
|
|
|
|
+ // Skip TLS certificate verification. Off unless a node deliberately turns
|
|
|
+ // it on: doing so means anyone able to intercept the connection can
|
|
|
+ // impersonate the host, so this belongs on a specific request against a
|
|
|
+ // host the caller controls or a failure they have personally checked, not
|
|
|
+ // left on as a habit. A warning is logged every time it fires, naming the
|
|
|
+ // host, so it shows up in the log even for someone who never opens the
|
|
|
+ // workflow that set it.
|
|
|
+ bool skip_tls_verify = false;
|
|
|
+ JSValue skip_tls_val = JS_GetPropertyStr(ctx, options, "skipTlsVerify");
|
|
|
+ if (JS_IsBool(skip_tls_val)) {
|
|
|
+ skip_tls_verify = JS_ToBool(ctx, skip_tls_val);
|
|
|
+ }
|
|
|
+ JS_FreeValue(ctx, skip_tls_val);
|
|
|
+ if (skip_tls_verify) {
|
|
|
+ LOG_WARN("http.request {} {} - TLS certificate verification is disabled for this request, "
|
|
|
+ "host is not authenticated", method, url);
|
|
|
+ }
|
|
|
+
|
|
|
// Retry settings. Off unless asked for: a request that is not safe to repeat
|
|
|
// - a payment, a post - must not start retrying itself because a helper
|
|
|
// gained the ability. A node that wants it says so.
|
|
|
@@ -1251,7 +1282,7 @@ static JSValue js_http_request(JSContext* ctx, JSValue this_val, int argc, JSVal
|
|
|
for (int attempt = 1; attempt <= attempts; ++attempt) {
|
|
|
bool retryable = false;
|
|
|
try {
|
|
|
- response = performHttpRequest(method, url, headers, body, timeout_ms, follow_redirects);
|
|
|
+ response = performHttpRequest(method, url, headers, body, timeout_ms, follow_redirects, skip_tls_verify);
|
|
|
last_transport_error.clear();
|
|
|
retryable = isRetryableStatus(response.status_code, retry_statuses);
|
|
|
if (!retryable) {
|