diff --git a/CMakeLists.txt b/CMakeLists.txt
index a7738d098f6283ef497e3bd37b3754790fefe195..64c0e57495b32825fe548e849f8a4df0d7718ef0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1550,6 +1550,7 @@ CHECK_FUNCTION_EXISTS(X509_get_key_usage LWS_HAVE_X509_get_key_usage)
 CHECK_FUNCTION_EXISTS(SSL_CTX_get0_certificate LWS_HAVE_SSL_CTX_get0_certificate)
 CHECK_FUNCTION_EXISTS(SSL_get0_alpn_selected LWS_HAVE_SSL_get0_alpn_selected)
 CHECK_FUNCTION_EXISTS(SSL_set_alpn_protos LWS_HAVE_SSL_set_alpn_protos)
+CHECK_FUNCTION_EXISTS(SSL_CTX_set_ciphersuites LWS_HAVE_SSL_CTX_set_ciphersuites)
 if (LWS_WITH_SSL AND NOT LWS_WITH_MBEDTLS)
 CHECK_SYMBOL_EXISTS(SSL_CTX_get_extra_chain_certs_only openssl/ssl.h LWS_HAVE_SSL_EXTRA_CHAIN_CERTS)
 endif()
diff --git a/READMEs/README.lwsws.md b/READMEs/README.lwsws.md
index b36b388513980b1e0e6684bfb8d6f0dabe4ec465..8893c86b6c2bdfbe04bfc0f3b91fcde8daa3464f 100644
--- a/READMEs/README.lwsws.md
+++ b/READMEs/README.lwsws.md
@@ -233,9 +233,15 @@ See also "rawonly" below.
 
  - `"enable-client-ssl"`: `"1"` enables the vhost's client SSL context, you will need this if you plan to create client conections on the vhost that will use SSL.  You don't need it if you only want http / ws client connections.
 
- - "`ciphers`": "<cipher list>"   sets the allowed list of ciphers and key exchange protocols for the vhost.  The default list is restricted to only those providing PFS (Perfect Forward Secrecy) on the author's Fedora system.
+ - "`ciphers`": "<cipher list>"  OPENSSL only: sets the allowed list of TLS <= 1.2 ciphers and key exchange protocols for the serving SSL_CTX on the vhost.  The default list is restricted to only those providing PFS (Perfect Forward Secrecy) on the author's Fedora system.
  
- If you need to allow weaker ciphers,you can provide an alternative list here per-vhost.
+ If you need to allow weaker ciphers, you can provide an alternative list here per-vhost.
+
+ - "`client-ssl-ciphers`": "<cipher list>"  OPENSSL only: sets the allowed list of <= TLS1.2 ciphers and key exchange protocols for the client SSL_CTX on the vhost
+
+ - "`tls13-ciphers`": "<cipher list>"  OPENSSL 1.1.1+ only: sets allowed list of TLS1.3+ ciphers and key exchange protocols for the client SSL_CTX on the vhost.  The default is to allow all.
+
+ - "`client-tls13-ciphers`": "<cipher list>"  OPENSSL 1.1.1+ only: sets the allowed list of TLS1.3+ ciphers and key exchange protocols for the client SSL_CTX on the vhost.  The default is to allow all.
  
  - "`ecdh-curve`": "<curve name>"   The default ecdh curve is "prime256v1", but you can override it here, per-vhost
 
diff --git a/cmake/lws_config.h.in b/cmake/lws_config.h.in
index e8539c1d51c10af642f11c15c70ecc64c9a7a21e..045be0e65c6e217b84cff42a05792e5eb1ab5379 100644
--- a/cmake/lws_config.h.in
+++ b/cmake/lws_config.h.in
@@ -111,6 +111,7 @@
 #cmakedefine LWS_HAVE_RSA_SET0_KEY
 #cmakedefine LWS_HAVE_X509_get_key_usage
 #cmakedefine LWS_HAVE_SSL_CTX_get0_certificate
+#cmakedefine LWS_HAVE_SSL_CTX_set_ciphersuites
 
 #cmakedefine LWS_HAVE_UV_VERSION_H
 #cmakedefine LWS_HAVE_NEW_UV_VERSION_H
