Changeset 1161


Ignore:
Timestamp:
12/04/08 07:48:32 (3 years ago)
Author:
KennethLavrsen
Message:

Item375: First part of addressing URLPARAM XSS issue
Additionally some docs will need some additional work.
Please test this carefully so we know which apps break from this.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/UnitTestContrib/test/unit/Fn_URLPARAM.pm

    r816 r1161  
    5555        '%URLPARAM{"foo" default="bar"}%', $this->{test_web}, $this->{test_topic}); 
    5656    $this->assert_str_equals('', "$str"); 
     57     
     58    $this->{request}->param( -name=>'foo', -value=>'<evil script>\'\"%'); 
     59    $str = $this->{twiki}->handleCommonTags( 
     60        '%URLPARAM{"foo" default="bar"}%', $this->{test_web}, $this->{test_topic}); 
     61    $this->assert_str_equals('&#60;evil script&#62;&#39;\&#34;&#37;', "$str"); 
    5762} 
    5863 
     
    6267    my $str; 
    6368 
    64     $this->{request}->param( -name=>'foo', -value=>'&?*!"'); 
     69    $this->{request}->param( -name=>'foo', -value=>'<>\'%&?*!"'); 
    6570    $str = $this->{twiki}->handleCommonTags( 
    6671        '%URLPARAM{"foo" encode="entity"}%', $this->{test_web}, $this->{test_topic}); 
    67     $this->assert_str_equals('&#38;?&#42;!&#34;', "$str"); 
     72    $this->assert_str_equals('&#60;&#62;&#39;&#37;&#38;?&#42;!&#34;', "$str"); 
    6873 
    6974    $this->{request}->param( -name=>'foo', -value=>'&?*!" '); 
     
    7681        '%URLPARAM{"foo" encode="quote"}%', $this->{test_web}, $this->{test_topic}); 
    7782    $this->assert_str_equals('&?*!\" ', "$str"); 
     83     
     84    $this->{request}->param( -name=>'foo', -value=>'<evil script>\'\"%'); 
     85    $str = $this->{twiki}->handleCommonTags( 
     86        '%URLPARAM{"foo" default="bar" encode="safe"}%', $this->{test_web}, $this->{test_topic}); 
     87    $this->assert_str_equals('&#60;evil script&#62;&#39;\&#34;&#37;', "$str"); 
     88     
     89    $this->{request}->param( -name=>'foo', -value=>'<evil script>\'\"%'); 
     90    $str = $this->{twiki}->handleCommonTags( 
     91        '%URLPARAM{"foo" default="bar" encode="off"}%', $this->{test_web}, $this->{test_topic}); 
     92    $this->assert_str_equals('<evil script>\'\"%', "$str"); 
     93     
     94    $this->{request}->param( -name=>'foo', -value=>'<evil script>\'\"%'); 
     95    $str = $this->{twiki}->handleCommonTags( 
     96        '%URLPARAM{"foo" default="bar" encode="none"}%', $this->{test_web}, $this->{test_topic}); 
     97    $this->assert_str_equals('<evil script>\'\"%', "$str"); 
    7898} 
    7999 
  • trunk/core/data/System/VarURLPARAM.txt

    r1022 r1161  
    1010     | =default="..."= | Default value in case parameter is empty or missing | empty string | 
    1111     | =newline="&lt;br /&gt;"= | Convert newlines in textarea to other delimiters | no conversion | 
    12      | =encode="entity"= | Encode special characters into HTML entities. See [[%IF{"'%INCLUDINGTOPIC%'='Macros'" then="#"}%VarENCODE][ENCODE]] for more details. | no encoding | 
    13      | =encode="url"= | Encode special characters for URL parameter use, like a double quote into =%22= | no encoding | 
    14      | =encode="quote"= | Escape double quotes with backslashes (=\"=), does not change other characters; required when feeding URL parameters into other macros | no encoding | 
     12     | =encode="off"= <br /> =encode="entity"= <br /> =encode="safe"= <br /> =encode="url"= <br /> =encode="quote"= | Control how special characters are encoded <hr /> =off=: No encoding. Avoid using this when possible. See the security warning below. <hr /> =entity=: Encode special characters into HTML entities. See [[%IF{"'%INCLUDINGTOPIC%'='Macros'" then="#"}%VarENCODE][ENCODE]] for more details. <hr /> =safe=: Encode characters ='"&lt;&gt;= into HTML entities. <hr /> =url=: Encode special characters for URL parameter use, like a double quote into =%22= <hr /> =quote=: Escape double quotes with backslashes (=\"=), does not change other characters; required when feeding URL parameters into other macros. | "safe" | 
    1513     | =multiple="on"= %BR% =multiple="[<nop>[$item]]"= | If set, gets all selected elements of a =&lt;select multiple="multiple"&gt;= tag. A format can be specified, with =$item= indicating the element, e.g. =multiple="Option: $item"= | first element | 
    1614     | =separator=", "= | Separator between multiple selections. Only relevant if multiple is specified | ="\n"= (new line) | 
     
    1816   * __%X% Notes:__ 
    1917      * URL parameters passed into HTML form fields must be entity [[%IF{"'%INCLUDINGTOPIC%'='Macros'" then="#"}%VarENCODE][ENCODEd]]. 
    20       * Double quotes in URL parameters must be escaped when passed into other macros.%BR% Example: =%<nop>SEARCH{ "%<nop>URLPARAM{ "search" encode="quotes" }%" noheader="on" }%= 
     18      * Double quotes in URL parameters must be escaped when passed into other macros.%BR% Example: =%<nop>SEARCH{ "%<nop>URLPARAM{ "search" encode="quote" }%" noheader="on" }%= 
    2119      * When used in a template topic, this macro will be expanded when the template is used to create a new topic. See TemplateTopics#TemplateTopicsVars for details. 
    2220      * Watch out for internal parameters, such as =rev=, =skin=, =template=, =topic=, =web=; they have a special meaning in Foswiki. Common parameters and view script specific parameters are documented at CommandAndCGIScripts. 
    2321      * If you have =%<nop>URLPARAM{= in the value of a URL parameter, it will be modified to =%&lt;nop&gt;URLPARAM{=. This is to prevent an infinite loop during expansion. 
    24       * There is a risk that this macro could be misused for cross-site scripting. 
     22      * Security warning! Using URLPARAM can easily be misused for cross-site scripting unless specific characters are entity encoded. By default URLPARAM encodes the characters ='"&lt;&gt;= into HTML entities (same as encode="safe") which is relatively safe. The safest is to use encode="entity". When passing URLPARAM inside another macro always use double quotes ("") combined with using URLPARAM with encode="quote". For maximum security against cross-site scripting you are adviced to install the Foswiki:Extensions.SafeWikiPlugin. 
    2523   * Related: [[%IF{"'%INCLUDINGTOPIC%'='Macros'" then="#"}%VarENCODE][ENCODE]], [[%IF{"'%INCLUDINGTOPIC%'='Macros'" then="#"}%VarSEARCH][SEARCH]], FormattedSearch, [[%IF{"'%INCLUDINGTOPIC%'='Macros'" then="#"}%VarQUERYSTRING][QUERYSTRING]] 
  • trunk/core/lib/Foswiki.pm

    r1127 r1161  
    38673867    my $param     = $params->{_DEFAULT} || ''; 
    38683868    my $newLine   = $params->{newline}; 
    3869     my $encode    = $params->{encode}; 
     3869    my $encode    = $params->{encode} || 'safe'; 
    38703870    my $multiple  = $params->{multiple}; 
    38713871    my $separator = $params->{separator}; 
     
    38973897    if ( defined $value ) { 
    38983898        $value =~ s/\r?\n/$newLine/go if ( defined $newLine ); 
    3899         if ($encode) { 
    3900             if ( $encode =~ /^entit(y|ies)$/i ) { 
    3901                 $value = entityEncode($value); 
    3902             } 
    3903             elsif ( $encode =~ /^quotes?$/i ) { 
    3904                 $value =~ s/\"/\\"/go 
    3905                   ;    # escape quotes with backslash (Bugs:Item3383 fix) 
    3906             } 
    3907             else { 
    3908                 $value =~ s/\r*\n\r*/<br \/>/;    # Legacy 
    3909                 $value = urlEncode($value); 
    3910             } 
     3899        if ( $encode =~ /^entit(y|ies)$/i ) { 
     3900            $value = entityEncode($value); 
     3901        } 
     3902        elsif ( $encode =~ /^quotes?$/i ) { 
     3903            $value =~ s/\"/\\"/go 
     3904              ;    # escape quotes with backslash (Bugs:Item3383 fix) 
     3905        } 
     3906        elsif ( $encode =~ /^(off|none)$/i ) { 
     3907            # no encoding 
     3908        } 
     3909        elsif ( $encode =~ /^url$/i ) { 
     3910            $value =~ s/\r*\n\r*/<br \/>/;    # Legacy 
     3911            $value = urlEncode($value); 
     3912        } 
     3913        else { # safe or default 
     3914            # entity encode ' " < > and % 
     3915            $value =~ s/([<>%'"])/'&#'.ord($1).';'/ge; 
    39113916        } 
    39123917    } 
Note: See TracChangeset for help on using the changeset viewer.