diff -up vim91/runtime/autoload/netrw.vim.CVE-2026-28417 vim91/runtime/autoload/netrw.vim --- vim91/runtime/autoload/netrw.vim.CVE-2026-28417 2026-03-17 19:22:17.101915588 +0100 +++ vim91/runtime/autoload/netrw.vim 2026-03-17 19:32:29.134514079 +0100 @@ -3376,13 +3376,26 @@ endif " s:NetrwValidateHostname: Validate that the hostname is valid {{{2 " Input: -" hostname +" hostname, may include an optional username, e.g. user@hostname +" allow a alphanumeric hostname or an IPv(4/6) address " Output: " true if g:netrw_machine is valid according to RFC1123 #Section 2 fun! s:NetrwValidateHostname(hostname) - " RFC1123#section-2 mandates, a valid hostname starts with letters or digits - " so reject everyhing else - return a:hostname =~? '^[a-z0-9]' + " Username: + let user_pat = '\%([a-zA-Z0-9._-]\+@\)\?' + " Hostname: 1-64 chars, alphanumeric/dots/hyphens. + " No underscores. No leading/trailing dots/hyphens. + let host_pat = '[a-zA-Z0-9]\%([-a-zA-Z0-9.]{,62}[a-zA-Z0-9]\)\?$' + + " IPv4: 1-3 digits separated by dots + let ipv4_pat = '\%(\d\{1,3}\.\)\{3\}\d\{1,3\}$' + + " IPv6: Hex, colons, and optional brackets + let ipv6_pat = '\[\?\%([a-fA-F0-9:]\{2,}\)\+\]\?$' + + return a:hostname =~? '^'.user_pat.host_pat || + \ a:hostname =~? '^'.user_pat.ipv4_pat || + \ a:hostname =~? '^'.user_pat.ipv6_pat endfun " --------------------------------------------------------------------- @@ -11880,15 +11893,15 @@ endfun " a correct command for use with a system() call fun! s:MakeSshCmd(sshcmd) " call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">") - if s:user == "" - let sshcmd = substitute(a:sshcmd,'\',s:machine,'') - else - let sshcmd = substitute(a:sshcmd,'\',s:user."@".s:machine,'') + let machine = shellescape(s:machine, 1) + if s:user != '' + let machine = shellescape(s:user, 1).'@'.machine endif + let sshcmd = substitute(a:sshcmd,'\',machine,'') if exists("g:netrw_port") && g:netrw_port != "" - let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'') + let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.shellescape(g:netrw_port,1),'') elseif exists("s:port") && s:port != "" - let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'') + let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.shellescape(s:port,1),'') else let sshcmd= substitute(sshcmd,"USEPORT ",'','') endif