diff --git a/include/libwebsockets/lws-context-vhost.h b/include/libwebsockets/lws-context-vhost.h
index 2dbf6eb3d0bd9718cb034ea0c5a171aa974469cf..1746093c5a45c475c141a47b15affcfa8b74c1cb 100644
--- a/include/libwebsockets/lws-context-vhost.h
+++ b/include/libwebsockets/lws-context-vhost.h
@@ -205,12 +205,15 @@ struct lws_context_creation_info {
 	 * filepath when setting up a vhost client SSL context,
 	 * but it is preferred to use .client_ssl_ca_filepath for that.) */
 	const char *ssl_cipher_list;
-	/**< VHOST: List of valid ciphers to use (eg,
+	/**< VHOST: List of valid ciphers to use ON TLS1.2 AND LOWER ONLY (eg,
 	 * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
 	 * or you can leave it as NULL to get "DEFAULT" (For backwards
 	 * compatibility, this can also be used to pass the client cipher
 	 * list when setting up a vhost client SSL context,
-	 * but it is preferred to use .client_ssl_cipher_list for that.)*/
+	 * but it is preferred to use .client_ssl_cipher_list for that.)
+	 * SEE .tls1_3_plus_cipher_list and .client_tls_1_3_plus_cipher_list
+	 * for the equivalent for tls1.3.
+	 */
 	const char *http_proxy_address;
 	/**< VHOST: If non-NULL, attempts to proxy via the given address.
 	 * If proxy auth is required, use format "username:password\@server:port" */
