2017-02-07 2 views
2

Следующий плагин используется для уведомления пользователей для членов форума vbulletin.уязвимость в плагине уведомлений о цитатах

друг сказал мне, что существует возможность уязвимости в базе данных Mysql из-за этого плагина. Я не эксперт mysql, поэтому я не могу сказать, в чем именно проблема.

Если кто-нибудь обнаружит эту уязвимость, я хотел бы точно знать, что я должен сделать, чтобы исправить ее.

С плагином приходит это PHP-страницу, которая будет отображаться список уведомлений для члена http://textuploader.com/d1hch не уверен, если это PHP скрипт имеет любую уязвимость

вопрос, может быть, связанные с Mysqli :: escape_string или PDO подготовили заявление ,

<?xml version="1.0" encoding="ISO-8859-1"?> 

<product productid="k_quote_notifications" active="0"> 
    <title>Quote Notifications</title> 
    <description>Notify User after being quoted</description> 
    <version>1.0.0</version> 
    <url></url> 
    <versioncheckurl></versioncheckurl> 
    <dependencies> 
    </dependencies> 
    <codes> 
     <code version="1.0.0"> 
      <installcode><![CDATA[$db->hide_errors(); 
$db->query_write(" 
CREATE TABLE " . TABLE_PREFIX . "quotedatanew (
    `quoted` int(10) NOT NULL default '0', 
    `quoter` int(10) NOT NULL default '0', 
    `quotername` varchar(255) NOT NULL default '0', 
    `postid` int(10) NOT NULL default '0', 
    `threadid` int(10) NOT NULL default '0', 
    `threadtitle` varchar(255) NOT NULL default '0', 
    `dateline` int(10) NOT NULL default '0', 
    `hasseen` int(1) NOT NULL default '0', 
    KEY `quoted` (`quoted`) 
) 
"); 
$db->show_errors();]]></installcode> 
      <uninstallcode><![CDATA[$db->query_write(" 
DROP TABLE " . TABLE_PREFIX . "quotedatanew 
");]]></uninstallcode> 
     </code> 
    </codes> 
    <templates> 
     <template name="NOTI" templatetype="template" date="1401826799" username="AAA" version="1.0.0"><![CDATA[$stylevar[htmldoctype] 
<html dir="$stylevar[textdirection]" lang="$stylevar[languagecode]"> 
<head> 
<title>$vboptions[bbtitle]</title> 

<style type="text/css"> 
.alert-box { 
    color:#555; 
    border-radius:10px; 
    font-family:Tahoma,Geneva,Arial,sans-serif;font-size:11px; 
    padding:10px 36px; 
    margin:10px; 
} 
.alert-box span { 
    font-weight:bold; 
    text-transform:uppercase; 
} 
.error { 
    background:#ffecec url('images/error.png') no-repeat 10px 50%; 
    border:1px solid #f5aca6; 
} 
.success { 
    background:#e9ffd9 url('images/success.png') no-repeat 10px 50%; 
    border:1px solid #a6ca8a; 
} 
.warning { 
    background:#fff8c4 url('images/warning.png') no-repeat 10px 50%; 
    border:1px solid #f2c779; 
} 
.notice { 
    background:#e3f7fc url('images/notice.png') no-repeat 10px 50%; 
    border:1px solid #8ed9f6; 
} 
.paginate { 
font-family:Arial, Helvetica, sans-serif; 
    padding: 3px; 
    margin: 3px; 
} 

.paginate a { 
    padding:2px 5px 2px 5px; 
    margin:2px; 
    border:1px solid #999; 
    text-decoration:none; 
    color: #666; 
} 
.paginate a:hover, .paginate a:active { 
    border: 1px solid #999; 
    color: #000; 
} 
.paginate span.current { 
    margin: 2px; 
    padding: 2px 5px 2px 5px; 
     border: 1px solid #999; 

     font-weight: bold; 
     background-color: #999; 
     color: #FFF; 
    } 
    .paginate span.disabled { 
     padding:2px 5px 2px 5px; 
     margin:2px; 
     border:1px solid #eee; 
     color:#DDD; 
    } 

</style> 
$headinclude 
</head> 
<body> 
$header 

$navbar 

<table class="tborder" cellpadding="$stylevar[cellpadding]" cellspacing="$stylevar[cellspacing]" border="0" width="100%" align="center"> 
<tr> 
    <td class="tcat">$vbphrase[notification_page_title]</td> 
</tr> 
<tr> 
    <td class="alt1">$content</td> 
</tr> 
$paginate 
</table> 

$footer 
</body> 
</html>]]></template> 
     <template name="TEST" templatetype="template" date="1401824077" username="AAA" version="1.0.0"><![CDATA[$stylevar[htmldoctype] 
<html dir="$stylevar[textdirection]" lang="$stylevar[languagecode]"> 
<head> 
<title>$vboptions[bbtitle]</title> 
$headinclude 
</head> 
<body> 
$header 

$navbar 

<table class="tborder" cellpadding="$stylevar[cellpadding]" cellspacing="$stylevar[cellspacing]" border="0" width="100%" align="center"> 
<tr> 
    <td class="tcat">Title</td> 
</tr> 
<tr> 
    <td class="alt1">Text</td> 
</tr> 
</table> 

$footer 
</body> 
</html>]]></template> 
    </templates> 
    <plugins> 
     <plugin active="1" executionorder="5"> 
      <title>Get Notifications</title> 
      <hookname>global_start</hookname> 
      <phpcode><![CDATA[$counter = $vbulletin->db->query_first("SELECT COUNT(*) AS id FROM quotedatanew where quoted =" . $vbulletin->userinfo['userid'] . " and hasseen= '0'"); 
$count = $counter['id']; 
$notifi = $vbulletin->db->query_read("SELECT * FROM quotedatanew where quoted =" . $vbulletin->userinfo['userid'] . " and hasseen = '0' ORDER BY dateline DESC LIMIT 4"); 
while ($noti = $vbulletin->db->fetch_array($notifi)) { 
    $threadurl = $vbulletin->options['bburl'] . '/showthread.php?source=noti&p=' . $noti['postid'] . '#post' . $noti['postid']; 
    $memberurl = $vbulletin->options['bburl'] . '/member.php?u=' . $noti['quoter']; 
    $notiurl  = $vbulletin->options['bburl'] . '/noti.php'; 
    $qoutername = $noti['quotername']; 
    $threadname = $noti['threadtitle']; 
    $phrasequote = $vbphrase['has_quoted_your_post_in']; 
    $seeallphrase = $vbphrase['see_all_noti']; 
    $notihtml .= '<tr><td class="vbmenu_option" style="white-space:normal;max-width:200px;"><a href="' . $memberurl . '">' . $qoutername . '</a> ' . $phrasequote . ' <a href="' . $threadurl . '">' . $threadname . '</a></td></tr>'; 
} 
if ($count > 4) { 
    $notihtml .= '<tr><td class="vbmenu_option" style="white-space:normal;max-width:200px;"><a href="' . $notiurl . '">' . $seeallphrase . '</a></td></tr>'; 
}]]></phpcode> 
     </plugin> 
     <plugin active="1" executionorder="5"> 
      <title>Insert Notification</title> 
      <hookname>newpost_complete</hookname> 
      <phpcode><![CDATA[if ($vbulletin->options['wqm_system'] == true) { 


    if (preg_match('/\[quote=(.*?)\]((?:.|\s)+?)\[\/quote\]/i', $post['message'])) { 
     preg_match_all('/\[quote=(.*?)\]((?:.|\s)+?)\[\/quote\]/i', $post['message'], $quotematch); 

     $quotecount = count($quotematch[0]); 
     $tempcount = 0; 
     $quotearray = array(); 


     while ($tempcount < $quotecount) { 
      $username  = explode(';', $quotematch[1][$tempcount]); 
      $quoteduserid = $vbulletin->db->query_first("SELECT userid FROM " . TABLE_PREFIX . "user 
      WHERE username = '" . $vbulletin->db->escape_string(htmlspecialchars_uni($username[0])) . "'"); 

      if (!in_array($quoteduserid['userid'], $quotearray)) { 
       if ($quoteduserid['userid'] > 0 AND $quoteduserid['userid'] != $vbulletin->userinfo['userid']) { 
        $quotearray[] = $quoteduserid['userid']; 

        // check forum permissions 
        $quoteduserinfo = fetch_userinfo(intval($quoteduserid['userid'])); 
        $forumperms  = fetch_permissions($foruminfo['forumid'], intval($quoteduserid['userid']), $quoteduserinfo); 

        if (!($forumperms & $vbulletin->bf_ugp_forumpermissions['canview']) OR !($forumperms & $vbulletin->bf_ugp_forumpermissions['canviewthreads'])) { 
         $tempcount++; 
         continue; 
        } 
        if (!($forumperms & $vbulletin->bf_ugp_forumpermissions['canviewothers']) AND ($threadinfo['postuserid'] != intval($quoteduserid['userid']) OR $vbulletin->userinfo['userid'] == 0)) { 
         $tempcount++; 
         continue; 
        } 

        $vbulletin->db->query_write(" 
        INSERT INTO " . TABLE_PREFIX . "quotedatanew (quoted,quoter,postid,threadid,threadtitle,dateline,quotername) 
        VALUES ('" . $quoteduserid['userid'] . "','" . $vbulletin->userinfo['userid'] . "','" . $post['postid'] . "','" . $threadinfo[threadid] . "','" . $vbulletin->db->escape_string(htmlspecialchars_uni($threadinfo[title])) . "','" . time() . "','" . $vbulletin->db->escape_string(htmlspecialchars_uni($vbulletin->userinfo['username'])) . "')"); 
       } 
      } 
      $tempcount++; 
     } 
    } 


}]]></phpcode> 
     </plugin> 
     <plugin active="1" executionorder="5"> 
      <title>Dismiss notification</title> 
      <hookname>showthread_start</hookname> 
      <phpcode><![CDATA[$postid = intval($_GET["p"]); 
$source = $_GET["source"]; 
if ($source == "noti") { 
    $vbulletin->db->query_write("update quotedatanew set hasseen = '1' where postid = '" . $postid . "' and quoted = '" . $vbulletin->userinfo['userid'] . "'"); 
}]]></phpcode> 
     </plugin> 
    </plugins> 
    <phrases> 
     <phrasetype name="GLOBAL" fieldname="global"> 
      <phrase name="delete_all_nots" date="1401999437" username="bbb" version="1.0.0"><![CDATA[Õ–› ÄÌ⁄ «· ‰»Ì« ]]></phrase> 
      <phrase name="has_quoted_your_post_in" date="1401739493" username="AAA" version="1.0.0"><![CDATA[Has Quoted Your Post In]]></phrase> 
      <phrase name="no_notification_text" date="1401999471" username="bbb" version="1.0.0"><![CDATA[·« ÌÊÃœ  ‰»Ì«  Ü̜…]]></phrase> 
      <phrase name="noti_icon" date="1401829523" username="AAA" version="1.0.0"><![CDATA[Notifications]]></phrase> 
      <phrase name="notification_read" date="1401825953" username="AAA" version="1.0.0"><![CDATA[Read]]></phrase> 
      <phrase name="notification_unread" date="1401826023" username="AAA" version="1.0.0"><![CDATA[Unread]]></phrase> 
      <phrase name="see_all_noti" date="1401810412" username="AAA" version="1.0.0"><![CDATA[See All Notification]]></phrase> 
     </phrasetype> 
     <phrasetype name="vBulletin Settings" fieldname="vbsettings"> 
      <phrase name="setting_wqm_system_desc" date="1401828337" username="AAA" version="1.0.0"><![CDATA[<style type="text/css"> 
body { background:#555;color:white; } 
a:link, a:visited, a:active { color:white; } 
.optiontitle { background:#10a113;color:#FFF;border:none; } 
.button { background:#10A113;border:none;color:white;padding:6px 12px;} 
.button:hover { background:#057c08; } 
.tcat { color:white;background: #111;border:none; } 
.tcat a:link, .tcat a:visited, .tcat a:active { color:white; } 
.tfoot { background:#111;border:none; } 
.alt1 { color:white;background:#333; } 
.tborder { border:1px solid #000; -moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow: 2px 2px 8px #000;-webkit-box-shadow: 2px 2px 8px #000;box-shadow: 2px 2px 8px #000; } 
textarea, .bginput, input.col-c, input.col-i, input.col-g { border:1px solid #000;color:#EEE;background:#444; } 
.pagetitle { background:#111;color:white;border:1px solid #000;-moz-box-shadow: 2px 2px 8px #000;-webkit-box-shadow: 2px 2px 8px #000;box-shadow: 2px 2px 8px #000; } 
</style>]]></phrase> 
      <phrase name="setting_wqm_system_title" date="1401828337" username="AAA" version="1.0.0"><![CDATA[Enable Notifications System]]></phrase> 
      <phrase name="settinggroup_Notification System" date="1401828329" username="AAA" version="1.0.0"><![CDATA[Notification System]]></phrase> 
     </phrasetype> 
    </phrases> 
    <options> 
     <settinggroup name="Notification System" displayorder="590"> 
      <setting varname="wqm_system" displayorder="10"> 
       <datatype>boolean</datatype> 
       <optioncode>yesno</optioncode> 
       <defaultvalue>1</defaultvalue> 
      </setting> 
     </settinggroup> 
    </options> 
    <helptopics> 
    </helptopics> 
    <cronentries> 
    </cronentries> 
    <faqentries> 
    </faqentries> 
</product> 

ответ

0

Единственный потенциальный вопрос, который я вижу с этим кодом, что запросы застроены конкатенации строк вместо того, чтобы использовать подготовленные заявления, экс:

 $quoteduserid = $vbulletin->db->query_first("SELECT userid FROM " . TABLE_PREFIX . "user 
     WHERE username = '" . $vbulletin->db->escape_string(htmlspecialchars_uni($username[0])) . "'"); 

Это подвергает запросы потенциальных инъекций атак SQL.

я вижу в коде, которые принимаются меры предосторожности, например, в Передней username где положение совмещают с:

username = '" . $vbulletin->db->escape_string(htmlspecialchars_uni($username[0])) . "'" 

username спасшемся db->escape_string, который должен предотвратить атаки инъекций. Но ошибка в этой функции может привести к тому, что код будет небезопасным.

Единственный рекомендуемый и пуленепробиваемый способ выполнения запросов - использование готовых таблиц.

Вот ссылка на prepared statements mysqli

Подготовленные заявления позволяют передать параметр, который будет использоваться в запросе (напр. Имя пользователя,) непосредственно к Mysqli или PDO. При таком подходе нет возможности для символьной или символьной последовательности в параметре «разбить» запрос, как это могло бы произойти, когда запрос строится путем конкатенации статических строк и (экранированных) значений переменных.


Если вы хотите улучшить код, вы должны подставить каждый запрос в его «подготовленной форме заявления».

Запросы с готовыми запросами легко сделать (просто проверьте, является ли $vbullettin->db соединение mysqli или PDO для использования правильных методов).

В качестве параметров следует передать неэкранированный вы должны проверить, что на самом деле делает $vbulletin->db->escape_string (в данном примере) для того, чтобы данные в хранимых в БД сохранить свой формат.

+0

Есть ли способ связаться с вами? электронная почта или любой контакт – user3693856

+0

@ user3693856, привет, извините, на данный момент я не даю своих контактных данных на SO. В любом случае, если вам нужна помощь в этом вопросе, я не могу помочь, потому что сейчас я слишком занят. Конечно, если что-то в моем ответе не ясно, просто укажите это, и я сделаю все возможное, чтобы улучшить его. – Paolo

+0

К сожалению, я не эксперт mysql.Любые советы, чтобы связаться с кем-то, кто мог бы справиться с этим как фрилансер? Я использовал freelancer.com, и никто не понимает, что мне нужно, даже после объяснения того, что вы сказали. – user3693856

Смежные вопросы