chiark / gitweb /
Fix XSS vuln by escaping all variables in templates
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 19 Oct 2025 19:12:57 +0000 (20:12 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 19 Oct 2025 19:15:48 +0000 (20:15 +0100)
bcp5-registry.pl
passwords.pl
utils.pl

index 48047dc82dd4c66e0fdd3327febfec5231a9eba6..2bd9e922ef648d5d33cc93258e9d713380bbf35e 100755 (executable)
@@ -445,7 +445,7 @@ sub finish_error ($) {
 }
 
 sub finish () {
-    process_file('template.html');
+    process_file('template.html', 1);
     print $out or die $!;
     close STDOUT or die $!;
     exit 0;
index 419b2ca6364c6e9a4c8cf4402b181d19c198e65f..2dacdf2d9d88d294ebe4dfa579753f1a75d0bb68 100644 (file)
@@ -57,7 +57,7 @@ sub make_password ($) {
 
 sub send_password ($) {
     $password= make_password($id);
-    process_file('notice.txt');
+    process_file('notice.txt', 0);
     open SM, "| /usr/sbin/sendmail -odb -oi -oee -f $nullemail -t" or die $!;
     print SM $out or die $!;
     close SM; $? and die $?;
index 41dcff8fcce933ff22e14e35c019ea5642dd13af..3528cb74d6b45fdb383eaadde2ddc5549f4bd7b4 100644 (file)
--- a/utils.pl
+++ b/utils.pl
@@ -18,8 +18,8 @@
 
 open RAND,"/dev/urandom" or die $!;
 
-sub process_file ($) {
-    local ($filename) = @_;
+sub process_file ($$) {
+    local ($filename, $quote_html) = @_;
     
     open X, "$filename" or die "$filename: $!";
     @x= <X>;
@@ -31,7 +31,7 @@ sub process_file ($) {
     $cl= 0;
     $out= '';
     $level= -1;
-    process(1);
+    process(1, $quote_html);
 }
 
 sub randnybs ($) {
@@ -48,8 +48,8 @@ sub out ($) {
     $out.= $_[0]."\n";
 }
 
-sub process ($) {
-    my ($doing) = @_;
+sub process ($$) {
+    my ($doing, $quote_html) = @_;
     my ($bcl);
     $level++;
     for (;;) {
@@ -67,7 +67,7 @@ sub process ($) {
                $do= !$do if $q eq 'ifnot';
 #              out("<!-- $level $doing $do $q $v $_ -->");
            }
-           process($doing && $do);
+           process($doing && $do, $quote_html);
        } elsif (m/^\@\@\@foreach\:(area|db)\@\@\@$/) {
            if ($doing) {
                $bcl= $cl;
@@ -75,16 +75,16 @@ sub process ($) {
                     &{"foreach_cond_$1"};
                     &{"foreach_incr_$1"}) {
                    &{"foreach_setvars_$1"};
-                   process($doing);
+                   process($doing, $quote_html);
                    $cl= $bcl;
                }
            }
-           process(0);
+           process(0, $quote_html);
        } elsif (m/^\@\@\@comment\:(\s.*)?$/) {
        } elsif (m/\S/) {
            s/^\@\@\@$//;
            if ($doing) {
-               s/\@\@\@(\w+)\@\@\@/ getvar("$1") /ge;
+               s/\@\@\@(\w+)\@\@\@/ getvar_mightquote("$1", $quote_html) /ge;
                out($_);
            } else {
                s/\@\@\@\w+\@\@\@//g;
@@ -101,6 +101,15 @@ sub getvar ($) {
     return $$vn;
 }
 
+sub getvar_mightquote ($$) {
+  my ($vn, $quote_html) = @_;
+  my $v = getvar($vn);
+  $v =~ s/\&/&amp;/g;  
+  $v =~ s/\</&lt;/g;  
+  $v =~ s/\>/&gt;/g;  
+  return $v;
+}
+
 %saniarray= ('<','lt', '>','gt', '&','amp', '"','quot');
 sub html_sani {
     local ($in) = @_;