From 797b07d809dcf8ea667b6050f4e1e24dbce0ac7f Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 6 Aug 2004 08:04:55 +0000 Subject: [PATCH] Add escaping to SQL queries and HTML output. Also tweaked HTML to more or less pass as XML (haven't yet tested). Fix for [ 1004067 ] article validation: SQL is unsafe --- includes/SpecialValidate.php | 123 +++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 57 deletions(-) diff --git a/includes/SpecialValidate.php b/includes/SpecialValidate.php index 8f0915a3e8..735de01659 100644 --- a/includes/SpecialValidate.php +++ b/includes/SpecialValidate.php @@ -24,7 +24,7 @@ class Validation { $id = "" ; $tab = "" ; - $sql = "SELECT cur_id,cur_timestamp FROM cur WHERE cur_namespace=0 AND cur_title='{$article_title}'" ; + $sql = "SELECT cur_id,cur_timestamp FROM cur WHERE cur_namespace=0 AND cur_title='" . wfStrencode( $article_title ) . "'" ; $res = wfQuery( $sql, DB_READ ); if( $s = wfFetchObject( $res ) ) { @@ -38,7 +38,8 @@ class Validation if ( $id == "" ) { - $sql = "SELECT old_id FROM old WHERE old_namespace=0 AND old_title='{$article_title}' AND old_timestamp='{$article_time}'" ; + $sql = "SELECT old_id FROM old WHERE old_namespace=0 AND old_title='" . wfStrencode( $article_title ) . + "' AND old_timestamp='" . wfStrencode( $article_time ) . "'" ; $res = wfQuery( $sql, DB_READ ); if( $s = wfFetchObject( $res ) ) { @@ -51,8 +52,9 @@ class Validation function get_prev_data ( $user_id , $article_title , $article_timestamp = "" ) { $ret = array () ; - $sql = "SELECT * FROM validate WHERE val_user='{$user_id}' AND val_title='{$article_title}'" ; - if ( $article_timestamp != "" ) $sql .= " AND val_timestamp='{$article_timestamp}'" ; + $sql = "SELECT * FROM validate WHERE val_user='" . wfStrencode( $user_id ) . + "' AND val_title='" . wfStrencode( $article_title ) . "'" ; + if ( $article_timestamp != "" ) $sql .= " AND val_timestamp='" . wfStrencode( $article_timestamp ) . "'" ; $res = wfQuery( $sql, DB_READ ); while( $s = wfFetchObject( $res ) ) $ret[$s->val_timestamp][$s->val_type] = $s ; return $ret ; @@ -88,7 +90,8 @@ class Validation { if ( $article_time == "" ) { - $res = wfQuery( "select cur_timestamp FROM cur WHERE cur_title=\"{$article_title}\" AND cur_namespace=0", DB_READ ); + $res = wfQuery( "select cur_timestamp FROM cur WHERE cur_title='" . + wfStrencode( $article_title ) . "' AND cur_namespace=0", DB_READ ); if ( $s = wfFetchObject( $res ) ) $article_time = $s->cur_timestamp ; } $val[$article_time] = array () ; @@ -134,8 +137,9 @@ class Validation # Clear all others if ( isset ( $_POST['clear_other'] ) && $_POST['clear_other'] == 1 ) { - $sql = "DELETE FROM validate WHERE val_title='{$article_title}' AND val_timestamp<>'{$oldtime}' AND val_user='" ; - $sql .= $wgUser->getID() . "'" ; + $sql = "DELETE FROM validate WHERE val_title='" . wfStrencode( $article_title ) . + "' AND val_timestamp<>'" . wfStrencode( $oldtime ) . "' AND val_user='" ; + $sql .= wfStrencode( $wgUser->getID() ) . "'" ; wfQuery( $sql, DB_WRITE ); $val2 = $val["{$oldtime}"] ; # Only version left $val = array () ; # So clear others @@ -143,15 +147,15 @@ class Validation } # Delete old "votes" for this version - $sql = "DELETE FROM validate WHERE val_title='{$article_title}' AND val_timestamp='{$oldtime}' AND val_user='" ; - $sql .= $wgUser->getID() . "'" ; + $sql = "DELETE FROM validate WHERE val_title='" . wfStrencode( $article_title ) . + "' AND val_timestamp='" . wfStrencode( $oldtime ) . "' AND val_user='" ; + $sql .= wfStrencode( $wgUser->getID() ) . "'" ; wfQuery( $sql, DB_WRITE ); # Incorporate changes for ( $idx = 0 ; $idx < count ( $validationtypes) ; $idx++ ) # Changes { $comment = $postcomment[$idx] ; - $comment_sql = str_replace ( "'" , "\'" , $comment ) ; $rad = $postrad[$idx] ; if ( !isset ( $val["{$oldtime}"][$idx] ) ) $val["{$oldtime}"][$idx] = "" ; $val["{$oldtime}"][$idx]->val_value = $rad ; @@ -160,7 +164,12 @@ class Validation { # Store it in the database $sql = "INSERT INTO validate (val_user,val_title,val_timestamp,val_type,val_value,val_comment) " . - "VALUES ( '" . $wgUser->getID() . "','{$article_title}','{$oldtime}','{$idx}','{$rad}','{$comment_sql}')" ; + "VALUES ( '" . wfStrencode( $wgUser->getID() ) . "','" . + wfStrencode( $article_title ) . "','" . + wfStrencode( $oldtime ) . "','" . + wfStrencode( $idx ) . "','" . + wfStrencode( $rad ) . "','" . + wfStrencode( $comment ) . "')" ; if ( $rad != -1 ) wfQuery( $sql, DB_WRITE ); } } @@ -172,25 +181,25 @@ class Validation $html = "" ; $skin = $wgUser->getSkin() ; - $staturl = $skin->makeSpecialURL ( "validate" , "mode=stat_page&article_title={$article_title}" ) ; + $staturl = $skin->makeSpecialURL ( "validate" , "mode=stat_page&article_title=" . urlencode( $article_title ) ) ; $listurl = $skin->makeSpecialURL ( "validate" , "mode=list_page" ) ; - $html .= "" . wfMsg('val_stat_link_text') . " \n" ; - $html .= "" . wfMsg('val_article_lists') . "
\n" ; - $html .= "" . wfMsg('val_form_note') . "
\n" ; + $html .= "" . wfMsg('val_stat_link_text') . " \n" ; + $html .= "" . wfMsg('val_article_lists') . "
\n" ; + $html .= "" . wfMsg('val_form_note') . "
\n" ; # Generating data tables - $tabsep = "" ; + $tabsep = "" ; $topstyle = "style='border-top:2px solid black'" ; foreach ( $val AS $time => $stuff ) { - $tablestyle = "cellspacing=0 cellpadding=2" ; + $tablestyle = "cellspacing='0' cellpadding='2'" ; if ( $article_time == $time ) $tablestyle .=" style='border: 2px solid red'" ; $html .= "

" . wfMsg( 'val_version_of', gmdate( "F d, Y H:i:s", wfTimestamp2Unix( $time ) ) ) ; $this->find_this_version ( $article_title , $time , $table_id , $table_name ) ; if ( $table_name == "cur" ) $html .= " (" . wfMsg ( 'val_this_is_current_version' ) . ")" ; $html .= "

\n" ; - $html .= "
\n" ; - $html .= "" ; + $html .= "\n" ; + $html .= "" ; $html .= "\n" ; $html .= wfMsg( 'val_table_header', $tabsep ) ; for ( $idx = 0 ; $idx < count ( $validationtypes) ; $idx++ ) @@ -200,34 +209,34 @@ class Validation else $choice = -1 ; if ( isset ( $stuff[$idx] ) ) $comment = $stuff[$idx]->val_comment ; else $comment = "" ; - $html .= "{$tabsep}{$tabsep}" ; + $html .= "" ; $html .= "\n" ; } - $html .= "" ; + $html .= "" ; $html .= "
{$x[0]}{$x[1]}" ; + $html .= "
{$x[0]}{$x[1]}" ; for ( $cnt = 0 ; $cnt < $x[3] ; $cnt++) { - $html .= "{$tabsep}" ; - $html .= "{$tabsep}" ; + $html .= "
" ; + $html .= "
" ; # link to version $title = Title::newFromDBkey ( $article_title ) ; if ( $table_name == "cur" ) $link_version = $title->getLocalURL( "" ) ; else $link_version = $title->getLocalURL( "oldid={$table_id}" ) ; - $link_version = "" . wfMsg ( 'val_view_version' ) . "" ; + $link_version = "" . wfMsg ( 'val_view_version' ) . "" ; $html .= $link_version ; - $html .= "" ; - $html .= "" ; + $html .= "" ; + $html .= "" ; $html .= wfMsg ( 'val_merge_old' ); - $html .= "
" ; + $html .= "
" ; $html .= wfMsg ( 'val_clear_old', $skin->makeKnownLinkObj( $article ) ); - $html .= "
\n" ; } @@ -240,9 +249,9 @@ class Validation { $ret = array () ; $sql = array () ; - if ( $user != -1 ) $sql[] = "val_user='{$user}'" ; - if ( $type != -1 ) $sql[] = "val_type='{$type}'" ; - if ( $title != "" ) $sql[] = "val_title='{$title}'" ; + if ( $user != -1 ) $sql[] = "val_user='" . wfStrencode( $user ) . "'" ; + if ( $type != -1 ) $sql[] = "val_type='" . wfStrencode( $type ) . "'" ; + if ( $title != "" ) $sql[] = "val_title='" . wfStrencode( $title ) . "'" ; $sql = implode ( " AND " , $sql ) ; if ( $sql != "" ) $sql = " WHERE " . $sql ; $sql = "SELECT * FROM validate" . $sql ; @@ -277,9 +286,9 @@ class Validation $html = "" ; $skin = $wgUser->getSkin() ; $listurl = $skin->makeSpecialURL ( "validate" , "mode=list_page" ) ; - $html .= "" . wfMsg('val_article_lists') . "

\n" ; + $html .= "" . wfMsg('val_article_lists') . "

\n" ; - $html .= "\n" ; + $html .= "
\n" ; $html .= "" ; foreach ( $validationtypes AS $idx => $title ) { @@ -294,12 +303,12 @@ class Validation $title = Title::newFromDBkey ( $article_title ) ; $version_date = gmdate("F d, Y H:i:s",wfTimestamp2Unix($version)) ; $version_validate_link = $title->getLocalURL( "action=validate×tamp={$version}" ) ; - $version_validate_link = "" . wfMsg('val_validate_version') . "" ; + $version_validate_link = "" . wfMsg('val_validate_version') . "" ; if ( $table_name[$version] == 'cur' ) $version_view_link = $title->getLocalURL( "" ) ; else $version_view_link = $title->getLocalURL( "oldid={$table_id[$version]}" ) ; $version_view_link = "" . wfMsg('val_view_version') . "" ; $html .= "" ; - $html .= "" ; + $html .= "" ; # Individual data $vmax = array() ; @@ -330,13 +339,13 @@ class Validation $total_percent += $average ; if ( $users[$idx] > 1 ) $msgid = "val_percent" ; else $msgid = "val_percent_single" ; - $html .= "" ; @@ -348,7 +357,7 @@ class Validation $total = number_format ( $total , 2 ) . " %" ; } else $total = "" ; - $html .= "" ; + $html .= "" ; $html .= "" ; } @@ -358,7 +367,7 @@ class Validation function countUserValidations ( $userid ) { - $sql = "SELECT count(DISTINCT val_title) AS num FROM validate WHERE val_user={$userid}" ; + $sql = "SELECT count(DISTINCT val_title) AS num FROM validate WHERE val_user=" . IntVal( $userid ); $res = wfQuery( $sql, DB_READ ); if ( $s = wfFetchObject( $res ) ) $num = $s->num ; else $num = 0 ; @@ -394,33 +403,33 @@ class Validation # The form - $html .= "\n" ; - $html .= "
" . wfMsg('val_version') . "
{$version_date}
{$version_view_link}
{$version_validate_link}
{$version_date}
{$version_view_link}
{$version_validate_link}
" . + $html .= "" . wfMsg ( $msgid, number_format ( $average , 2 ) , $vcur[$idx] , $vmax[$idx] , $users[$idx] ) ; } else { - $html .= "" ; + $html .= "" ; $html .= "(" . wfMsg ( "val_noop" ) . ")" ; } $html .= "{$total}{$total}
" ; + $html .= "\n" ; + $html .= "
" ; foreach ( $validationtypes AS $idx => $data ) { $x = explode ( "|" , $data , 4 ) ; $html .= "" ; - $html .= "" ; - $html .= "" ; + $html .= "" ; + $html .= "" ; for ( $a = 0 ; $a < $maxw ; $a++ ) { if ( $a < $x[3] ) { - $td = "\n" ; - $html .= "" ; + $html .= "\n" ; + $html .= "" ; $html .= "
{$x[0]}{$x[1]}{$x[0]}{$x[1]}
\n" ; $html .= "\n" ; @@ -455,7 +464,7 @@ class Validation if ( count ( $out ) > 0 ) { $html .= "
  • \n" ; - $html .= $title->getText() . "\n" ; + $html .= htmlspecialchars( $title->getText() ) . "\n" ; $html .= "\n
  • \n" ; @@ -472,11 +481,11 @@ class Validation if ( $table_name == 'cur' ) $link = $title->getLocalURL( "" ) ; else $link = $title->getLocalURL( "action=validate×tamp={$table_id}" ) ; $linktitle = wfMsg( 'val_version_of', gmdate( "F d, Y H:i:s", wfTimestamp2Unix( $timestamp ) ) ) ; - $link = "" . $linktitle . "" ; + $link = "" . $linktitle . "" ; if ( $table_name == 'cur' ) $link .= " (" . wfMsg ( 'val_this_is_current_version' ) . ")" ; $vlink = wfMsg ( 'val_tab' ) ; - $vlink = "[getLocalURL( "action=validate×tamp={$timestamp}" ) . "\">{$vlink}] " . $link ; + $vlink = "[escapeLocalURL( "action=validate×tamp={$timestamp}" ) . "\">{$vlink}] " . $link ; return $vlink ; } -- 2.20.1