@@ -491,6 +494,19 @@ struct lws_context_creation_info {
 	long ssl_client_options_clear;
 	/**< VHOST: Any bits set here will be cleared as CLIENT SSL options */
 
+	const char *tls1_3_plus_cipher_list;
+	/**< VHOST: List of valid ciphers to use for incoming server connections
+	 * ON TLS1.3 AND ABOVE (eg, "TLS_CHACHA20_POLY1305_SHA256" on this vhost
+	 * or you can leave it as NULL to get "DEFAULT".
+	 * SEE .client_tls_1_3_plus_cipher_list to do the same on the vhost
+	 * client SSL_CTX.
+	 */
+	const char *client_tls_1_3_plus_cipher_list;
+	/**< VHOST: List of valid ciphers to use for outgoing client connections
+	 * ON TLS1.3 AND ABOVE on this vhost (eg,
+	 * "TLS_CHACHA20_POLY1305_SHA256") or you can leave it as NULL to get
+	 * "DEFAULT".
+	 */
 
 	/* Add new things just above here ---^
 	 * This is part of the ABI, don't needlessly break compatibility
diff --git a/lib/roles/http/server/lejp-conf.c b/lib/roles/http/server/lejp-conf.c
index 425c956aad594865062fc399f8348e003e530350..cc6a76663568ef899013ebf98cbf5de98920dd7b 100644
--- a/lib/roles/http/server/lejp-conf.c
+++ b/lib/roles/http/server/lejp-conf.c
@@ -107,6 +107,8 @@ static const char * const paths_vhosts[] = {
 	"vhosts[].alpn",
 	"vhosts[].ssl-client-option-set",
 	"vhosts[].ssl-client-option-clear",
+	"vhosts[].tls13-ciphers",
+	"vhosts[].client-tls13-ciphers",
 };
 
 enum lejp_vhost_paths {
@@ -160,6 +162,8 @@ enum lejp_vhost_paths {
 	LEJPVP_ALPN,
 	LEJPVP_SSL_CLIENT_OPTION_SET,
 	LEJPVP_SSL_CLIENT_OPTION_CLEAR,
+	LEJPVP_TLS13_CIPHERS,
+	LEJPVP_CLIENT_TLS13_CIPHERS,
 };
 
 static const char * const parser_errs[] = {
@@ -623,6 +627,13 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
 	case LEJPVP_CIPHERS:
 		a->info->ssl_cipher_list = a->p;
 		break;
+	case LEJPVP_TLS13_CIPHERS:
+		a->info->tls1_3_plus_cipher_list = a->p;
+		break;
+	case LEJPVP_CLIENT_TLS13_CIPHERS:
+		a->info->client_tls_1_3_plus_cipher_list = a->p;
+		break;
+
 	case LEJPVP_ECDH_CURVE:
 		a->info->ecdh_curve = a->p;
 		break;
diff --git a/lib/roles/http/server/server.c b/lib/roles/http/server/server.c
index 61e82ac13a9ba00678d5f183e3b0ec8d1e530ca5..16e3f1041bbe33269b967ce389e6c837247ce04a 100644
--- a/lib/roles/http/server/server.c
+++ b/lib/roles/http/server/server.c
@@ -1270,14 +1270,15 @@ lws_http_action(struct lws *wsi)
 			}
 
 			*p++ = '?';
-			lws_hdr_copy(wsi, p,
+			if (lws_hdr_copy(wsi, p,
 				     (int)(&rpath[sizeof(rpath) - 1] - p),
-				     WSI_TOKEN_HTTP_URI_ARGS);
-			while (--na) {
-				if (*p == '\0')
-					*p = '&';
-				p++;
-			}
+				     WSI_TOKEN_HTTP_URI_ARGS) > 0)
+				while (--na) {
+					if (*p == '\0')
+						*p = '&';
+					p++;
+				}
+			*p = '\0';
 		}
 
 		i.path = rpath;
diff --git a/lib/tls/openssl/openssl-client.c b/lib/tls/openssl/openssl-client.c
index 52976d712b3b4c6a73013b2b75b54ae32e7c79a9..a452aa3e6014a9f4f310fdca0caac43a59655854 100644
--- a/lib/tls/openssl/openssl-client.c
+++ b/lib/tls/openssl/openssl-client.c
@@ -389,6 +389,12 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh,
 	if (cipher_list)
 		SSL_CTX_set_cipher_list(vh->tls.ssl_client_ctx, cipher_list);
 
+#if defined(LWS_HAVE_SSL_CTX_set_ciphersuites)
+	if (info->client_tls_1_3_plus_cipher_list)
+		SSL_CTX_set_ciphersuites(vh->tls.ssl_client_ctx,
+					 info->client_tls_1_3_plus_cipher_list);
+#endif
+
 #ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
 	if (!lws_check_opt(vh->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
 		/* loads OS default CA certs */
diff --git a/lib/tls/openssl/openssl-server.c b/lib/tls/openssl/openssl-server.c
index 7e23c2e6bf108347e451e7c7b79ef2a566ba62f4..4afe1d6c30b86a87b0c241a0126315320acff178 100644
--- a/lib/tls/openssl/openssl-server.c
+++ b/lib/tls/openssl/openssl-server.c
@@ -376,6 +376,12 @@ lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info,
 	if (info->ssl_cipher_list)
 		SSL_CTX_set_cipher_list(vhost->tls.ssl_ctx, info->ssl_cipher_list);
 
+#if defined(LWS_HAVE_SSL_CTX_set_ciphersuites)
+	if (info->tls1_3_plus_cipher_list)
+		SSL_CTX_set_ciphersuites(vhost->tls.ssl_ctx,
+					 info->tls1_3_plus_cipher_list);
+#endif
+
 #if !defined(OPENSSL_NO_TLSEXT)
 	SSL_CTX_set_tlsext_servername_callback(vhost->tls.ssl_ctx,
 					       lws_ssl_server_name_cb);
diff --git a/test-apps/test-server.c b/test-apps/test-server.c
index 355dbc5ee6d65c1178cf57c304e3bf9dbe7095f7..1e1f1ee53a1b37b8cb50ec22ecd3a6a1121fdef9 100644
--- a/test-apps/test-server.c
+++ b/test-apps/test-server.c
@@ -107,8 +107,7 @@ lws_callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
 			}
 
 			if (lws_hdr_copy(wsi, buf, sizeof buf, n) < 0)
-				fprintf(stderr, "    %s (too big)\n",
-					(char *)c, buf);
+				fprintf(stderr, "    %s (too big)\n", (char *)c);
 			else {
 				buf[sizeof(buf) - 1] = '\0';