Tyk Hybrid SSL not working with IE11

I recently installed the Tyk Hybrid Gateway using the instructions at this link:

https://tyk.io/docs/get-started/with-tyk-hybrid/tutorials/install-hybrid-gateway/

My Docker installation on Ubuntu was successful, and I was able to build a working developer portal from the various tutorials on the Tyk site.

The developer portal works as expected (i.e. the “Try It Out” feature) using HTTP with the Chrome and IE11 browsers on Windows 7.

The developer portal also works as expected using HTTPS with the Chrome browser.

However, the developer portal does not work as expected using HTTPS with the IE11 browser. The F12 developer tool in IE11 shows that a CORS preflight was being made when the following error occurred:

SCRIPT7002: XMLHttpRequest: Network Error: 0x80070005, Access is denied.

After Googling around, I found this link that explains why the CORS preflight might be getting aborted in IE11 (Microsoft Bug 1028302):

https://connect.microsoft.com/IE/feedback/details/1028302/ie11-cors-preflight-request-is-aborted-when-server-requests-client-tls-certificate

Apparently, if IE11 sees a server ask for a client certificate on the CORS preflight, it just gives up immediately. It does not even attempt to complete the SSL handshake.

I was able to verify that this was happening in my case with this openssl command:

openssl s_client -connect :8080 -CAfile rootcert.pem -state

Any idea why the Tyk Hybrid Gateway would be asking for a client certificate during the SSL handshake when my gateway was set up for “Auth Token” authentication? I did not select “Mutual TLS” authentication.

1 Like

Can you pls provide your API definition and Tyk config (if there are any custom changes).

Here’s my redacted API definition:

{
“id”: “XXXXXXXXXXXXXXXXXXXXXXXX”,
“name”: “XXXXXXXXXXXXXXX”,
“slug”: “XXXXXXXXXXXXXXX”,
“api_id”: “XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”,
“org_id”: “XXXXXXXXXXXXXXXXXXXXXXXX”,
“use_keyless”: false,
“use_oauth2”: false,
“use_openid”: false,
“openid_options”: {
“providers”: ,
“segregate_by_client”: false
},
“oauth_meta”: {
“allowed_access_types”: ,
“allowed_authorize_types”: ,
“auth_login_redirect”: “”
},
“auth”: {
“use_param”: false,
“param_name”: “”,
“use_cookie”: false,
“cookie_name”: “”,
“auth_header_name”: “Authorization”,
“use_certificate”: false
},
“use_basic_auth”: false,
“use_mutual_tls_auth”: false,
“client_certificates”: ,
“upstream_certificates”: {},
“enable_jwt”: false,
“use_standard_auth”: true,
“enable_coprocess_auth”: false,
“jwt_signing_method”: “”,
“jwt_source”: “”,
“jwt_identity_base_field”: “”,
“jwt_client_base_field”: “”,
“jwt_policy_field_name”: “”,
“notifications”: {
“shared_secret”: “”,
“oauth_on_keychange_url”: “”
},
“enable_signature_checking”: false,
“hmac_allowed_clock_skew”: -1,
“base_identity_provided_by”: “”,
“definition”: {
“location”: “header”,
“key”: “version”
},
“version_data”: {
“not_versioned”: true,
“versions”: {
“v1”: {
“name”: “v1”,
“expires”: “”,
“paths”: {
“ignored”: ,
“white_list”: ,
“black_list”:
},
“use_extended_paths”: true,
“extended_paths”: {},
“global_headers”: {
“Authorization”: “Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”
},
“global_headers_remove”: [
“Authorization”
],
“global_size_limit”: 0,
“override_target”: “”
}
}
},
“uptime_tests”: {
“check_list”: ,
“config”: {
“expire_utime_after”: 0,
“service_discovery”: {
“use_discovery_service”: false,
“query_endpoint”: “”,
“use_nested_query”: false,
“parent_data_path”: “”,
“data_path”: “”,
“port_data_path”: “”,
“target_path”: “”,
“use_target_list”: false,
“cache_timeout”: 60,
“endpoint_returns_list”: false
},
“recheck_wait”: 0
}
},
“proxy”: {
“preserve_host_header”: false,
“listen_path”: “/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/”,
“target_url”: “https://XXXXXXXXXXXXXXXXXXX.com/XXXXXXXXXXXXXX/XXX/XXXXXXXXXXX/”,
“strip_listen_path”: true,
“enable_load_balancing”: false,
“target_list”: ,
“check_host_against_uptime_tests”: false,
“service_discovery”: {
“use_discovery_service”: false,
“query_endpoint”: “”,
“use_nested_query”: false,
“parent_data_path”: “”,
“data_path”: “”,
“port_data_path”: “”,
“target_path”: “”,
“use_target_list”: false,
“cache_timeout”: 0,
“endpoint_returns_list”: false
}
},
“disable_rate_limit”: false,
“disable_quota”: false,
“custom_middleware”: {
“pre”: ,
“post”: ,
“post_key_auth”: ,
“auth_check”: {
“name”: “”,
“path”: “”,
“require_session”: false
},
“response”: ,
“driver”: “”,
“id_extractor”: {
“extract_from”: “”,
“extract_with”: “”,
“extractor_config”: {}
}
},
“custom_middleware_bundle”: “”,
“cache_options”: {
“cache_timeout”: 0,
“enable_cache”: false,
“cache_all_safe_requests”: false,
“cache_response_codes”: ,
“enable_upstream_cache_control”: false
},
“session_lifetime”: 0,
“active”: true,
“auth_provider”: {
“name”: “”,
“storage_engine”: “”,
“meta”: {}
},
“session_provider”: {
“name”: “”,
“storage_engine”: “”,
“meta”: {}
},
“event_handlers”: {
“events”: {}
},
“enable_batch_request_support”: false,
“enable_ip_whitelisting”: false,
“allowed_ips”: ,
“dont_set_quota_on_create”: false,
“expire_analytics_after”: 0,
“response_processors”: ,
“CORS”: {
“enable”: false,
“allowed_origins”: ,
“allowed_methods”: ,
“allowed_headers”: ,
“exposed_headers”: ,
“allow_credentials”: false,
“max_age”: 0,
“options_passthrough”: true,
“debug”: false
},
“domain”: “”,
“do_not_track”: false,
“tags”: ,
“enable_context_vars”: false,
“config_data”: {},
“tag_headers”: ,
“global_rate_limit”: {
“rate”: 0,
“per”: 0
},
“strip_auth_data”: false
}

