From: Simon McVittie Date: Sun, 5 Oct 2014 21:56:55 +0000 (+0100) Subject: Avoid mixed content when cgiurl is https but url is not X-Git-Tag: debian/3.20141016~66 X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/commitdiff_plain/d712389ae3e8351c1416aa81d4b85586cf98f002?ds=sidebyside Avoid mixed content when cgiurl is https but url is not --- diff --git a/IkiWiki.pm b/IkiWiki.pm index c1518a2ae..38b91ae1d 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -613,7 +613,26 @@ sub checkconfig () { $local_cgiurl = $cgiurl->path; - if ($cgiurl->scheme ne $baseurl->scheme) { + if ($cgiurl->scheme eq 'https' && + $baseurl->scheme eq 'http') { + # We assume that the same content is available + # over both http and https, because if it + # wasn't, accessing the static content + # from the CGI would be mixed-content, + # which would be a security flaw. + + if ($cgiurl->authority ne $baseurl->authority) { + # use protocol-relative URL for + # static content + $local_url = "$config{url}/"; + $local_url =~ s{^http://}{//}; + } + # else use host-relative URL for static content + + # either way, CGI needs to be absolute + $local_cgiurl = $config{cgiurl}; + } + elsif ($cgiurl->scheme ne $baseurl->scheme) { # too far apart, fall back to absolute URLs $local_url = "$config{url}/"; $local_cgiurl = $config{cgiurl}; @@ -626,6 +645,7 @@ sub checkconfig () { $local_cgiurl = $config{cgiurl}; $local_cgiurl =~ s{^https?://}{//}; } + # else keep host-relative URLs } $local_url =~ s{//$}{/}; diff --git a/t/relativity.t b/t/relativity.t index 6c4d1107e..675efc903 100755 --- a/t/relativity.t +++ b/t/relativity.t @@ -407,12 +407,9 @@ run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub { $ENV{HTTPS} = 'on'; }); %bits = parse_cgi_content($content); -TODO: { -local $TODO = "avoid mixed content"; is($bits{basehref}, "https://example.com/wiki/"); like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$}); like($bits{tophref}, qr{^(?:/wiki|\.)/$}); -} like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$}); # when not accessed via HTTPS, ??? @@ -439,11 +436,13 @@ run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub { $ENV{HTTPS} = 'on'; }); %bits = parse_cgi_content($content); +# because the static and dynamic stuff is on the same server, we assume that +# both are also on the staging server +like($bits{basehref}, qr{^https://staging.example.net/wiki/$}); +like($bits{stylehref}, qr{^(?:(?:https:)?//staging.example.net)?/wiki/style.css$}); +like($bits{tophref}, qr{^(?:(?:(?:https:)?//staging.example.net)?/wiki|\.)/$}); TODO: { -local $TODO = "avoid mixed content"; -like($bits{basehref}, qr{^https://example.com/wiki/$}); -like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$}); -like($bits{tophref}, qr{^(?:(?:(?:https:)?//example.com)?/wiki|\.)/$}); +local $TODO = "this should really point back to itself but currently points to example.com"; like($bits{cgihref}, qr{^(?:(?:https:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$}); } @@ -458,11 +457,8 @@ run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub { $ENV{HTTPS} = 'on'; }); %bits = parse_cgi_content($content); -TODO: { -local $TODO = "avoid mixed content"; is($bits{basehref}, "https://example.com/wiki/a/b/c/"); like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$}); -} like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$}); like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$}); diff --git a/t/urlto.t b/t/urlto.t index 025409b7f..50cad88dd 100755 --- a/t/urlto.t +++ b/t/urlto.t @@ -50,11 +50,13 @@ is(IkiWiki::baseurl(undef), "//example.co.uk/~smcv/"); is(IkiWiki::urlto('stoats', undef), "//example.co.uk/~smcv/stoats/"); is(IkiWiki::urlto('', undef), "//example.co.uk/~smcv/"); -# with url and cgiurl on different schemes, "local" degrades to absolute +# with url and cgiurl on different schemes, "local" degrades to absolute for +# CGI but protocol-relative for static content, to avoid the CGI having +# mixed content $IkiWiki::config{url} = "http://example.co.uk/~smcv"; $IkiWiki::config{cgiurl} = "https://dynamic.example.co.uk/~smcv/ikiwiki.cgi"; is(IkiWiki::checkconfig(), 1); is(IkiWiki::cgiurl(), "https://dynamic.example.co.uk/~smcv/ikiwiki.cgi"); -is(IkiWiki::baseurl(undef), "http://example.co.uk/~smcv/"); -is(IkiWiki::urlto('stoats', undef), "http://example.co.uk/~smcv/stoats/"); -is(IkiWiki::urlto('', undef), "http://example.co.uk/~smcv/"); +is(IkiWiki::baseurl(undef), "//example.co.uk/~smcv/"); +is(IkiWiki::urlto('stoats', undef), "//example.co.uk/~smcv/stoats/"); +is(IkiWiki::urlto('', undef), "//example.co.uk/~smcv/");