# HG changeset patch # User Dan # Date 1196390882 18000 # Node ID 5585ac341820ae169111b32d99d75cd87879102b # Parent 36bc382ed4596305e8dd2762e09a2af5c998dd6a SECURITY: fix stupid XSS vulnerability on initial post submit; add in support for the new search API diff -r 36bc382ed459 -r 5585ac341820 decir/functions.php --- a/decir/functions.php Wed Nov 14 19:26:21 2007 -0500 +++ b/decir/functions.php Thu Nov 29 21:48:02 2007 -0500 @@ -35,6 +35,16 @@ $post_text = $db->escape($post_text); $post_subject = $db->escape($post_subject); + if ( empty($post_subject) ) + { + $q = $db->sql_query('SELECT topic_title FROM '.table_prefix.'decir_topics WHERE topic_id = ' . $topic_id . ';'); + if ( !$q ) + $db->_die('Decir functions.php in decir_submit_post()'); + if ( $db->numrows() < 1 ) + return false; + list($post_subject) = $db->fetchrow_num(); + $post_subject = 'Re: ' . $db->escape($post_subject); + } $q = $db->sql_query('INSERT INTO '.table_prefix."decir_posts(topic_id,poster_id,poster_name,post_subject,timestamp) VALUES($topic_id, $poster_id, '$poster_name', '$post_subject', $timestamp);"); if ( !$q ) @@ -114,7 +124,7 @@ if ( !$q ) $db->_die('Decir functions.php in decir_edit_post()'); - $q = $db->sql_query('UPDATE '.table_prefix."decir_posts_text SET post_text='$post_text' WHERE post_id=$post_id;"); + $q = $db->sql_query('UPDATE '.table_prefix."decir_posts_text SET post_text='$post_text',bbcode_uid='$bbcode_uid' WHERE post_id=$post_id;"); if ( !$q ) $db->_die('Decir functions.php in decir_edit_post()'); diff -r 36bc382ed459 -r 5585ac341820 decir/posting.php --- a/decir/posting.php Wed Nov 14 19:26:21 2007 -0500 +++ b/decir/posting.php Thu Nov 29 21:48:02 2007 -0500 @@ -90,11 +90,13 @@ if ( sizeof($errors) < 1 ) { // Collect other options + $post_text = trim(htmlspecialchars($_POST['post_text'])); + $post_subject = trim(htmlspecialchars($_POST['subject'])); // Submit post if ( $parms['mode'] == 'reply' || $parms['mode'] == 'quote' ) { - $result = decir_submit_post($parms['topic_in'], $_POST['subject'], $_POST['post_text'], $post_id); + $result = decir_submit_post($parms['topic_in'], $post_subject, $post_text, $post_id); if ( $result ) { // update forum stats @@ -110,7 +112,7 @@ } else if ( $parms['mode'] == 'topic' ) { - $result = decir_submit_topic($parms['forum_id'], $_POST['subject'], $_POST['post_text'], $topic_id, $post_id); + $result = decir_submit_topic($parms['forum_id'], $post_subject, $post_text, $topic_id, $post_id); if ( $result ) { // update forum stats diff -r 36bc382ed459 -r 5585ac341820 decir/search.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/decir/search.php Thu Nov 29 21:48:02 2007 -0500 @@ -0,0 +1,135 @@ +attachHook('search_global_inner', 'decir_search($query, $query_phrase, $scores, $page_data, $case_sensitive, $word_list);'); + +/** + * Searches the forums for the specified search terms. Called from a hook. + * @access private + */ + +function decir_search(&$query, &$query_phrase, &$scores, &$page_data, &$case_sensitive, &$word_list) +{ + global $db, $session, $paths, $template, $plugins; // Common objects + + require_once( DECIR_ROOT . '/bbcode.php' ); + require_once( DECIR_ROOT . '/functions_viewtopic.php' ); + + // Based on the search function from Snapr + + // Let's do this all in one query + $terms = array( + 'any' => array_merge($query['any'], $query_phrase['any']), + 'req' => array_merge($query['req'], $query_phrase['req']), + 'not' => $query['not'] + ); + $where = array('any' => array(), 'req' => array(), 'not' => array()); + $where_any =& $where['any']; + $where_req =& $where['req']; + $where_not =& $where['not']; + $title_col = ( $case_sensitive ) ? 'p.post_subject' : 'lcase(p.post_subject)'; + $desc_col = ( $case_sensitive ) ? 't.post_text' : 'lcase(t.post_text)'; + foreach ( $terms['any'] as $term ) + { + $term = escape_string_like($term); + if ( !$case_sensitive ) + $term = strtolower($term); + $where_any[] = "( $title_col LIKE '%{$term}%' OR $desc_col LIKE '%{$term}%' )"; + } + foreach ( $terms['req'] as $term ) + { + $term = escape_string_like($term); + if ( !$case_sensitive ) + $term = strtolower($term); + $where_req[] = "( $title_col LIKE '%{$term}%' OR $desc_col LIKE '%{$term}%' )"; + } + foreach ( $terms['not'] as $term ) + { + $term = escape_string_like($term); + if ( !$case_sensitive ) + $term = strtolower($term); + $where_not[] = "$title_col NOT LIKE '%{$term}%' AND $desc_col NOT LIKE '%{$term}%'"; + } + if ( empty($where_any) ) + unset($where_any, $where['any']); + if ( empty($where_req) ) + unset($where_req, $where['req']); + if ( empty($where_not) ) + unset($where_not, $where['not']); + + $where_any = '(' . implode(' OR ', $where_any) . '' . ( isset($where['req']) || isset($where['not']) ? ' OR 1 = 1' : '' ) . ')'; + + if ( isset($where_req) ) + $where_req = implode(' AND ', $where_req); + if ( isset($where_not) ) + $where_not = implode( 'AND ', $where_not); + + $where = implode(' AND ', $where); + $sql = "SELECT p.post_id, p.post_subject, t.post_text, p.poster_name, p.poster_id, u.username, p.edit_count, p.last_edited_by, p.timestamp,\n" + . " p.post_deleted, u2.username AS editor, p.edit_reason, u.user_level, u.reg_time, t.post_text, t.bbcode_uid\n" + . " FROM " . table_prefix . "decir_posts AS p\n" + . " LEFT JOIN " . table_prefix . "decir_posts_text AS t\n" + . " ON ( t.post_id = p.post_id )\n" + . " LEFT JOIN " . table_prefix . "users AS u2\n" + . " ON (u2.user_id=p.last_edited_by OR p.last_edited_by IS NULL)\n" + . " LEFT JOIN " . table_prefix . "users AS u\n" + . " ON ( u.user_id = p.poster_id )\n" + . " WHERE ( $where ) AND post_deleted != 1\n" + . " GROUP BY p.post_id;"; + + if ( !($q = $db->sql_unbuffered_query($sql)) ) + { + $db->_die('Error is in auto-generated SQL query in the Decir plugin search module'); + } + + $postbit = new DecirPostbit(); + + if ( $row = $db->fetchrow() ) + { + do + { + $idstring = 'ns=DecirPost;pid=' . $row['post_id']; + foreach ( $word_list as $term ) + { + $func = ( $case_sensitive ) ? 'strstr' : 'stristr'; + $inc = ( $func($row['post_subject'], $term) ? 1.5 : ( $func($row['text'], $term) ? 1 : 0 ) ); + ( isset($scores[$idstring]) ) ? $scores[$idstring] = $scores[$idstring] + $inc : $scores[$idstring] = $inc; + } + // Generate text... + $text = render_bbcode($row['post_text'], $row['bbcode_uid']); + $text = highlight_and_clip_search_result($text, $word_list); + $post_length = strlen($row['post_text']); + + $row['post_text'] = $text; + $rendered_postbit = $postbit->_render('', $row); + + // Inject result + + if ( isset($scores[$idstring]) ) + { + // echo('adding image "' . $row['img_title'] . '" to results
'); + $page_data[$idstring] = array( + 'page_name' => highlight_search_result(htmlspecialchars($row['post_subject']), $word_list), + 'page_text' => $rendered_postbit, + 'score' => $scores[$idstring], + 'page_note' => '[Forum post]', + 'page_id' => strval($row['post_id']), + 'namespace' => 'DecirPost', + 'page_length' => $post_length, + ); + } + } + while ( $row = $db->fetchrow() ); + } +} diff -r 36bc382ed459 -r 5585ac341820 decir/viewforum.php --- a/decir/viewforum.php Wed Nov 14 19:26:21 2007 -0500 +++ b/decir/viewforum.php Thu Nov 29 21:48:02 2007 -0500 @@ -78,6 +78,8 @@ { if ( $num_replies < 0 ) $num_replies = 0; + if ( $i == $db->numrows() && $i == 1 ) + $num_replies++; if ( $last_row['topic_deleted'] == 1 ) { $thread_link = '<Deleted>'; diff -r 36bc382ed459 -r 5585ac341820 plugins/Decir.php --- a/plugins/Decir.php Wed Nov 14 19:26:21 2007 -0500 +++ b/plugins/Decir.php Thu Nov 29 21:48:02 2007 -0500 @@ -34,6 +34,7 @@ '); require( DECIR_ROOT . '/admincp/admin_base.php' ); +require( DECIR_ROOT . '/search.php' ); function decir_early_init(&$paths, &$session) {