And here’s my redacted Tyk config:

{
“http_server_options”: {
“use_ssl”: true,
“server_name”: “XXXXXXXXX.XXX.com”,
“min_version”: 771,
“certificates”: [
{
“domain_name”: “*.XXX.com”,
“cert_file”: “/etc/ssl/certs/XXX.crt”,
“key_file”: “/etc/ssl/certs/XXX.key”
}
]
},
“listen_port”: 8080,
“secret”: “XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”,
“template_path”: “./templates”,
“tyk_js_path”: “./js/tyk.js”,
“middleware_path”: “./middleware”,
“use_db_app_configs”: false,
“app_path”: “./apps/”,
“storage”: {
“type”: “redis”,
“host”: “localhost”,
“port”: 6379,
“username”: “”,
“password”: “”,
“database”: 0,
“optimisation_max_idle”: 500
},
“enable_analytics”: true,
“analytics_config”: {
“type”: “rpc”,
“csv_dir”: “/tmp”,
“mongo_url”: “localhost”,
“mongo_db_name”: “tyk_analytics”,
“mongo_collection”: “tyk_analytics”,
“purge_delay”: 10,
“ignored_ips”: ,
“enable_geo_ip”: true,
“geo_ip_db_path”: “/opt/tyk-gateway/GeoLite2-City.mmdb”,
“normalise_urls”: {
“enabled”: true,
“normalise_uuids”: true,
“normalise_numbers”: true,
“custom_patterns”:
}
},
“health_check”: {
“enable_health_checks”: false,
“health_check_value_timeouts”: 60
},
“optimisations_use_async_session_write”: true,
“allow_master_keys”: false,
“policies”: {
“policy_source”: “rpc”,
“policy_record_name”: “tyk_policies”
},
“hash_keys”: true,
“suppress_redis_signal_reload”: false,
“use_sentry”: false,
“sentry_code”: “”,
“enforce_org_data_age”: true,
“http_server_options”: {
“enable_websockets”: true
},
“monitor”: {
“enable_trigger_monitors”: true,
“configuration”: {
“method”: “POST”,
“target_path”: “http://cloud.tyk.io/1337/tyk/webhook”,
“template_path”: “templates/monitor_template.json”,
“header_map”: {“x-tyk-monitor-secret”: “XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”},
“event_timeout”: 10
},
“global_trigger_limit”: 80.0,
“monitor_user_keys”: false,
“monitor_org_keys”: true
},
“slave_options”: {
“use_rpc”: true,
“rpc_key”: “XXXXXXXXXXXXXXXXXXXXXXXX”,
“api_key”: “XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”,
“connection_string”: “hybrid.cloud.tyk.io:9090”,
“enable_rpc_cache”: true,
“bind_to_slugs”: true
},
“local_session_cache”: {
“disable_cached_session_state”: false,
“cached_session_timeout”: 5,
“cached_session_eviction”: 10
},
“enforce_org_quotas”: false,
“experimental_process_org_off_thread”: true,
“enable_non_transactional_rate_limiter”: true,
“enable_sentinel_rate_limiter”: false,
“auth_override”: {
“force_auth_provider”: true,
“auth_provider”: {
“name”: “”,
“storage_engine”: “rpc”,
“meta”: {}
}
},
“enable_context_vars”: true,
“hostname”: “”,
“enable_api_segregation”: false,
“control_api_hostname”: “”,
“enable_custom_domains”: true,
“enable_jsvm”: true,
“coprocess_options”: {
“enable_coprocess”: false
},
“hide_generator_header”: false,
“event_handlers”: {
“events”: {}
},
“pid_file_location”: “./tyk-gateway.pid”,
“allow_insecure_configs”: true,
“public_key_path”: “”,
“close_idle_connections”: false,
“allow_remote_config”: false,
“enable_bundle_downloader”: true,
“service_discovery”: {
“default_cache_timeout”: 20
},
“close_connections”: true,
“max_idle_connections_per_host”: 100,
“disable_dashboard_zeroconf”: true
}

