diff --git a/html5/js/Client.js b/html5/js/Client.js index a2108f52..e0eb1dad 100644 --- a/html5/js/Client.js +++ b/html5/js/Client.js @@ -2676,6 +2676,10 @@ XpraClient.prototype._process_challenge = function(packet, ctx) { ctx.do_process_challenge(digest, server_salt, salt_digest, password); } if (ctx.passwords.length>0) { + if (!ctx.is_digest_safe(digest)) { + ctx.disconnect("refusing to send a password over an insecure connection"); + return; + } const password = ctx.passwords.shift(); do_process_challenge(password); return; @@ -2684,7 +2688,12 @@ XpraClient.prototype._process_challenge = function(packet, ctx) { ctx.cancel_hello_timer(); ctx.keycloak_prompt_fn(server_salt, do_process_challenge); return; - } else if (ctx.password_prompt_fn) { + } + if (ctx.password_prompt_fn && ctx.is_digest_safe(digest)) { + if (!ctx.is_digest_safe(digest)) { + ctx.disconnect("refusing to prompt for a password over an insecure connection"); + return; + } const address = ""+client.host+":"+client.port; ctx.cancel_hello_timer(); ctx.password_prompt_fn("The server at "+address+" requires a "+prompt, do_process_challenge); @@ -2693,13 +2702,17 @@ XpraClient.prototype._process_challenge = function(packet, ctx) { ctx.disconnect("No password specified for authentication challenge"); } +XpraClient.prototype.is_digest_safe = function(digest) { + return digest != "xor" || this.ssl || this.encryption || this.insecure || this.host == "localhost" || this.host == "127.0.0.1" || this.host=="::1"; +} + XpraClient.prototype.do_process_challenge = function(digest, server_salt, salt_digest, password) { this.schedule_hello_timer(); let client_salt = null; let l = server_salt.length; //don't use xor over unencrypted connections unless explicitly allowed: - if (digest == "xor" && !this.ssl && !this.encryption && !this.insecure && this.host != "localhost" && this.host != "127.0.0.1") { + if (!this.is_digest_safe(digest)) { this.callback_close(`server requested digest xor, cowardly refusing to use it without encryption with ${this.host}`); return; }