[pve-devel] Allow accessing novnc console without being logged in

Dietmar Maurer dietmar at proxmox.com
Mon Jan 4 07:51:51 CET 2016


Hi Henry,

first, thanks for the patch. 

Please note that you need to sign a CLA if you want that we 
include your code, see:

https://pve.proxmox.com/wiki/Developer_Documentation

further comments inline.

> When using an API it's impossible to use the novnc console.
> This patch introduces a new API endpoint
> (https://proxmoxurl.com:8006/api2/json/websocket) where we can connect
> without being logged in. Authentication is done by validating the vnc
> ticket.

Is this secure enough?

> Tested on Proxmox VE 4.
> 
> From 0ca59236a4cdcc6e7479b982e8baec1466ac809d Mon Sep 17 00:00:00 2001
> From: Henry Spanka <henry at myvirtualserver.de>
> Date: Mon, 2 Nov 2015 21:45:46 +0100
> Subject: [PATCH 1/1] Allow accessing novnc console when not logged in
> 
> ---
>  /PVE/HTTPServer.pm | 59 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/PVE/HTTPServer.pm b/PVE/HTTPServer.pm
> index 927abc0..f23d9e4 100755
> --- a/PVE/HTTPServer.pm
> +++ b/PVE/HTTPServer.pm
> @@ -1221,6 +1221,65 @@ sub unshift_read_header {
>  		    }
>  		    $self->handle_spice_proxy_request($reqstate,
> $connect_str, $vmid, $node, $port);
>  		    return;
> +        } elsif ($path =~ /^\/api2\/json\/websocket$/) {
> +            my $upgrade = $r->header('upgrade');
> +            $upgrade = lc($upgrade) if $upgrade;
> +
> +            my $vncticket = extract_params($r, $method)->{vncticket};
> +
> +            my $vmid = extract_params($r, $method)->{vmid};
> +
> +            my $user = extract_params($r, $method)->{user};

Please try to avoid multiple calls to extract_param(). Instead, call
once and store the result.

This is the first security risk. We try to read/parse parameters
before the call is authenticated - no good.
How can we improve that? Pass VNC ticket as header?

> +
> +            my $authpath = "/vms/$vmid";
> +
> +            if (!$upgrade || ($upgrade ne 'websocket')) {
> +                $self->error($reqstate, HTTP_INTERNAL_SERVER_ERROR, "unable
> to upgrade to protocol '$upgrade'\n");
> +                return;
> +            }
> +
> +            my $wsver = $r->header('sec-websocket-version');
> +            if (!$wsver || ($wsver ne '13')) {
> +                $self->error($reqstate, HTTP_INTERNAL_SERVER_ERROR,
> "unsupported websocket-version '$wsver'\n");
> +                return;
> +            }
> +
> +            my $wsproto_str = $r->header('sec-websocket-protocol');
> +            if (!$wsproto_str) {
> +                $self->error($reqstate, HTTP_INTERNAL_SERVER_ERROR,
> "missing websocket-protocol header");
> +                return;
> +            }
> +
> +            my $wsproto;
> +
> +            foreach my $p (PVE::Tools::split_list($wsproto_str)) {
> +                $wsproto = $p if !$wsproto && $p eq 'base64';
> +                $wsproto = $p if $p eq 'binary';
> +            }
> +
> +            if (!$wsproto) {
> +                $self->error($reqstate, HTTP_INTERNAL_SERVER_ERROR,
> "unsupported websocket-protocol protocol '$wsproto_str'\n");
> +                return;
> +            }
> +
> +            my $wskey = $r->header('sec-websocket-key');
> +
> +            if (!$wskey) {
> +                $self->error($reqstate, HTTP_INTERNAL_SERVER_ERROR,
> "missing websocket-key\n");
> +                return;
> +            }

That code looks somehow familiar - I see same code handle_api2_request().
Is it possible to reuse that somehow?




More information about the pve-devel mailing list