Can you confirm that such error does not happen if you are using Chrome or Firefox? What about newer IE?

I have a feeling that SSL SNI broken in IE11 and (Redirecting) confirms it.

SNI, in general, is a way to specify a domain for TLS connection. It supported by most of the clients, but in your case broken SNI can be a case.

I think Tyk also has a bug when it does not properly handle clients without SNI support. You can check it by providing non empty value like this: openssl s_client -connect :8080 -CAfile rootcert.pem -state -servername localhost

As a potential way to mitigate the issue, I propose adding following change to your tyk.conf:
"control_api_hostname": "localhost" (or desired domain you want). Basically setting it to non empty value. And if you need to make a call to Tyk Admin API, you need do it on the domain specified in config, and with http client which supports SNI.

We will plan include fix for this issue in the next release.

Hope it helps!

When I run this openssl command against my Tyk Hybrid developer portal:

openssl s_client -connect devportal.XXX.com:8080 -CAfile rootcert.pem -state

I was expecting this SSL handshake:

SSL_connect:SSLv3/TLS read server certificate
SSL_connect:SSLv3/TLS read server key exchange
SSL_connect:SSLv3/TLS read server done
SSL_connect:SSLv3/TLS write client key exchange
SSL_connect:SSLv3/TLS write change cipher spec
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS read server session ticket
SSL_connect:SSLv3/TLS read change cipher spec
SSL_connect:SSLv3/TLS read finished

However, I got this SSL handshake:

SSL_connect:SSLv3/TLS read server certificate
SSL_connect:SSLv3/TLS read server key exchange
SSL_connect:SSLv3/TLS read server certificate request
SSL_connect:SSLv3/TLS read server done
SSL_connect:SSLv3/TLS write client certificate
SSL_connect:SSLv3/TLS write client key exchange
SSL_connect:SSLv3/TLS write change cipher spec
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS read server session ticket
SSL_connect:SSLv3/TLS read change cipher spec
SSL_connect:SSLv3/TLS read finished

This SSL handshake is unexpected, because I did not configure the Tyk Hybrid Gateway for client certificate authentication. Any idea why Tyk would be requesting a client certificate?

When I run the “Try it out” feature in my Tyk developer portal on Chrome, it displays a “Select a certificate” dialog with this message:

Select a certificate to authenticate yourself to devportal.XXX.com:8080

When I select the appropriate certificate, I get the expected response from my API.

However, when I run the “Try it out” feature in my Tyk developer portal on IE11, I get an error response in the developer portal (Network request failed). As I mentioned previously, this error is because CORS does not work in IE11 with client certificate authentication (Microsoft Bug 1028302).

It’s still not clear to me why Tyk is requesting a client certificate when my configuration is only set up for “Auth Token” authentication. Will setting “control_api_hostname” to “localhost”, as you suggested, prevent Tyk from requesting a client certificate?

Unfortunately, setting control_api_hostname to localhost in tyk.conf (and restarting the Tyk Gateway) did not mitigate this issue. Is there anything else I could try?

Interestingly, if I run Fiddler, this issue goes away in IE 11. Digging deeper, I found that this only happens when “Decrypt HTTPS traffic” is enabled in Fiddler HTTPS options. Apparently, Fiddler decrypts HTTPS sessions by re-signing traffic using self-generated certificates. Any idea why Fiddler with HTTPS decryption enabled would make this issue go away in IE11?

1 Like

For completeness in this response, Tyk Hybrid SSL does not work with Microsoft IE11 and Microsoft Edge. However, it does work with Chrome and Firefox.

Did anyone find a way to solve this issue ?

Alexandre_Jacquot, can you confirm that issue for you happens only when you are using portal try it out functionality?