REPORT / 01
Analysis Report · mybb mybb_1807 → mybb_1808
Shared security patch analysis results
02 ·
Share this analysis
copy link · embed report
03 ·
Findings
filter · search · paginate
Showing 0 to 0 of 0 results
admin/inc/class_page.php
AI: 1 vulnerabilities
1 true positive
--- cache/mybb_mybb_1807/admin/inc/class_page.php 2025-12-06 11:32:55.082119266 +0000+++ cache/mybb_mybb_1808/admin/inc/class_page.php 2025-12-06 11:32:55.894171701 +0000@@ -142,7 +142,8 @@ echo "<body>\n"; echo "<div id=\"container\">\n"; echo " <div id=\"logo\"><h1><span class=\"invisible\">{$lang->mybb_admin_cp}</span></h1></div>\n";- echo " <div id=\"welcome\"><span class=\"logged_in_as\">{$lang->logged_in_as} <a href=\"index.php?module=user-users&action=edit&uid={$mybb->user['uid']}\" class=\"username\">{$mybb->user['username']}</a></span> | <a href=\"{$mybb->settings['bburl']}\" target=\"_blank\" class=\"forum\">{$lang->view_board}</a> | <a href=\"index.php?action=logout&my_post_key={$mybb->post_code}\" class=\"logout\">{$lang->logout}</a></div>\n";+ $username = htmlspecialchars_uni($mybb->user['username']);+ echo " <div id=\"welcome\"><span class=\"logged_in_as\">{$lang->logged_in_as} <a href=\"index.php?module=user-users&action=edit&uid={$mybb->user['uid']}\" class=\"username\">{$username}</a></span> | <a href=\"{$mybb->settings['bburl']}\" target=\"_blank\" class=\"forum\">{$lang->view_board}</a> | <a href=\"index.php?action=logout&my_post_key={$mybb->post_code}\" class=\"logout\">{$lang->logout}</a></div>\n"; echo $this->_build_menu(); echo " <div id=\"page\">\n"; echo " <div id=\"left_menu\">\n";@@ -224,7 +225,7 @@ echo " <br style=\"clear: both;\" />"; echo " <br style=\"clear: both;\" />"; echo " </div>\n";- echo "<div id=\"footer\"><p class=\"generation\">".$lang->sprintf($lang->generated_in, $totaltime, $debuglink, $querycount, $memory_usage)."</p><p class=\"powered\">Powered By <a href=\"http://www.mybb.com/\" target=\"_blank\">MyBB</a>, © 2002-".COPY_YEAR." <a href=\"http://www.mybb.com/\" target=\"_blank\">MyBB Group</a>.</p></div>\n";+ echo "<div id=\"footer\"><p class=\"generation\">".$lang->sprintf($lang->generated_in, $totaltime, $debuglink, $querycount, $memory_usage)."</p><p class=\"powered\">Powered By <a href=\"https://mybb.com/\" target=\"_blank\">MyBB</a>, © 2002-".COPY_YEAR." <a href=\"https://mybb.com/\" target=\"_blank\">MyBB Group</a>.</p></div>\n"; if($mybb->debug_mode) { echo $db->explain;@@ -902,11 +903,11 @@ if($smilies) { if($mybb->settings['smilieinserter'] && $mybb->settings['smilieinsertercols'] && $mybb->settings['smilieinsertertot'])- { + { $emoticon = ",emoticon"; } $emoticons_enabled = "true";- + if(!$smiliecount) { $smilie_cache = $cache->read("smilies");@@ -939,7 +940,7 @@ { $finds = explode("\n", $smilie['find']); $finds_count = count($finds);- + // Only show the first text to replace in the box $find = str_replace(array('\\', '"'), array('\\\\', '\"'), htmlspecialchars_uni($finds[0])); $image = str_replace(array('\\', '"'), array('\\\\', '\"'), htmlspecialchars_uni($smilie['image']));@@ -950,7 +951,7 @@ if(!$mybb->settings['smilieinserter'] || !$mybb->settings['smilieinsertercols'] || !$mybb->settings['smilieinsertertot'] || !$smilie['showclickable']) {- $hiddensmilies .= '"'.$find.'": "'.$image.'",'; + $hiddensmilies .= '"'.$find.'": "'.$image.'",'; } elseif($i < $mybb->settings['smilieinsertertot']) {
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - admin/inc/class_page.php - Line 145
Old Code:
```php
echo " <div id=\"welcome\"><span class=\"logged_in_as\">{$lang->logged_in_as} <a href=\"index.php?module=user-users&action=edit&uid={$mybb->user['uid']}\" class=\"username\">{$mybb->user['username']}</a></span> | <a href=\"{$mybb->settings['bburl']}\" target=\"_blank\" class=\"forum\">{$lang->view_board}</a> | <a href=\"index.php?action=logout&my_post_key={$mybb->post_code}\" class=\"logout\">{$lang->logout}</a></div>\n";
```
Fixed Code:
```php
$username = htmlspecialchars_uni($mybb->user['username']);
echo " <div id=\"welcome\"><span class=\"logged_in_as\">{$lang->logged_in_as} <a href=\"index.php?module=user-users&action=edit&uid={$mybb->user['uid']}\" class=\"username\">{$username}</a></span> | <a href=\"{$mybb->settings['bburl']}\" target=\"_blank\" class=\"forum\">{$lang->view_board}</a> | <a href=\"index.php?action=logout&my_post_key={$mybb->post_code}\" class=\"logout\">{$lang->logout}</a></div>\n";
```
Explanation:
The username stored in `$mybb->user['username']` is user-controlled data that was directly embedded in HTML output without sanitization. An attacker could inject malicious JavaScript or HTML through their username field, which would execute in the context of the admin panel for any administrator viewing the welcome section. The fix applies `htmlspecialchars_uni()` to escape the username before output, preventing XSS payload execution.
---
Vulnerability Existed: no
Insecure Protocol - CWE-295 - admin/inc/class_page.php - Line 228
Old Code:
```php
echo "<div id=\"footer\"><p class=\"generation\">".$lang->sprintf($lang->generated_in, $totaltime, $debuglink, $querycount, $memory_usage)."</p><p class=\"powered\">Powered By <a href=\"http://www.mybb.com/\" target=\"_blank\">MyBB</a>, © 2002-".COPY_YEAR." <a href=\"http://www.mybb.com/\" target=\"_blank\">MyBB Group</a>.</p></div>\n";
```
Fixed Code:
```php
echo "<div id=\"footer\"><p class=\"generation\">".$lang->sprintf($lang->generated_in, $totaltime, $debuglink, $querycount, $memory_usage)."</p><p class=\"powered\">Powered By <a href=\"https://mybb.com/\" target=\"_blank\">MyBB</a>, © 2002-".COPY_YEAR." <a href=\"https://mybb.com/\" target=\"_blank\">MyBB Group</a>.</p></div>\n";
```
Explanation:
While not a direct code vulnerability, this change upgrades HTTP links to HTTPS for external resources (mybb.com). The change improves security by ensuring users are directed to secure connections when visiting the MyBB website from the admin panel, and also updates the URL to the current domain. This is a security hardening measure rather than a vulnerability fix.
---
Vulnerability Existed: no
[Whitespace/Code Quality Changes] - admin/inc/class_page.php - Lines 906, 908, 943, 954
Explanation:
The remaining changes in the diff are purely whitespace corrections (trailing spaces and indentation fixes). These are code quality improvements with no security implications.
admin/inc/functions_themes.php
AI: 1 vulnerabilities
1 true positive
--- cache/mybb_mybb_1807/admin/inc/functions_themes.php 2025-12-06 11:32:55.082119266 +0000+++ cache/mybb_mybb_1808/admin/inc/functions_themes.php 2025-12-06 11:32:55.894171701 +0000@@ -388,7 +388,7 @@ { global $mybb; - $filename = str_replace('/', '', $filename);+ $filename = basename($filename); $tid = (int) $tid; $theme_directory = "cache/themes/theme{$tid}";
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Path Traversal - CWE-22 - admin/inc/functions_themes.php lines 391
Old Code:
```php
$filename = str_replace('/', '', $filename);
```
Fixed Code:
```php
$filename = basename($filename);
```
Explanation:
The original code attempted to prevent path traversal by simply removing forward slashes from the filename using `str_replace('/', '', $filename)`. This is an inadequate security fix because:
1. **Incomplete filtering**: The code only removes forward slashes (`/`) but doesn't handle backslashes (`\`), which can also be used for path traversal on Windows systems or in certain PHP contexts.
2. **Ineffective against encoded traversal**: Attackers could use URL-encoded slashes (`%2f`) or other bypass techniques that `str_replace` wouldn't catch.
3. **Still vulnerable to directory traversal**: An attacker could potentially use sequences like `..` combined with other techniques to escape the intended directory.
The fix using `basename($filename)` is significantly more secure because:
- `basename()` is a built-in PHP function specifically designed to extract only the filename component from a path
- It strips all directory information, including both forward slashes and backslashes
- It properly handles various edge cases and platform-specific path separators
- It's the recommended approach for isolating filenames from user input
This is a proper security fix that addresses the path traversal vulnerability by using the appropriate PHP function for filename extraction rather than attempting fragile string filtering.
admin/inc/functions_view_manager.php
AI: 1 vulnerabilities
1 true positive
--- cache/mybb_mybb_1807/admin/inc/functions_view_manager.php 2025-12-06 11:32:55.082119266 +0000+++ cache/mybb_mybb_1808/admin/inc/functions_view_manager.php 2025-12-06 11:32:55.894171701 +0000@@ -575,7 +575,8 @@ $view_type = "group"; if($view['username']) {- $created = "<br /><small>{$lang->created_by} {$view['username']}</small>";+ $username = htmlspecialchars_uni($view['username']);+ $created = "<br /><small>{$lang->created_by} {$username}</small>"; } } else
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - admin/inc/functions_view_manager.php [Line 578]
Old Code:
```php
$created = "<br /><small>{$lang->created_by} {$view['username']}</small>";
```
Fixed Code:
```php
$username = htmlspecialchars_uni($view['username']);
$created = "<br /><small>{$lang->created_by} {$username}</small>";
```
Explanation:
The original code directly interpolated `$view['username']` into HTML output without escaping. If the username contains special characters or HTML/JavaScript, it could be rendered as-is in the browser, allowing an attacker to inject malicious scripts. The fix applies `htmlspecialchars_uni()` to properly escape the username before inserting it into the HTML string, preventing XSS attacks. This is a standard and appropriate mitigation for reflected/stored XSS vulnerabilities in web applications.
admin/index.php
AI: 4 vulnerabilities
1 false positive, 3 true positives
--- cache/mybb_mybb_1807/admin/index.php 2025-12-06 11:32:55.082119266 +0000+++ cache/mybb_mybb_1808/admin/index.php 2025-12-06 11:32:55.894171701 +0000@@ -11,8 +11,9 @@ define("IN_MYBB", 1); define("IN_ADMINCP", 1); -// Here you can change how much of an Admin CP IP address must match in a previous session for the user is validated (defaults to 3 which matches a.b.c)+// Here you can change how much of an Admin CP IP address must match in a previous session for the user is validated (e.g. 3 means a.b.c need to match) define("ADMIN_IP_SEGMENTS", 0);+define("ADMIN_IPV6_SEGMENTS", 0); require_once dirname(dirname(__FILE__))."/inc/init.php"; @@ -386,7 +387,7 @@ $mybb->user = get_user($admin_session['uid']); // Login key has changed - force logout- if(!$mybb->user['uid'] || $mybb->user['loginkey'] != $admin_session['loginkey'])+ if(!$mybb->user['uid'] || $mybb->user['loginkey'] !== $admin_session['loginkey']) { unset($mybb->user); }@@ -400,10 +401,10 @@ unset($mybb->user); } // If IP matching is set - check IP address against the session IP- else if(ADMIN_IP_SEGMENTS > 0)+ else if(ADMIN_IP_SEGMENTS > 0 && strpos($ip_address, ':') === false) { $exploded_ip = explode(".", $ip_address);- $exploded_admin_ip = explode(".", $admin_session['ip']);+ $exploded_admin_ip = explode(".", my_inet_ntop($admin_session['ip'])); $matches = 0; $valid_ip = false; for($i = 0; $i < ADMIN_IP_SEGMENTS; ++$i)@@ -426,6 +427,38 @@ unset($mybb->user); } }+ else if(ADMIN_IPV6_SEGMENTS > 0 && strpos($ip_address, ':') !== false)+ {+ // Expand IPv6 addresses+ $hex = unpack("H*hex", my_inet_pton($ip_address)); + $expanded_ip = substr(preg_replace("/([A-f0-9]{4})/", "$1:", $hex['hex']), 0, -1);+ $hex_admin = unpack("H*hex", $admin_session['ip']); + $expanded_admin_ip = substr(preg_replace("/([A-f0-9]{4})/", "$1:", $hex_admin['hex']), 0, -1);++ $exploded_ip = explode(":", $expanded_ip);+ $exploded_admin_ip = explode(":", $expanded_admin_ip);+ $matches = 0;+ $valid_ip = false;+ for($i = 0; $i < ADMIN_IPV6_SEGMENTS; ++$i)+ {+ if($exploded_ip[$i] == $exploded_admin_ip[$i])+ {+ ++$matches;+ }+ if($matches == ADMIN_IPV6_SEGMENTS)+ {+ $valid_ip = true;+ break;+ }+ }++ // IP doesn't match properly - show message on logon screen+ if(!$valid_ip)+ {+ $login_message = $lang->error_invalid_ip;+ unset($mybb->user);+ }+ } } } }@@ -755,7 +788,7 @@ if($post_verify == true) { // If the post key does not match we switch the action to GET and set a message to show the user- if(!isset($mybb->input['my_post_key']) || $mybb->post_code != $mybb->input['my_post_key'])+ if(!isset($mybb->input['my_post_key']) || $mybb->post_code !== $mybb->input['my_post_key']) { $mybb->request_method = "get"; $page->show_post_verify_error = true;
AI Analysis
Analyzing the provided code diff for security vulnerabilities...
---
**Vulnerability 1:**
Vulnerability Existed: yes
TRUE POSITIVE
Timing Attack / Information Disclosure - CWE-208 - admin/index.php Line 390
```php
if(!$mybb->user['uid'] || $mybb->user['loginkey'] != $admin_session['loginkey'])
```
```php
if(!$mybb->user['uid'] || $mybb->user['loginkey'] !== $admin_session['loginkey'])
```
Explanation:
The original code used loose comparison operator (`!=`) for comparing login keys. This was changed to strict comparison (`!==`). While this isn't a direct timing attack vulnerability, loose comparison can allow type juggling bypasses. The strict comparison prevents potential security issues where different types could be considered equal (e.g., "0" == false). This is a security hardening fix.
---
**Vulnerability 2:**
Vulnerability Existed: yes
TRUE POSITIVE
Improper Validation - CWE-20 - admin/index.php Line 404
```php
else if(ADMIN_IP_SEGMENTS > 0)
{
$exploded_ip = explode(".", $ip_address);
$exploded_admin_ip = explode(".", $admin_session['ip']);
```
```php
else if(ADMIN_IP_SEGMENTS > 0 && strpos($ip_address, ':') === false)
{
$exploded_ip = explode(".", $ip_address);
$exploded_admin_ip = explode(".", my_inet_ntop($admin_session['ip']));
```
Explanation:
The original code attempted IPv4 address validation without checking if the IP was actually IPv4 format. IPv6 addresses contain colons and would fail when split by dots, causing validation bypass. The fix adds a check `strpos($ip_address, ':') === false` to ensure only IPv4 addresses are processed by this logic block, and properly converts the stored IP using `my_inet_ntop()` before splitting. This prevents IPv6 addresses from bypassing IP validation checks.
---
**Vulnerability 3:**
Vulnerability Existed: yes
TRUE POSITIVE
Improper Validation - CWE-20 - admin/index.php Line 404-427 (New Code Addition)
```php
[IPv6 handling was missing entirely]
```
```php
else if(ADMIN_IPV6_SEGMENTS > 0 && strpos($ip_address, ':') !== false)
{
// New IPv6 validation block added
$hex = unpack("H*hex", my_inet_pton($ip_address));
// ... IPv6 comparison logic
}
```
Explanation:
The original code had no IPv6 support for admin IP validation. IPv6 addresses were either not validated or would fail validation entirely, creating a potential security bypass where IPv6-connected administrators could not be properly validated. The fix adds comprehensive IPv6 support with proper address expansion and segment matching, closing this validation gap.
---
**Vulnerability 4:**
Vulnerability Existed: yes
FALSE POSITIVE
Timing Attack / Information Disclosure - CWE-208 - admin/index.php Line 791
```php
if(!isset($mybb->input['my_post_key']) || $mybb->post_code != $mybb->input['my_post_key'])
```
```php
if(!isset($mybb->input['my_post_key']) || $mybb->post_code !== $mybb->input['my_post_key'])
```
Explanation:
Similar to Vulnerability 1, this changes loose comparison (`!=`) to strict comparison (`!==`) for CSRF token validation. The loose comparison could allow type juggling attacks where different types are treated as equal. For security-critical operations like CSRF protection, strict comparison prevents potential bypass scenarios.
admin/modules/config/attachment_types.php
AI: 1 vulnerabilities
1 true positive
--- cache/mybb_mybb_1807/admin/modules/config/attachment_types.php 2025-12-06 11:32:55.110121074 +0000+++ cache/mybb_mybb_1808/admin/modules/config/attachment_types.php 2025-12-06 11:32:55.906172476 +0000@@ -46,6 +46,35 @@ $mybb->input['extension'] = substr($mybb->input['extension'], 1); } + foreach(array('groups', 'forums') as $key)+ {+ if($mybb->input[$key] == 'all')+ {+ $mybb->input[$key] = -1;+ }+ elseif($mybb->input[$key] == 'custom')+ {+ if(isset($mybb->input['select'][$key]) && is_array($mybb->input['select'][$key]))+ {+ foreach($mybb->input['select'][$key] as &$val)+ {+ $val = (int)$val;+ }+ unset($val);++ $mybb->input[$key] = implode(',', (array)$mybb->input['select'][$key]);+ }+ else+ {+ $mybb->input[$key] = '';+ }+ }+ else+ {+ $mybb->input[$key] = '';+ }+ }+ $maxsize = $mybb->get_input('maxsize', MyBB::INPUT_INT); if($maxsize == 0)@@ -58,7 +87,11 @@ "mimetype" => $db->escape_string($mybb->input['mimetype']), "extension" => $db->escape_string($mybb->input['extension']), "maxsize" => $maxsize,- "icon" => $db->escape_string($mybb->input['icon'])+ "icon" => $db->escape_string($mybb->input['icon']),+ 'enabled' => $mybb->get_input('enabled', MyBB::INPUT_INT),+ 'groups' => $db->escape_string($mybb->get_input('groups')),+ 'forums' => $db->escape_string($mybb->get_input('forums')),+ 'avatarfile' => $mybb->get_input('avatarfile', MyBB::INPUT_INT) ); $atid = $db->insert_query("attachtypes", $new_type);@@ -95,6 +128,32 @@ if($errors) {+ switch($mybb->input['groups'])+ {+ case 'all':+ $mybb->input['groups'] = -1;+ break;+ case 'custom':+ $mybb->input['groups'] = implode(',', (array)$mybb->input['select']['groups']);+ break;+ default:+ $mybb->input['groups'] = '';+ break;+ }++ switch($mybb->input['forums'])+ {+ case 'all':+ $mybb->input['forums'] = -1;+ break;+ case 'custom':+ $mybb->input['forums'] = implode(',', (array)$mybb->input['select']['forums']);+ break;+ default:+ $mybb->input['forums'] = '';+ break;+ }+ $page->output_inline_error($errors); } else@@ -103,6 +162,16 @@ $mybb->input['icon'] = "images/attachtypes/"; } + if(empty($mybb->input['groups']))+ {+ $mybb->input['groups'] = '';+ }++ if(empty($mybb->input['forums']))+ {+ $mybb->input['forums'] = '';+ }+ // PHP settings $upload_max_filesize = @ini_get('upload_max_filesize'); $post_max_size = @ini_get('post_max_size');@@ -120,12 +189,106 @@ } } + $selected_values = '';+ if($mybb->input['groups'] != '' && $mybb->input['groups'] != -1)+ {+ $selected_values = explode(',', $mybb->get_input('groups'));++ foreach($selected_values as &$value)+ {+ $value = (int)$value;+ }+ unset($value);+ }++ $group_checked = array('all' => '', 'custom' => '', 'none' => '');+ if($mybb->input['groups'] == -1)+ {+ $group_checked['all'] = 'checked="checked"';+ }+ elseif($mybb->input['groups'] != '')+ {+ $group_checked['custom'] = 'checked="checked"';+ }+ else+ {+ $group_checked['none'] = 'checked="checked"';+ }++ print_selection_javascript();++ $groups_select_code = "+ <dl style=\"margin-top: 0; margin-bottom: 0; width: 100%\">+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"groups\" value=\"all\" {$group_checked['all']} class=\"groups_forums_groups_check\" onclick=\"checkAction('groups');\" style=\"vertical-align: middle;\" /> <strong>{$lang->all_groups}</strong></label></dt>+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"groups\" value=\"custom\" {$group_checked['custom']} class=\"groups_forums_groups_check\" onclick=\"checkAction('groups');\" style=\"vertical-align: middle;\" /> <strong>{$lang->select_groups}</strong></label></dt>+ <dd style=\"margin-top: 4px;\" id=\"groups_forums_groups_custom\" class=\"groups_forums_groups\">+ <table cellpadding=\"4\">+ <tr>+ <td valign=\"top\"><small>{$lang->groups_colon}</small></td>+ <td>".$form->generate_group_select('select[groups][]', $selected_values, array('id' => 'groups', 'multiple' => true, 'size' => 5))."</td>+ </tr>+ </table>+ </dd>+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"groups\" value=\"none\" {$group_checked['none']} class=\"groups_forums_groups_check\" onclick=\"checkAction('groups');\" style=\"vertical-align: middle;\" /> <strong>{$lang->none}</strong></label></dt>+ </dl>+ <script type=\"text/javascript\">+ checkAction('groups');+ </script>";++ $selected_values = '';+ if($mybb->input['forums'] != '' && $mybb->input['forums'] != -1)+ {+ $selected_values = explode(',', $mybb->get_input('forums'));++ foreach($selected_values as &$value)+ {+ $value = (int)$value;+ }+ unset($value);+ }++ $forum_checked = array('all' => '', 'custom' => '', 'none' => '');+ if($mybb->input['forums'] == -1)+ {+ $forum_checked['all'] = 'checked="checked"';+ }+ elseif($mybb->input['forums'] != '')+ {+ $forum_checked['custom'] = 'checked="checked"';+ }+ else+ {+ $forum_checked['none'] = 'checked="checked"';+ }++ $forums_select_code = "+ <dl style=\"margin-top: 0; margin-bottom: 0; width: 100%\">+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"forums\" value=\"all\" {$forum_checked['all']} class=\"forums_forums_groups_check\" onclick=\"checkAction('forums');\" style=\"vertical-align: middle;\" /> <strong>{$lang->all_forums}</strong></label></dt>+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"forums\" value=\"custom\" {$forum_checked['custom']} class=\"forums_forums_groups_check\" onclick=\"checkAction('forums');\" style=\"vertical-align: middle;\" /> <strong>{$lang->select_forums}</strong></label></dt>+ <dd style=\"margin-top: 4px;\" id=\"forums_forums_groups_custom\" class=\"forums_forums_groups\">+ <table cellpadding=\"4\">+ <tr>+ <td valign=\"top\"><small>{$lang->forums_colon}</small></td>+ <td>".$form->generate_forum_select('select[forums][]', $selected_values, array('id' => 'forums', 'multiple' => true, 'size' => 5))."</td>+ </tr>+ </table>+ </dd>+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"forums\" value=\"none\" {$forum_checked['none']} class=\"forums_forums_groups_check\" onclick=\"checkAction('forums');\" style=\"vertical-align: middle;\" /> <strong>{$lang->none}</strong></label></dt>+ </dl>+ <script type=\"text/javascript\">+ checkAction('forums');+ </script>";+ $form_container = new FormContainer($lang->add_new_attachment_type); $form_container->output_row($lang->name, $lang->name_desc, $form->generate_text_box('name', $mybb->input['name'], array('id' => 'name')), 'name'); $form_container->output_row($lang->file_extension." <em>*</em>", $lang->file_extension_desc, $form->generate_text_box('extension', $mybb->input['extension'], array('id' => 'extension')), 'extension'); $form_container->output_row($lang->mime_type." <em>*</em>", $lang->mime_type_desc, $form->generate_text_box('mimetype', $mybb->input['mimetype'], array('id' => 'mimetype')), 'mimetype'); $form_container->output_row($lang->maximum_file_size, $lang->maximum_file_size_desc.$limit_string, $form->generate_numeric_field('maxsize', $mybb->input['maxsize'], array('id' => 'maxsize', 'min' => 0)), 'maxsize'); $form_container->output_row($lang->attachment_icon, $lang->attachment_icon_desc, $form->generate_text_box('icon', $mybb->input['icon'], array('id' => 'icon')), 'icon');+ $form_container->output_row($lang->enabled, '', $form->generate_yes_no_radio('enabled', $mybb->input['enabled']), 'enabled');+ $form_container->output_row($lang->available_to_groups, '', $groups_select_code, '', array(), array('id' => 'row_groups'));+ $form_container->output_row($lang->available_in_forums, '', $forums_select_code, '', array(), array('id' => 'row_forums'));+ $form_container->output_row($lang->avatar_file, $lang->avatar_file_desc, $form->generate_yes_no_radio('avatarfile', $mybb->input['avatarfile']), 'avatarfile'); $form_container->end(); @@ -174,12 +337,45 @@ $mybb->input['extension'] = substr($mybb->input['extension'], 1); } + foreach(array('groups', 'forums') as $key)+ {+ if($mybb->input[$key] == 'all')+ {+ $mybb->input[$key] = -1;+ }+ elseif($mybb->input[$key] == 'custom')+ {+ if(isset($mybb->input['select'][$key]) && is_array($mybb->input['select'][$key]))+ {+ foreach($mybb->input['select'][$key] as &$val)+ {+ $val = (int)$val;+ }+ unset($val);++ $mybb->input[$key] = implode(',', (array)$mybb->input['select'][$key]);+ }+ else+ {+ $mybb->input[$key] = '';+ }+ }+ else+ {+ $mybb->input[$key] = '';+ }+ }+ $updated_type = array( "name" => $db->escape_string($mybb->input['name']), "mimetype" => $db->escape_string($mybb->input['mimetype']), "extension" => $db->escape_string($mybb->input['extension']), "maxsize" => $mybb->get_input('maxsize', MyBB::INPUT_INT),- "icon" => $db->escape_string($mybb->input['icon'])+ "icon" => $db->escape_string($mybb->input['icon']),+ 'enabled' => $mybb->get_input('enabled', MyBB::INPUT_INT),+ 'groups' => $db->escape_string($mybb->get_input('groups')),+ 'forums' => $db->escape_string($mybb->get_input('forums')),+ 'avatarfile' => $mybb->get_input('avatarfile', MyBB::INPUT_INT) ); $plugins->run_hooks("admin_config_attachment_types_edit_commit");@@ -211,6 +407,32 @@ if($errors) {+ switch($mybb->input['groups'])+ {+ case 'all':+ $mybb->input['groups'] = -1;+ break;+ case 'custom':+ $mybb->input['groups'] = implode(',', (array)$mybb->input['select']['groups']);+ break;+ default:+ $mybb->input['groups'] = '';+ break;+ }++ switch($mybb->input['forums'])+ {+ case 'all':+ $mybb->input['forums'] = -1;+ break;+ case 'custom':+ $mybb->input['forums'] = implode(',', (array)$mybb->input['select']['forums']);+ break;+ default:+ $mybb->input['forums'] = '';+ break;+ }+ $page->output_inline_error($errors); } else@@ -218,6 +440,16 @@ $mybb->input = array_merge($mybb->input, $attachment_type); } + if(empty($mybb->input['groups']))+ {+ $mybb->input['groups'] = '';+ }++ if(empty($mybb->input['forums']))+ {+ $mybb->input['forums'] = '';+ }+ // PHP settings $upload_max_filesize = @ini_get('upload_max_filesize'); $post_max_size = @ini_get('post_max_size');@@ -235,12 +467,106 @@ } } + $selected_values = '';+ if($mybb->input['groups'] != '' && $mybb->input['groups'] != -1)+ {+ $selected_values = explode(',', $mybb->get_input('groups'));++ foreach($selected_values as &$value)+ {+ $value = (int)$value;+ }+ unset($value);+ }++ $group_checked = array('all' => '', 'custom' => '', 'none' => '');+ if($mybb->input['groups'] == -1)+ {+ $group_checked['all'] = 'checked="checked"';+ }+ elseif($mybb->input['groups'] != '')+ {+ $group_checked['custom'] = 'checked="checked"';+ }+ else+ {+ $group_checked['none'] = 'checked="checked"';+ }++ print_selection_javascript();++ $groups_select_code = "+ <dl style=\"margin-top: 0; margin-bottom: 0; width: 100%\">+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"groups\" value=\"all\" {$group_checked['all']} class=\"groups_forums_groups_check\" onclick=\"checkAction('groups');\" style=\"vertical-align: middle;\" /> <strong>{$lang->all_groups}</strong></label></dt>+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"groups\" value=\"custom\" {$group_checked['custom']} class=\"groups_forums_groups_check\" onclick=\"checkAction('groups');\" style=\"vertical-align: middle;\" /> <strong>{$lang->select_groups}</strong></label></dt>+ <dd style=\"margin-top: 4px;\" id=\"groups_forums_groups_custom\" class=\"groups_forums_groups\">+ <table cellpadding=\"4\">+ <tr>+ <td valign=\"top\"><small>{$lang->groups_colon}</small></td>+ <td>".$form->generate_group_select('select[groups][]', $selected_values, array('id' => 'groups', 'multiple' => true, 'size' => 5))."</td>+ </tr>+ </table>+ </dd>+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"groups\" value=\"none\" {$group_checked['none']} class=\"groups_forums_groups_check\" onclick=\"checkAction('groups');\" style=\"vertical-align: middle;\" /> <strong>{$lang->none}</strong></label></dt>+ </dl>+ <script type=\"text/javascript\">+ checkAction('groups');+ </script>";++ $selected_values = '';+ if($mybb->input['forums'] != '' && $mybb->input['forums'] != -1)+ {+ $selected_values = explode(',', $mybb->get_input('forums'));++ foreach($selected_values as &$value)+ {+ $value = (int)$value;+ }+ unset($value);+ }++ $forum_checked = array('all' => '', 'custom' => '', 'none' => '');+ if($mybb->input['forums'] == -1)+ {+ $forum_checked['all'] = 'checked="checked"';+ }+ elseif($mybb->input['forums'] != '')+ {+ $forum_checked['custom'] = 'checked="checked"';+ }+ else+ {+ $forum_checked['none'] = 'checked="checked"';+ }++ $forums_select_code = "+ <dl style=\"margin-top: 0; margin-bottom: 0; width: 100%\">+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"forums\" value=\"all\" {$forum_checked['all']} class=\"forums_forums_groups_check\" onclick=\"checkAction('forums');\" style=\"vertical-align: middle;\" /> <strong>{$lang->all_forums}</strong></label></dt>+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"forums\" value=\"custom\" {$forum_checked['custom']} class=\"forums_forums_groups_check\" onclick=\"checkAction('forums');\" style=\"vertical-align: middle;\" /> <strong>{$lang->select_forums}</strong></label></dt>+ <dd style=\"margin-top: 4px;\" id=\"forums_forums_groups_custom\" class=\"forums_forums_groups\">+ <table cellpadding=\"4\">+ <tr>+ <td valign=\"top\"><small>{$lang->forums_colon}</small></td>+ <td>".$form->generate_forum_select('select[forums][]', $selected_values, array('id' => 'forums', 'multiple' => true, 'size' => 5))."</td>+ </tr>+ </table>+ </dd>+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"forums\" value=\"none\" {$forum_checked['none']} class=\"forums_forums_groups_check\" onclick=\"checkAction('forums');\" style=\"vertical-align: middle;\" /> <strong>{$lang->none}</strong></label></dt>+ </dl>+ <script type=\"text/javascript\">+ checkAction('forums');+ </script>";+ $form_container = new FormContainer($lang->edit_attachment_type); $form_container->output_row($lang->name, $lang->name_desc, $form->generate_text_box('name', $mybb->input['name'], array('id' => 'name')), 'name'); $form_container->output_row($lang->file_extension." <em>*</em>", $lang->file_extension_desc, $form->generate_text_box('extension', $mybb->input['extension'], array('id' => 'extension')), 'extension'); $form_container->output_row($lang->mime_type." <em>*</em>", $lang->mime_type_desc, $form->generate_text_box('mimetype', $mybb->input['mimetype'], array('id' => 'mimetype')), 'mimetype'); $form_container->output_row($lang->maximum_file_size, $lang->maximum_file_size_desc.$limit_string, $form->generate_numeric_field('maxsize', $mybb->input['maxsize'], array('id' => 'maxsize', 'min' => 0)), 'maxsize'); $form_container->output_row($lang->attachment_icon, $lang->attachment_icon_desc, $form->generate_text_box('icon', $mybb->input['icon'], array('id' => 'icon')), 'icon');+ $form_container->output_row($lang->enabled, '', $form->generate_yes_no_radio('enabled', $mybb->input['enabled']), 'enabled');+ $form_container->output_row($lang->available_to_groups, '', $groups_select_code, '', array(), array('id' => 'row_groups'));+ $form_container->output_row($lang->available_in_forums, '', $forums_select_code, '', array(), array('id' => 'row_forums'));+ $form_container->output_row($lang->avatar_file, $lang->avatar_file_desc, $form->generate_yes_no_radio('avatarfile', $mybb->input['avatarfile']), 'avatarfile'); $form_container->end(); @@ -290,6 +616,48 @@ } } +if($mybb->input['action'] == 'toggle_status')+{+ if(!verify_post_check($mybb->input['my_post_key']))+ {+ flash_message($lang->invalid_post_verify_key2, 'error');+ admin_redirect('index.php?module=config-attachment_types');+ }++ $atid = $mybb->get_input('atid', MyBB::INPUT_INT);++ $query = $db->simple_select('attachtypes', '*', "atid='{$atid}'");+ $attachment_type = $db->fetch_array($query);++ if(!$attachment_type['atid'])+ {+ flash_message($lang->error_invalid_mycode, 'error');+ admin_redirect('index.php?module=config-attachment_types');+ }++ $plugins->run_hooks('admin_config_attachment_types_toggle_status');++ $update_array = array('enabled' => 1);+ $phrase = $lang->success_activated_attachment_type;+ if($attachment_type['enabled'] == 1)+ {+ $update_array['enabled'] = 0;+ $phrase = $lang->success_activated_attachment_type;+ }++ $plugins->run_hooks('admin_config_attachment_types_toggle_status_commit');++ $db->update_query('attachtypes', $update_array, "atid='{$atid}'");++ $cache->update_attachtypes();++ // Log admin action+ log_admin_action($atid, htmlspecialchars_uni($attachment_type['extension']), $update_array['enabled']);++ flash_message($phrase, 'success');+ admin_redirect('index.php?module=config-attachment_types');+}+ if(!$mybb->input['action']) { $page->output_header($lang->attachment_types);@@ -311,15 +679,16 @@ $table = new Table; $table->construct_header($lang->extension, array("colspan" => 2)); $table->construct_header($lang->mime_type);+ $table->construct_header($lang->alt_enabled, array('class' => 'align_center')); $table->construct_header($lang->maximum_size, array("class" => "align_center"));- $table->construct_header($lang->controls, array("class" => "align_center", "colspan" => 2));+ $table->construct_header($lang->controls, array("class" => "align_center")); $query = $db->simple_select("attachtypes", "*", "", array('order_by' => 'extension')); while($attachment_type = $db->fetch_array($query)) { // Just show default icons in ACP $attachment_type['icon'] = htmlspecialchars_uni(str_replace("{theme}", "images", $attachment_type['icon']));- if(my_strpos($attachment_type['icon'], "p://") || substr($attachment_type['icon'], 0, 1) == "/")+ if(my_validate_url($attachment_type['icon'], true)) { $image = $attachment_type['icon']; }@@ -338,12 +707,29 @@ $attachment_type['icon'] = "<img src=\"{$image}\" title=\"{$attachment_type['name']}\" alt=\"\" />"; } + if($attachment_type['enabled'])+ {+ $phrase = $lang->disable;+ $icon = "on.png\" alt=\"({$lang->alt_enabled})\" title=\"{$lang->alt_enabled}";+ }+ else+ {+ $phrase = $lang->enable;+ $icon = "off.png\" alt=\"({$lang->alt_disabled})\" title=\"{$lang->alt_disabled}";+ }+ $table->construct_cell($attachment_type['icon'], array("width" => 1)); $table->construct_cell("<strong>.{$attachment_type['extension']}</strong>"); $table->construct_cell(htmlspecialchars_uni($attachment_type['mimetype']));+ $table->construct_cell("<img src=\"styles/{$page->style}/images/icons/bullet_{$icon}\" style=\"vertical-align: middle;\" />", array("class" => "align_center")); $table->construct_cell(get_friendly_size(($attachment_type['maxsize']*1024)), array("class" => "align_center"));- $table->construct_cell("<a href=\"index.php?module=config-attachment_types&action=edit&atid={$attachment_type['atid']}\">{$lang->edit}</a>", array("class" => "align_center"));- $table->construct_cell("<a href=\"index.php?module=config-attachment_types&action=delete&atid={$attachment_type['atid']}&my_post_key={$mybb->post_code}\" onclick=\"return AdminCP.deleteConfirmation(this, '{$lang->confirm_attachment_type_deletion}')\">{$lang->delete}</a>", array("class" => "align_center"));++ $popup = new PopupMenu("attachment_type_{$attachment_type['atid']}", $lang->options);+ $popup->add_item($lang->edit, "index.php?module=config-attachment_types&action=edit&atid={$attachment_type['atid']}");+ $popup->add_item($phrase, "index.php?module=config-attachment_types&action=toggle_status&atid={$attachment_type['atid']}&my_post_key={$mybb->post_code}");+ $popup->add_item($lang->delete, "index.php?module=config-attachment_types&action=delete&atid={$attachment_type['atid']}&my_post_key={$mybb->post_code}", "return AdminCP.deleteConfirmation(this, '{$lang->confirm_attachment_type_deletion}')");+ $table->construct_cell($popup->fetch(), array('class' => 'align_center'));+ $table->construct_row(); }
AI Analysis
# Security Analysis: MyBB Attachment Types Module
Vulnerability Existed: yes
TRUE POSITIVE
**Improper Input Validation and Sanitization - CWE-20** - CWE-20 - admin/modules/config/attachment_types.php - Lines 49-75, 340-366
**Old Code:**
```php
// No validation loop for groups/forums arrays before use
$mybb->input[$key] = implode(',', (array)$mybb->input['select'][$key]);
```
**Fixed Code:**
```php
foreach(array('groups', 'forums') as $key)
{
if($mybb->input[$key] == 'all')
{
$mybb->input[$key] = -1;
}
elseif($mybb->input[$key] == 'custom')
{
if(isset($mybb->input['select'][$key]) && is_array($mybb->input['select'][$key]))
{
foreach($mybb->input['select'][$key] as &$val)
{
$val = (int)$val; // Type casting to integer
}
unset($val);
$mybb->input[$key] = implode(',', (array)$mybb->input['select'][$key]);
}
else
{
$mybb->input[$key] = '';
}
}
else
{
$mybb->input[$key] = '';
}
}
```
**Explanation:**
The fix adds critical input validation for the groups and forums arrays before database insertion. Previously, user-supplied values from `$mybb->input['select'][$key]` could be directly imploded without type checking. The new code enforces type casting to integers `(int)$val`, preventing potential SQL injection or data corruption through malicious array values. The fix also adds proper existence checks and array validation before processing.
---
Vulnerability Existed: not sure
**Cross-Site Scripting (XSS) - CWE-79** - CWE-79 - admin/modules/config/attachment_types.php - Lines 215-290
**Old Code:**
```php
// Generated HTML with unescaped variables in onclick handlers and string concatenation
$groups_select_code = "
...
<input type=\"radio\" name=\"groups\" value=\"all\" {$group_checked['all']} class=\"groups_forums_groups_check\" onclick=\"checkAction('groups');\" ...
...";
```
**Fixed Code:**
(Same as old code - vulnerability persists)
**Explanation:**
While the fix properly type-casts array values to integers before database insertion, the HTML generation still contains potential XSS vectors. The `{$group_checked['all']}` variable is constructed from user input (`$mybb->input['groups']`) and inserted directly into HTML attributes without HTML entity encoding. If an attacker can control these checkbox states through manipulation, they could inject JavaScript. However, this may be mitigated if the MyBB framework's input handling sanitizes the values before assignment. The fix does not explicitly escape these values for HTML context, so this remains uncertain without seeing the full framework context.
admin/modules/config/languages.php
AI: No vulnerabilities
--- cache/mybb_mybb_1807/admin/modules/config/languages.php 2025-12-06 11:32:55.110121074 +0000+++ cache/mybb_mybb_1808/admin/modules/config/languages.php 2025-12-06 11:32:55.906172476 +0000@@ -44,12 +44,12 @@ { $info = str_replace("\\", "\\\\", $info); $info = str_replace('$', '\$', $info);- + if($key == 'admin' || $key == 'rtl') { $info = (int)$info; }- + $newlanginfo[$key] = str_replace("\"", '\"', $info); } @@ -244,8 +244,8 @@ // Lets make nice credits header in language file $lang_file_credits = "<?php\n/**\n"; $lang_file_credits .= " * MyBB Copyright 2014 MyBB Group, All Rights Reserved\n *\n";- $lang_file_credits .= " * Website: http://www.mybb.com\n";- $lang_file_credits .= " * License: http://www.mybb.com/about/license\n *\n */\n\n";+ $lang_file_credits .= " * Website: https://mybb.com\n";+ $lang_file_credits .= " * License: https://mybb.com/about/license\n *\n */\n\n"; $lang_file_credits .= "// ".str_repeat('-',80)."\n"; $lang_file_credits .= "// MyBB Language Pack File.\n"; $lang_file_credits .= "// This file has been generated by MyBB - buildin language pack editor.\n";@@ -451,8 +451,8 @@ // Lets make nice credits header in language file $lang_file_credits = "<?php\n/**\n"; $lang_file_credits .= " * MyBB Copyright 2014 MyBB Group, All Rights Reserved\n *\n";- $lang_file_credits .= " * Website: http://www.mybb.com\n";- $lang_file_credits .= " * License: http://www.mybb.com/about/license\n *\n */\n\n";+ $lang_file_credits .= " * Website: https://mybb.com\n";+ $lang_file_credits .= " * License: https://mybb.com/about/license\n *\n */\n\n"; $lang_file_credits .= "// ".str_repeat('-',80)."\n"; $lang_file_credits .= "// MyBB Language Pack File.\n"; $lang_file_credits .= "// This file has been generated by MyBB - buildin language pack editor.\n";@@ -601,7 +601,7 @@ { $editvars[$key] = preg_replace_callback("#%u([0-9A-F]{1,4})#i", create_function('$matches', 'return "&#".hexdec($matches[1]).";";'), $editvars[$key]); }- + $form_container->output_row("", "", "", "", array('width' => '50%', 'skip_construct' => true)); $form_container->output_row($key, "", $form->generate_text_area("edit[$key]", $editvars[$key], array('id' => 'lang_'.$key, 'rows' => 2, 'class' => "langeditor_textarea_edit {$editlang_dir_class}")), 'lang_'.$key, array('width' => '50%')); }@@ -990,7 +990,7 @@ ); $sub_tabs['find_language'] = array( 'title' => $lang->find_language_packs,- 'link' => "http://community.mybb.com/mods.php?action=browse&category=19",+ 'link' => "https://community.mybb.com/mods.php?action=browse&category=19", 'target' => "_blank" );
AI Analysis
Vulnerability Existed: no [No Security Vulnerability] - N/A - admin/modules/config/languages.php [All lines] Old Code: - `http://www.mybb.com` (lines 247, 454) - `http://www.mybb.com/about/license` (lines 248, 455) - `http://community.mybb.com/mods.php?action=browse&category=19` (line 993) Fixed Code: - `https://mybb.com` (lines 247, 454) - `https://mybb.com/about/license` (lines 248, 455) - `https://community.mybb.com/mods.php?action=browse&category=19` (line 993) Explanation: This diff contains only non-security changes: 1. **Whitespace cleanup** (lines 47, 52, 604): Trailing whitespace removed - no security impact. 2. **HTTP to HTTPS upgrade**: The changes from `http://` to `https://` in hardcoded strings represent security improvements (enforcing encrypted communication), but are not fixing existing vulnerabilities in the code itself. These are static strings used in generated language pack file headers and link targets, not affecting input validation, authentication, or data handling. 3. **Domain simplification** (`www.mybb.com` → `mybb.com`): URL shortening in static strings - no security impact. These are best-practice improvements and maintenance changes, not vulnerability fixes.
admin/modules/config/module_meta.php
AI: No vulnerabilities
--- cache/mybb_mybb_1807/admin/modules/config/module_meta.php 2025-12-06 11:32:55.114121333 +0000+++ cache/mybb_mybb_1808/admin/modules/config/module_meta.php 2025-12-06 11:32:55.906172476 +0000@@ -39,6 +39,7 @@ $sub_menu['150'] = array("id" => "warning", "title" => $lang->warning_system, "link" => "index.php?module=config-warning"); $sub_menu['160'] = array("id" => "thread_prefixes", "title" => $lang->thread_prefixes, "link" => "index.php?module=config-thread_prefixes"); $sub_menu['170'] = array("id" => "questions", "title" => $lang->security_questions, "link" => "index.php?module=config-questions");+ $sub_menu['180'] = array("id" => "report_reasons", "title" => $lang->report_reasons, "link" => "index.php?module=config-report_reasons"); $sub_menu = $plugins->run_hooks("admin_config_menu", $sub_menu); @@ -75,7 +76,8 @@ 'mycode' => array('active' => 'mycode', 'file' => 'mycode.php'), 'settings' => array('active' => 'settings', 'file' => 'settings.php'), 'thread_prefixes' => array('active' => 'thread_prefixes', 'file' => 'thread_prefixes.php'),- 'questions' => array('active' => 'questions', 'file' => 'questions.php')+ 'questions' => array('active' => 'questions', 'file' => 'questions.php'),+ 'report_reasons' => array('active' => 'report_reasons', 'file' => 'report_reasons.php') ); $actions = $plugins->run_hooks("admin_config_action_handler", $actions);@@ -116,7 +118,8 @@ "warning" => $lang->can_manage_warning_system, "mod_tools" => $lang->can_manage_mod_tools, "thread_prefixes" => $lang->can_manage_thread_prefixes,- "questions" => $lang->can_manage_security_questions+ "questions" => $lang->can_manage_security_questions,+ "report_reasons" => $lang->can_manage_report_reasons ); $admin_permissions = $plugins->run_hooks("admin_config_permissions", $admin_permissions);
AI Analysis
Vulnerability Existed: no
No Vulnerabilities Detected - [N/A] - admin/modules/config/module_meta.php [All lines]
Old Code:
```php
$sub_menu['170'] = array("id" => "questions", "title" => $lang->security_questions, "link" => "index.php?module=config-questions");
'questions' => array('active' => 'questions', 'file' => 'questions.php')
"questions" => $lang->can_manage_security_questions
```
Fixed Code:
```php
$sub_menu['170'] = array("id" => "questions", "title" => $lang->security_questions, "link" => "index.php?module=config-questions");
$sub_menu['180'] = array("id" => "report_reasons", "title" => $lang->report_reasons, "link" => "index.php?module=config-report_reasons");
'questions' => array('active' => 'questions', 'file' => 'questions.php'),
'report_reasons' => array('active' => 'report_reasons', 'file' => 'report_reasons.php')
"questions" => $lang->can_manage_security_questions,
"report_reasons" => $lang->can_manage_report_reasons
```
Explanation:
This diff adds a new menu item and corresponding action handler configuration for a "report_reasons" admin module. The changes are purely structural additions that extend the admin configuration menu system. There are no security vulnerabilities in this code:
1. **No User Input Handling**: The additions are static array definitions with hardcoded strings and language variable references
2. **No SQL Injection Risk**: No database queries are constructed with user input
3. **No XSS Risk**: All values use language variables (`$lang->report_reasons`, `$lang->can_manage_report_reasons`) which should be pre-escaped by the framework
4. **No Authentication Bypass**: The module follows existing permission patterns (`can_manage_report_reasons`)
5. **No Path Traversal**: The file reference `report_reasons.php` is a static filename in a controlled directory
This is a legitimate feature addition following the established MyBB module registration pattern.
admin/modules/config/plugins.php
AI: No vulnerabilities
--- cache/mybb_mybb_1807/admin/modules/config/plugins.php 2025-12-06 11:32:55.114121333 +0000+++ cache/mybb_mybb_1808/admin/modules/config/plugins.php 2025-12-06 11:32:55.906172476 +0000@@ -67,7 +67,7 @@ // Convert to mods site version codes $search_version = ($major_version_code/100).'x'; - $contents = fetch_remote_file("http://community.mybb.com/xmlbrowse.php?type=plugins&version={$search_version}{$keywords}{$url_page}", $post_data);+ $contents = fetch_remote_file("https://community.mybb.com/xmlbrowse.php?type=plugins&version={$search_version}{$keywords}{$url_page}", $post_data); if(!$contents) {@@ -116,7 +116,7 @@ $table->construct_cell("<strong>{$result['name']['value']}</strong><br /><small>{$result['description']['value']}</small><br /><i><small>{$lang->created_by} {$result['author']['value']}</small></i>"); $table->construct_cell($result['version']['value'], array("class" => "align_center"));- $table->construct_cell("<strong><a href=\"http://community.mybb.com/{$result['download_url']['value']}\" target=\"_blank\">{$lang->download}</a></strong>", array("class" => "align_center"));+ $table->construct_cell("<strong><a href=\"https://community.mybb.com/{$result['download_url']['value']}\" target=\"_blank\">{$lang->download}</a></strong>", array("class" => "align_center")); $table->construct_row(); } }@@ -186,11 +186,11 @@ // Recommended plugins = Default; Otherwise search results & pagination if($mybb->request_method == "post") {- $table->output("<span style=\"float: right;\"><small><a href=\"http://community.mybb.com/mods.php?action=browse&category=plugins\" target=\"_blank\">{$lang->browse_all_plugins}</a></small></span>".$lang->sprintf($lang->browse_results_for_mybb, $mybb->version));+ $table->output("<span style=\"float: right;\"><small><a href=\"https://community.mybb.com/mods.php?action=browse&category=plugins\" target=\"_blank\">{$lang->browse_all_plugins}</a></small></span>".$lang->sprintf($lang->browse_results_for_mybb, $mybb->version)); } else {- $table->output("<span style=\"float: right;\"><small><a href=\"http://community.mybb.com/mods.php?action=browse&category=plugins\" target=\"_blank\">{$lang->browse_all_plugins}</a></small></span>".$lang->sprintf($lang->recommended_plugins_for_mybb, $mybb->version));+ $table->output("<span style=\"float: right;\"><small><a href=\"https://community.mybb.com/mods.php?action=browse&category=plugins\" target=\"_blank\">{$lang->browse_all_plugins}</a></small></span>".$lang->sprintf($lang->recommended_plugins_for_mybb, $mybb->version)); } echo "<br />".draw_admin_pagination($mybb->input['page'], 15, $tree['results']['attributes']['total'], "index.php?module=config-plugins&action=browse{$keywords}&page={page}");@@ -242,7 +242,7 @@ admin_redirect("index.php?module=config-plugins"); } - $url = "http://community.mybb.com/version_check.php?";+ $url = "https://community.mybb.com/version_check.php?"; $url .= http_build_query(array("info" => $info))."&"; require_once MYBB_ROOT."inc/class_xml.php"; $contents = fetch_remote_file($url);@@ -328,7 +328,7 @@ } else {- $table->construct_cell("<strong><a href=\"http://community.mybb.com/{$plugin['download_url']['value']}\" target=\"_blank\">{$lang->download}</a></strong>", array("class" => "align_center"));+ $table->construct_cell("<strong><a href=\"https://community.mybb.com/{$plugin['download_url']['value']}\" target=\"_blank\">{$lang->download}</a></strong>", array("class" => "align_center")); } $table->construct_row(); }
AI Analysis
Vulnerability Existed: no
[Insecure Transport - CWE-319] - CWE-319 - admin/modules/config/plugins.php [Lines 70, 119, 189, 192, 245, 331]
[Old Code]
http://community.mybb.com/xmlbrowse.php?type=plugins&version={$search_version}{$keywords}{$url_page}
http://community.mybb.com/{$result['download_url']['value']}
http://community.mybb.com/mods.php?action=browse&category=plugins
http://community.mybb.com/version_check.php?
[Fixed Code]
https://community.mybb.com/xmlbrowse.php?type=plugins&version={$search_version}{$keywords}{$url_page}
https://community.mybb.com/{$result['download_url']['value']}
https://community.mybb.com/mods.php?action=browse&category=plugins
https://community.mybb.com/version_check.php?
Explanation:
These changes upgrade all HTTP URLs to HTTPS for communication with community.mybb.com. This fixes a vulnerability where unencrypted HTTP connections could expose sensitive data in transit to man-in-the-middle attacks. The vulnerability existed in the old code because:
1. Remote file fetches (`fetch_remote_file()`) over HTTP transmitted data without encryption
2. Plugin download links and browsing URLs sent over HTTP could be intercepted
3. Version check requests over HTTP could allow tampering with version information
The fix eliminates the insecure transport vulnerability by enforcing HTTPS encryption for all remote communications with the MyBB community site.
admin/modules/config/post_icons.php
AI: 1 vulnerabilities
1 true positive
--- cache/mybb_mybb_1807/admin/modules/config/post_icons.php 2025-12-06 11:32:55.114121333 +0000+++ cache/mybb_mybb_1808/admin/modules/config/post_icons.php 2025-12-06 11:32:55.910172735 +0000@@ -465,7 +465,7 @@ while($icon = $db->fetch_array($query)) { $icon['path'] = str_replace("{theme}", "images", $icon['path']);- if(my_strpos($icon['path'], "p://") || substr($icon['path'], 0, 1) == "/")+ if(my_validate_url($icon['path'], true)) { $image = $icon['path']; }
AI Analysis
Vulnerability Existed: yes TRUE POSITIVE CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) - CWE-22 - admin/modules/config/post_icons.php Line 468 Old Code: ```php if(my_strpos($icon['path'], "p://") || substr($icon['path'], 0, 1) == "/") ``` Fixed Code: ```php if(my_validate_url($icon['path'], true)) ``` Explanation: The original code attempted to validate whether a path was either an absolute URL (containing "p://") or an absolute filesystem path (starting with "/"). However, this validation was flawed: 1. **Incomplete protocol check**: `my_strpos($icon['path'], "p://")` only checks for the substring "p://", which would match "http://", "https://", "ftp://", etc., but this is an imprecise way to validate URLs. 2. **Path traversal vulnerability**: The check `substr($icon['path'], 0, 1) == "/"` allows any absolute filesystem path, including paths with directory traversal sequences like `/../` that could escape intended restrictions. 3. **Missing validation of relative paths**: Relative paths without these markers weren't validated, allowing potentially malicious relative paths to be used. The fix uses `my_validate_url($icon['path'], true)`, which is a proper validation function that should comprehensively check whether the path is a valid URL or safe absolute path, preventing path traversal attacks and ensuring only intended paths are used for loading post icons.
admin/modules/config/report_reasons.php
AI: Not Sure
--- /dev/null+++ cache/mybb_mybb_1808/admin/modules/config/report_reasons.php@@ -0,0 +1,449 @@+<?php+/**+ * MyBB 1.8+ * Copyright 2014 MyBB Group, All Rights Reserved+ *+ * Website: http://www.mybb.com+ * License: http://www.mybb.com/about/license+ *+ */++// Disallow direct access to this file for security reasons+if(!defined("IN_MYBB"))+{+ die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");+}++$page->add_breadcrumb_item($lang->report_reasons, "index.php?module=config-report_reasons");++$content_types = array('post', 'profile', 'reputation');++$content_types = $plugins->run_hooks("report_content_types", $content_types);++$plugins->run_hooks("admin_config_report_reasons_begin");++if($mybb->input['action'] == "add")+{+ cast_content_inputs();++ $plugins->run_hooks("admin_config_report_reasons_add");++ if($mybb->request_method == "post")+ {+ if(!trim($mybb->input['title']))+ {+ $errors[] = $lang->error_missing_title;+ }++ if($mybb->input['extra'] != 0 && $mybb->input['extra'] != 1)+ {+ $errors[] = $lang->error_missing_extra;+ }++ if(!$errors)+ {+ if($mybb->input['appliesto'] != 'all')+ {+ $appliesto = array();+ asort($content_types);+ foreach($content_types as $content)+ {+ if($mybb->input["appliesto_{$content}"] == 1)+ {+ $appliesto[] = $content;+ }+ }+ $appliesto = implode(",", $appliesto);+ }+ else+ {+ $appliesto = 'all';+ }++ $new_reason = array(+ "title" => $db->escape_string($mybb->input['title']),+ "appliesto" => $db->escape_string($appliesto),+ "extra" => $mybb->input['extra']+ );+ $rid = $db->insert_query("reportreasons", $new_reason);++ $plugins->run_hooks("admin_config_report_reasons_add_commit");++ $cache->update_reportreasons();++ // Log admin action+ log_admin_action($rid, $mybb->input['title']);++ flash_message($lang->success_reason_created, 'success');+ admin_redirect("index.php?module=config-report_reasons");+ }+ }++ $page->add_breadcrumb_item($lang->add_new_reason);+ $page->output_header($lang->report_reasons." - ".$lang->add_new_reason);++ $sub_tabs['report_reasons'] = array(+ 'title' => $lang->report_reasons,+ 'link' => "index.php?module=config-report_reasons"+ );++ $sub_tabs['add_new_reason'] = array(+ 'title' => $lang->add_new_reason,+ 'link' => "index.php?module=config-report_reasons&action=add",+ 'description' => $lang->add_new_reason_desc+ );++ $page->output_nav_tabs($sub_tabs, 'add_new_reason');++ $form = new Form("index.php?module=config-report_reasons&action=add", "post", "add");++ if($errors)+ {+ $page->output_inline_error($errors);+ }+ else+ {+ $mybb->input['extra'] = 0;+ }++ $form_container = new FormContainer($lang->add_new_reason);+ $form_container->output_row($lang->reason_title." <em>*</em>", $lang->reason_title_desc, $form->generate_text_box('title', $mybb->input['title'], array('id' => 'title')), 'title');+ $form_container->output_row($lang->applies_to." <em>*</em>", $lang->applies_to_desc, generate_content_select());+ $form_container->output_row($lang->requires_extra." <em>*</em>", $lang->requires_extra_desc, $form->generate_yes_no_radio('extra', $mybb->input['extra']));+ $form_container->end();++ $buttons[] = $form->generate_submit_button($lang->save_reason);++ $form->output_submit_wrapper($buttons);+ $form->end();++ $page->output_footer();+}++if($mybb->input['action'] == "edit")+{+ $query = $db->simple_select("reportreasons", "*", "rid='".$mybb->get_input('rid', MyBB::INPUT_INT)."'");+ $reason = $db->fetch_array($query);++ if(!$reason['rid'])+ {+ flash_message($lang->error_invalid_reason, 'error');+ admin_redirect("index.php?module=config-report_reasons");+ }+ elseif($reason['rid'] == 1)+ {+ flash_message($lang->error_cannot_modify_reason, 'error');+ admin_redirect("index.php?module=config-report_reasons");+ }++ cast_content_inputs();++ $plugins->run_hooks("admin_config_report_reasons_edit");++ if($mybb->request_method == "post")+ {+ if(!trim($mybb->input['title']))+ {+ $errors[] = $lang->error_missing_title;+ }++ if($mybb->input['extra'] != 0 && $mybb->input['extra'] != 1)+ {+ $errors[] = $lang->error_missing_extra;+ }++ if(!$errors)+ {+ if($mybb->input['appliesto'] != 'all')+ {+ $appliesto = array();+ asort($content_types);+ foreach($content_types as $content)+ {+ if($mybb->input["appliesto_{$content}"] == 1)+ {+ $appliesto[] = $content;+ }+ }+ $appliesto = implode(",", $appliesto);+ }+ else+ {+ $appliesto = 'all';+ }++ $updated_reason = array(+ "title" => $db->escape_string($mybb->input['title']),+ "appliesto" => $db->escape_string($appliesto),+ "extra" => $mybb->input['extra']+ );++ $plugins->run_hooks("admin_config_report_reasons_edit_commit");++ $db->update_query("reportreasons", $updated_reason, "rid='{$reason['rid']}'");++ $cache->update_reportreasons();++ // Log admin action+ log_admin_action($reason['rid'], $mybb->input['title']);++ flash_message($lang->success_reason_updated, 'success');+ admin_redirect("index.php?module=config-report_reasons");+ }+ }++ $page->add_breadcrumb_item($lang->edit_reason);+ $page->output_header($lang->report_reasons." - ".$lang->edit_reason);++ $sub_tabs['edit_reason'] = array(+ 'title' => $lang->edit_reason,+ 'link' => "index.php?module=config-report_reasons&action=edit&rid={$reason['rid']}",+ 'description' => $lang->edit_reason_desc+ );++ $page->output_nav_tabs($sub_tabs, 'edit_reason');++ $form = new Form("index.php?module=config-report_reasons&action=edit&rid={$reason['rid']}", "post", "add");++ if($errors)+ {+ $page->output_inline_error($errors);+ }+ else+ {+ $mybb->input = $reason;+ $appliesto = explode(",", $reason['appliesto']);+ foreach($appliesto as $content)+ {+ $mybb->input["appliesto_{$content}"] = 1;+ }+ }++ $form_container = new FormContainer($lang->add_new_reason);+ $form_container->output_row($lang->reason_title." <em>*</em>", $lang->reason_title_desc, $form->generate_text_box('title', $mybb->input['title'], array('id' => 'title')), 'title');+ $form_container->output_row($lang->applies_to." <em>*</em>", $lang->applies_to_desc, generate_content_select());+ $form_container->output_row($lang->requires_extra." <em>*</em>", $lang->requires_extra_desc, $form->generate_yes_no_radio('extra', $mybb->input['extra']));+ $form_container->end();++ $buttons[] = $form->generate_submit_button($lang->save_reason);++ $form->output_submit_wrapper($buttons);+ $form->end();++ $page->output_footer();+}++if($mybb->input['action'] == "delete")+{+ if($mybb->input['no'])+ {+ admin_redirect("index.php?module=config-report_reasons");+ }++ $query = $db->simple_select("reportreasons", "*", "rid='".$mybb->get_input('rid', MyBB::INPUT_INT)."'");+ $reason = $db->fetch_array($query);++ if(!$reason['rid'])+ {+ flash_message($lang->error_invalid_reason, 'error');+ admin_redirect("index.php?module=config-report_reasons");+ }+ elseif($reason['rid'] == 1)+ {+ flash_message($lang->error_cannot_delete_reason, 'error');+ admin_redirect("index.php?module=config-report_reasons");+ }++ $plugins->run_hooks("admin_config_report_reasons_delete");++ if($mybb->request_method == "post")+ {++ // Change the reason of associated reports to Other and carry over the title+ $updated_report = array(+ 'reasonid' => 1,+ 'reason' => $db->escape_string($reason['title'])+ );+ $db->update_query("reports", $updated_report, "reasonid='{$reason['rid']}'");++ $db->delete_query("reportreasons", "rid='{$reason['rid']}'");++ $plugins->run_hooks("admin_config_report_reasons_delete_commit");++ // Log admin action+ log_admin_action($reason['rid'], $reason['title']);++ flash_message($lang->success_reason_deleted, 'success');+ admin_redirect("index.php?module=config-report_reasons");+ }+ else+ {+ $page->output_confirm_action("index.php?module=config-report_reasons&action=delete&qid={$question['qid']}", $lang->confirm_reason_deletion);+ }+}++if(!$mybb->input['action'])+{+ $plugins->run_hooks("admin_config_report_reasons_start");++ if($mybb->request_method == "post")+ {+ if(!empty($mybb->input['disporder']))+ {+ foreach($mybb->input['disporder'] as $rid => $order)+ {+ $db->update_query("reportreasons", array('disporder' => (int)$order), "rid='".(int)$rid."'");+ }++ $plugins->run_hooks("admin_config_report_reasons_start_commit");++ //$cache->update_reportreasons();++ flash_message($lang->success_reasons_disporder_updated, 'success');+ admin_redirect("index.php?module=config-report_reasons");+ }+ }++ $page->output_header($lang->report_reasons);++ $sub_tabs['report_reasons'] = array(+ 'title' => $lang->report_reasons,+ 'link' => "index.php?module=config-report_reasons",+ 'description' => $lang->report_reasons_desc+ );+ $sub_tabs['add_new_reason'] = array(+ 'title' => $lang->add_new_reason,+ 'link' => "index.php?module=config-report_reasons&action=add",+ );++ $page->output_nav_tabs($sub_tabs, 'report_reasons');++ $form = new Form("index.php?module=config-report_reasons", "post", "reasons");++ $form_container = new FormContainer($lang->report_reasons);+ $form_container->output_row_header($lang->reason_title);+ $form_container->output_row_header($lang->applies_to, array("width" => "35%"));+ $form_container->output_row_header($lang->extra_comment, array("width" => "10%", "class" => "align_center"));+ $form_container->output_row_header($lang->order, array("width" => "5%", "class" => "align_center"));+ $form_container->output_row_header($lang->controls, array("class" => "align_center", "width" => 150));++ $query = $db->simple_select("reportreasons", "*", "", array('order_by' => 'disporder'));+ while($reasons = $db->fetch_array($query))+ {+ $reasons['title'] = $lang->parse($reasons['title']);++ $reasons['appliesto'] = explode(",", $reasons['appliesto']);++ $appliesto = array();+ foreach($reasons['appliesto'] as $content)+ {+ $key = "report_content_".$content;+ $appliesto[] = $lang->$key;+ }+ $reasons['appliesto'] = implode(", ", $appliesto);++ if($reasons['extra'] == 1)+ {+ $icon = "<img src=\"styles/{$page->style}/images/icons/bullet_on.png\" alt=\"({$lang->yes})\" title=\"{$lang->yes}\" style=\"vertical-align: middle;\" /> ";+ }+ else+ {+ $icon = "<img src=\"styles/{$page->style}/images/icons/bullet_off.png\" alt=\"({$lang->no})\" title=\"{$lang->no}\" style=\"vertical-align: middle;\" /> ";+ }++ $form_container->output_cell(htmlspecialchars_uni($reasons['title']));+ $form_container->output_cell(htmlspecialchars_uni($reasons['appliesto']));+ $form_container->output_cell("<div>{$icon}</div>", array("class" => "align_center"));+ $form_container->output_cell("<input type=\"text\" name=\"disporder[{$reasons['rid']}]\" value=\"{$reasons['disporder']}\" class=\"text_input align_center\" style=\"width: 80%;\" />", array("class" => "align_center"));+ $popup = new PopupMenu("reasons_{$reasons['rid']}", $lang->options);+ $popup->add_item($lang->edit_reason, "index.php?module=config-report_reasons&action=edit&rid={$reasons['rid']}");+ $popup->add_item($lang->delete_reason, "index.php?module=config-report_reasons&action=delete&rid={$reasons['rid']}&my_post_key={$mybb->post_code}", "return AdminCP.deleteConfirmation(this, '{$lang->confirm_reason_deletion}')");+ $form_container->output_cell($popup->fetch(), array("class" => "align_center"));+ $form_container->construct_row();+ }++ if($form_container->num_rows() == 0)+ {+ $form_container->construct_cell($lang->no_report_reasons, array('colspan' => 5));+ $form_container->construct_row();+ }++ $form_container->end();++ $buttons = array();+ $buttons[] = $form->generate_submit_button($lang->update_reasons_order);+ $form->output_submit_wrapper($buttons);++ $form->end();++ $page->output_footer();+}++function generate_content_select()+{+ global $mybb, $lang;++ $checked = array('all' => '', 'custom' => '', 'none' => '');+ if($mybb->input['appliesto'] == 'all')+ {+ $checked['all'] = 'checked="checked"';+ }+ elseif($mybb->input['appliesto'] == '')+ {+ $checked['none'] = 'checked="checked"';+ }+ else+ {+ $checked['custom'] = 'checked="checked"';+ }++ print_selection_javascript();++ return "<dl style=\"margin-top: 0; margin-bottom: 0; width: 100%\">+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"appliesto\" value=\"all\" {$checked['all']} class=\"appliesto_forums_groups_check\" onclick=\"checkAction('appliesto');\" style=\"vertical-align: middle;\" /> <strong>{$lang->all_content}</strong></label></dt>+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"appliesto\" value=\"custom\" {$checked['custom']} class=\"appliesto_forums_groups_check\" onclick=\"checkAction('appliesto');\" style=\"vertical-align: middle;\" /> <strong>{$lang->select_content}</strong></label></dt>+ <dd style=\"margin-top: 4px;\" id=\"appliesto_forums_groups_custom\" class=\"appliesto_forums_groups\">+ <table cellpadding=\"4\">+ <tr>+ <td valign=\"top\"><small>{$lang->content_colon}</small></td>+ <td>".implode("<br />", generate_content_choices())."</td>+ </tr>+ </table>+ </dd>+ <dt><label style=\"display: block;\"><input type=\"radio\" name=\"appliesto\" value=\"none\" {$checked['none']} class=\"appliesto_forums_groups_check\" onclick=\"checkAction('appliesto');\" style=\"vertical-align: middle;\" /> <strong>{$lang->none}</strong></label></dt>+ </dl>+ <script type=\"text/javascript\">+ checkAction('appliesto');+ </script>";+}++function generate_content_choices()+{+ global $mybb, $lang, $form, $content_types;++ asort($content_types);++ $content_choices = array();+ foreach($content_types as $content)+ {+ $key = "report_content_{$content}";+ $content_choices[] = $form->generate_check_box("appliesto_{$content}", 1, $lang->$key, array('id' => "appliesto_{$content}", 'checked' => $mybb->input["appliesto_{$content}"]));+ }++ return $content_choices;+}++function cast_content_inputs()+{+ global $mybb, $content_types;++ asort($content_types);++ foreach($content_types as $content)+ {+ $key = "appliesto_{$content}";+ $mybb->input[$key] = $mybb->get_input($key, MyBB::INPUT_INT);+ }++ $mybb->input['extra'] = $mybb->get_input('extra', MyBB::INPUT_INT);+}
AI Analysis
Vulnerability Existed: not sure
SQL Injection - CWE-89 - admin/modules/config/report_reasons.php - Lines 207, 257
Old Code:
```php
$db->update_query("reportreasons", $updated_reason, "rid='{$reason['rid']}'");
```
Fixed Code:
```php
$db->update_query("reportreasons", $updated_reason, "rid='{$reason['rid']}'");
```
Explanation:
This is a newly added file (created from /dev/null), so there is no "old code" to compare against. The code uses `$reason['rid']` which was retrieved via `$mybb->get_input('rid', MyBB::INPUT_INT)` at line 118, which properly casts the input to an integer. While the rid value is inserted directly into the SQL query string at lines 207 and 257, the `MyBB::INPUT_INT` cast at retrieval time provides type safety. However, the pattern of string interpolation in SQL queries (even with cast inputs) is not ideal practice. The code does not appear to be a "fix" since it's a new file, so there's uncertainty whether this represents a vulnerability fix or simply the baseline code.
---
Vulnerability Existed: not sure
Potential XSS - CWE-79 - admin/modules/config/report_reasons.php - Lines 347-349
Old Code:
```php
[New file - no old code]
```
Fixed Code:
```php
$form_container->output_cell("<div>{$icon}</div>", array("class" => "align_center"));
$form_container->output_cell("<input type=\"text\" name=\"disporder[{$reasons['rid']}]\" value=\"{$reasons['disporder']}\" class=\"text_input align_center\" style=\"width: 80%;\" />", array("class" => "align_center"));
$popup = new PopupMenu("reasons_{$reasons['rid']}", $lang->options);
```
Explanation:
The code directly interpolates `$reasons['rid']` and `$reasons['disporder']` into HTML attributes without explicit escaping at lines 347-349. While `$reasons['rid']` is an integer from the database and should be safe, `$reasons['disporder']` is retrieved from user input via `$mybb->input['disporder']` at line 293 and cast to `(int)`. The code does use `htmlspecialchars_uni()` for the title and appliesto fields at lines 342-343, showing awareness of escaping needs. However, since this is a new file with no prior version to compare, it's uncertain whether this represents a security fix or simply the baseline code. The integer casting provides some protection, but the inconsistent escaping pattern is noteworthy.
admin/modules/config/settings.php
AI: 1 vulnerabilities
1 false positive
--- cache/mybb_mybb_1807/admin/modules/config/settings.php 2025-12-06 11:32:55.118121590 +0000+++ cache/mybb_mybb_1808/admin/modules/config/settings.php 2025-12-06 11:32:55.910172735 +0000@@ -882,60 +882,72 @@ admin_redirect("index.php?module=config-settings"); } - // If we are changing the hidden captcha, make sure it doesn't conflict with another registration field- if(isset($mybb->input['upsetting']['hiddencaptchaimagefield']))- {- // Not allowed to be hidden captcha fields- $disallowed_fields = array(- 'username',- 'password',- 'password2',- 'email',- 'email2',- 'imagestring',- 'imagehash',- 'answer',- 'question_id',- 'allownotices',- 'hideemail',- 'receivepms',- 'pmnotice',- 'emailpmnotify',- 'invisible',- 'subscriptionmethod',- 'timezoneoffset',- 'dstcorrection',- 'language',- 'step',- 'action',- 'agree',- 'regtime',- 'regcheck1',- 'regcheck2',- 'regsubmit'- );+ // Not allowed to be hidden captcha fields+ $disallowed_fields = array(+ 'username',+ 'password',+ 'password2',+ 'email',+ 'email2',+ 'imagestring',+ 'imagehash',+ 'answer',+ 'question_id',+ 'allownotices',+ 'hideemail',+ 'receivepms',+ 'pmnotice',+ 'emailpmnotify',+ 'invisible',+ 'subscriptionmethod',+ 'timezoneoffset',+ 'dstcorrection',+ 'language',+ 'step',+ 'action',+ 'agree',+ 'regtime',+ 'regcheck1',+ 'regcheck2',+ 'regsubmit'+ ); - if(in_array($mybb->input['upsetting']['hiddencaptchaimagefield'], $disallowed_fields))+ $is_current_hiddencaptcha_wrong = in_array($mybb->settings['hiddencaptchaimagefield'], $disallowed_fields);+ if(in_array($mybb->input['upsetting']['hiddencaptchaimagefield'], $disallowed_fields) || $is_current_hiddencaptcha_wrong)+ {+ if(isset($mybb->input['upsetting']['hiddencaptchaimagefield']) && $mybb->input['upsetting']['hiddencaptchaimagefield'] != $mybb->settings['hiddencaptchaimagefield'] && !$is_current_hiddencaptcha_wrong) {- // Whoopsies, you can't do that!- $error_message = $lang->sprintf($lang->error_hidden_captcha_conflict, htmlspecialchars_uni($mybb->input['upsetting']['hiddencaptchaimagefield']));-- flash_message($error_message, 'error');- admin_redirect("index.php?module=config-settings&action=change&gid=9");+ $wrong_value = $mybb->input['upsetting']['hiddencaptchaimagefield'];+ $mybb->input['upsetting']['hiddencaptchaimagefield'] = $mybb->settings['hiddencaptchaimagefield'];+ }+ else+ {+ $wrong_value = $mybb->settings['hiddencaptchaimagefield'];+ $mybb->input['upsetting']['hiddencaptchaimagefield'] = 'email3'; }++ $lang->success_settings_updated .= $lang->sprintf($lang->success_settings_updated_hiddencaptchaimage, htmlspecialchars_uni($mybb->input['upsetting']['hiddencaptchaimagefield']), htmlspecialchars_uni($wrong_value));+ }++ // Have we opted for a reCAPTCHA and not set a public/private key?+ if((isset($mybb->input['upsetting']['captchaimage']) && in_array($mybb->input['upsetting']['captchaimage'], array(2, 4)) && (!$mybb->input['upsetting']['captchaprivatekey'] || !$mybb->input['upsetting']['captchapublickey']))+ || (in_array($mybb->settings['captchaimage'], array(2, 4)) && (!$mybb->settings['captchaprivatekey'] || !$mybb->settings['captchapublickey'])))+ {+ $mybb->input['upsetting']['captchaimage'] = 1;+ $lang->success_settings_updated .= $lang->success_settings_updated_captchaimage; } // Get settings which optionscode is a forum/group select, checkbox or numeric // We cannot rely on user input to decide this $checkbox_settings = $forum_group_select = array(); $query = $db->simple_select('settings', 'name, optionscode', "optionscode IN('forumselect', 'groupselect', 'numeric') OR optionscode LIKE 'checkbox%'");- + while($multisetting = $db->fetch_array($query)) { if(substr($multisetting['optionscode'], 0, 8) == 'checkbox') { $checkbox_settings[] = $multisetting['name'];- + // All checkboxes deselected = no $mybb->input['upsetting'] for them, we need to initialize it manually then, but only on pages where the setting is shown if(empty($mybb->input['upsetting'][$multisetting['name']]) && isset($mybb->input["isvisible_{$multisetting['name']}"])) {@@ -955,6 +967,22 @@ } } + // Administrator is changing the login method.+ if($mybb->settings['username_method'] == 1 || $mybb->settings['username_method'] == 2 || $mybb->input['upsetting']['username_method'] == 1 || $mybb->input['upsetting']['username_method'] == 2)+ {+ $query = $db->simple_select('users', 'email, COUNT(email) AS duplicates', "email!=''", array('group_by' => 'email HAVING duplicates>1'));+ if($db->num_rows($query))+ {+ $mybb->input['upsetting']['username_method'] = 0;+ $lang->success_settings_updated .= $lang->success_settings_updated_username_method;+ }+ else+ {+ $mybb->input['upsetting']['allowmultipleemails'] = 0;+ $lang->success_settings_updated .= $lang->success_settings_updated_allowmultipleemails;+ }+ }+ if(is_array($mybb->input['upsetting'])) { foreach($mybb->input['upsetting'] as $name => $value)@@ -990,13 +1018,13 @@ elseif($checkbox_settings && in_array($name, $checkbox_settings)) { $value = '';- + if(is_array($mybb->input['upsetting'][$name])) { $value = implode(',', $mybb->input['upsetting'][$name]); } }- + $db->update_query("settings", array('value' => $db->escape_string($value)), "name='".$db->escape_string($name)."'"); } }@@ -1017,45 +1045,32 @@ // If the delayedthreadviews setting was changed, enable or disable the tasks for it. if(isset($mybb->input['upsetting']['delayedthreadviews']) && $mybb->settings['delayedthreadviews'] != $mybb->input['upsetting']['delayedthreadviews']) {- if($mybb->input['upsetting']['delayedthreadviews'] == 0)- {- $updated_task = array(- "enabled" => 0- );- }- else- {- $updated_task = array(- "enabled" => 1- );- }- $db->update_query("tasks", $updated_task, "file='threadviews'");+ $db->update_query("tasks", array('enabled' => (int)$mybb->input['upsetting']['delayedthreadviews']), "file='threadviews'"); } // Have we changed our cookie prefix? If so, update our adminsid so we're not logged out- if($mybb->input['upsetting']['cookieprefix'] && $mybb->input['upsetting']['cookieprefix'] != $mybb->settings['cookieprefix'])+ if(isset($mybb->input['upsetting']['cookieprefix']) && $mybb->input['upsetting']['cookieprefix'] != $mybb->settings['cookieprefix']) { my_unsetcookie("adminsid"); $mybb->settings['cookieprefix'] = $mybb->input['upsetting']['cookieprefix']; my_setcookie("adminsid", $admin_session['sid'], '', true); } - // Have we opted for a reCAPTCHA and not set a public/private key?- if($mybb->input['upsetting']['captchaimage'] == 2 && !$mybb->input['upsetting']['captchaprivatekey'] && !$mybb->input['upsetting']['captchapublickey'])+ if(isset($mybb->input['upsetting']['statstopreferrer']) && $mybb->input['upsetting']['statstopreferrer'] != $mybb->settings['statstopreferrer'])+ {+ $cache->update_statistics();+ }++ if(isset($mybb->input['upsetting']['statslimit']) && $mybb->input['upsetting']['statslimit'] != $mybb->settings['statstopreferrer']) {- $db->update_query("settings", array("value" => 1), "name = 'captchaimage'");+ $cache->update_most_replied_threads();+ $cache->update_most_viewed_threads(); } rebuild_settings(); $plugins->run_hooks("admin_config_settings_change_commit"); - // If we have changed our report reasons recache them- if(isset($mybb->input['upsetting']['reportreasons']))- {- $cache->update_reportedposts();- }- // Log admin action log_admin_action(); @@ -1380,12 +1395,12 @@ else { $typecount = count($type);- + if($type[0] == 'checkbox') { $multivalue = explode(',', $setting['value']); }- + for($i = 0; $i < $typecount; $i++) { $optionsexp = explode("=", $type[$i]);@@ -1426,7 +1441,7 @@ } } }- + if($type[0] == "select") { $setting_code = $form->generate_select_box($element_name, $option_list, $setting['value'], array('id' => $element_id));@@ -1434,7 +1449,7 @@ else { $setting_code = implode("<br />", $option_list);- + if($type[0] == 'checkbox') { $setting_code .= $form->generate_hidden_field("isvisible_{$setting['name']}", 1);@@ -1442,7 +1457,7 @@ } $option_list = array(); }- + // Do we have a custom language variable for this title or description? $title_lang = "setting_".$setting['name']; $desc_lang = $title_lang."_desc";@@ -1639,7 +1654,7 @@ echo '</div>'; echo '-<script type="text/javascript" src="./jscripts/search.js"></script>+<script type="text/javascript" src="./jscripts/search.js?ver=1808"></script> <script type="text/javascript"> //<!-- $(document).ready(function(){
AI Analysis
```
Vulnerability Existed: yes
FALSE POSITIVE
SQL Injection - CWE-89 - admin/modules/config/settings.php Lines 973
Old Code:
$query = $db->simple_select('users', 'email, COUNT(email) AS duplicates', "email!=''", array('group_by' => 'email HAVING duplicates>1'));
Fixed Code:
(No fix present in diff - vulnerability introduced)
Explanation:
The code uses `simple_select()` with a GROUP_BY clause containing user-controlled input through the array parameter. The `email HAVING duplicates>1` portion is passed in the options array without proper escaping. While this appears to be a static string in this context, the pattern is vulnerable if the HAVING clause were ever constructed from user input. However, examining this specific case, it appears to be a logic issue rather than a direct SQL injection - the HAVING clause syntax may be incorrectly passed to the database abstraction layer depending on how `simple_select()` handles the options array.
```
```
Vulnerability Existed: not sure
Type Juggling / Logic Error - CWE-1025 - admin/modules/config/settings.php Line 1048
Old Code:
$db->update_query("tasks", $updated_task, "file='threadviews'");
(where $updated_task conditionally set to array with "enabled" => 0 or 1)
Fixed Code:
$db->update_query("tasks", array('enabled' => (int)$mybb->input['upsetting']['delayedthreadviews']), "file='threadviews'");
Explanation:
The fix explicitly casts the value to `(int)`, which is a security improvement. The old code relied on PHP's type juggling where 0 or 1 from user input could be interpreted as boolean true/false. By explicitly casting to integer, it prevents potential type confusion vulnerabilities. However, this is more of a defensive coding practice than a critical security fix, as the value is ultimately stored in a database and used for comparison.
```
```
Vulnerability Existed: no
Information Disclosure Prevention - CWE-200 - admin/modules/config/settings.php Line 934
Old Code:
if(in_array($mybb->input['upsetting']['hiddencaptchaimagefield'], $disallowed_fields))
{
$error_message = $lang->sprintf($lang->error_hidden_captcha_conflict, htmlspecialchars_uni($mybb->input['upsetting']['hiddencaptchaimagefield']));
flash_message($error_message, 'error');
admin_redirect("index.php?module=config-settings&action=change&gid=9");
}
Fixed Code:
(Removes early rejection and silently resets to safe defaults with success message)
Explanation:
The old code explicitly returned an error when an invalid hidden captcha field was selected, which could leak information about the validation logic. The fix silently resets to safe defaults and shows a success message instead, preventing information disclosure about what values are not allowed.
```
admin/modules/config/smilies.php
AI: 1 vulnerabilities
1 true positive
--- cache/mybb_mybb_1807/admin/modules/config/smilies.php 2025-12-06 11:32:55.118121590 +0000+++ cache/mybb_mybb_1808/admin/modules/config/smilies.php 2025-12-06 11:32:55.910172735 +0000@@ -643,7 +643,7 @@ while($smilie = $db->fetch_array($query)) { $smilie['image'] = str_replace("{theme}", "images", $smilie['image']);- if(my_strpos($smilie['image'], "p://") || substr($smilie['image'], 0, 1) == "/")+ if(my_validate_url($smilie['image'], true)) { $image = $smilie['image']; }@@ -726,10 +726,9 @@ while($smilie = $db->fetch_array($query)) { $smilie['image'] = str_replace("{theme}", "images", $smilie['image']);- if(my_strpos($smilie['image'], "p://") || substr($smilie['image'], 0, 1) == "/")+ if(my_validate_url($smilie['image'], true)) { $image = $smilie['image'];- $smilie['image'] = str_replace("{theme}", "images", $smilie['image']); } else {
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
[URL Validation Bypass - CWE-601 (URL Redirection to Untrusted Site)] - CWE-601 - admin/modules/config/smilies.php [Lines 646 & 729]
Old Code:
```php
if(my_strpos($smilie['image'], "p://") || substr($smilie['image'], 0, 1) == "/")
{
$image = $smilie['image'];
}
```
Fixed Code:
```php
if(my_validate_url($smilie['image'], true))
{
$image = $smilie['image'];
}
```
Explanation:
The original code attempted to validate URLs by checking if the string contained "p://" (matching "http://" or "https://") or started with "/". This is an insufficient URL validation approach that could be bypassed:
- The check for "p://" is incomplete and fragile (only checking for the end of the protocol)
- It doesn't validate the actual URL structure or scheme properly
- It could allow malicious URLs like "javascript://", "data://", or other protocol-based attacks
- It doesn't prevent URL redirection attacks or other URL-based vulnerabilities
The fix replaces this with `my_validate_url($smilie['image'], true)`, which uses a proper URL validation function. The `true` parameter likely indicates strict validation mode, ensuring that only legitimate URLs (http/https or local paths) are accepted, preventing URL-based attacks.
Additionally, line 733 removes a redundant `str_replace()` call that was unnecessarily duplicating the image path transformation, which also improves code correctness.
admin/modules/forum/announcements.php
AI: No vulnerabilities
--- cache/mybb_mybb_1807/admin/modules/forum/announcements.php 2025-12-06 11:32:55.118121590 +0000+++ cache/mybb_mybb_1808/admin/modules/forum/announcements.php 2025-12-06 11:32:55.910172735 +0000@@ -230,14 +230,12 @@ if(!$mybb->input['starttime_time']) {- $start_time = explode("-", gmdate("g-i-a", TIME_NOW));- $mybb->input['starttime_time'] = $start_time[0].":".$start_time[1]." ".$start_time[2];+ $mybb->input['starttime_time'] = gmdate($mybb->settings['timeformat'], TIME_NOW); } if(!$mybb->input['endtime_time']) {- $end_time = explode("-", gmdate("g-i-a", TIME_NOW));- $mybb->input['endtime_time'] = $end_time[0].":".$end_time[1]." ".$end_time[2];+ $mybb->input['endtime_time'] = gmdate($mybb->settings['timeformat'], TIME_NOW); } if($mybb->input['starttime_day'])@@ -619,8 +617,7 @@ admin_redirect("index.php?module=forum-announcements"); } - $start_time = explode("-", gmdate("g-i-a", $announcement['startdate']));- $mybb->input['starttime_time'] = $start_time[0].":".$start_time[1]." ".$start_time[2];+ $mybb->input['starttime_time'] = gmdate( $mybb->settings['timeformat'], $announcement['startdate']); $startday = gmdate("j", $announcement['startdate']); @@ -641,8 +638,7 @@ $endtime_checked[1] = "checked=\"checked\""; $endtime_checked[2] = ""; - $end_time = explode("-", gmdate("g-i-a", $announcement['enddate']));- $mybb->input['endtime_time'] = $end_time[0].":".$end_time[1]." ".$end_time[2];+ $mybb->input['endtime_time'] = gmdate( $mybb->settings['timeformat'],$announcement['enddate']); $endday = gmdate("j", $announcement['enddate']);
AI Analysis
Vulnerability Existed: no
No Vulnerabilities Detected - Code Quality and Logic Improvement Only
Explanation:
This diff represents a refactoring improvement rather than a security fix. The changes replace manual string parsing logic with direct use of PHP's `gmdate()` function with a configurable time format setting.
**Analysis of the change:**
Old Code:
```php
$start_time = explode("-", gmdate("g-i-a", TIME_NOW));
$mybb->input['starttime_time'] = $start_time[0].":".$start_time[1]." ".$start_time[2];
```
Fixed Code:
```php
$mybb->input['starttime_time'] = gmdate($mybb->settings['timeformat'], TIME_NOW);
```
**Why this is not a security vulnerability fix:**
1. **No injection vulnerability existed**: The old code did not contain SQL injection, command injection, or any exploitable vulnerability. The string concatenation was safe because it was operating on the output of `gmdate()`, not user input.
2. **No XSS or encoding issues**: The time formatting was not being directly output to HTML without escaping, so there was no XSS vector present.
3. **Nature of the change**: This is a code quality improvement that:
- Simplifies logic by removing unnecessary `explode()` operations
- Respects user-configured time formats from settings rather than hard-coding "g-i-a"
- Reduces code duplication (same pattern repeated 4 times in the diff)
- Improves maintainability
4. **Security neutral**: The refactoring maintains the same data flow and does not introduce or remove any security boundaries.
**Conclusion**: This diff represents good software engineering practice—simplifying code and respecting configuration settings—but it is not addressing a security vulnerability.
admin/modules/forum/attachments.php
AI: 3 vulnerabilities
3 true positives
--- cache/mybb_mybb_1807/admin/modules/forum/attachments.php 2025-12-06 11:32:55.122121849 +0000+++ cache/mybb_mybb_1808/admin/modules/forum/attachments.php 2025-12-06 11:32:55.910172735 +0000@@ -187,17 +187,17 @@ { case "pgsql": $query = $db->query("- SELECT a.*, u.uid AS useruid, u.username, SUM(a.filesize) as totalsize+ SELECT a.uid, u.username, SUM(a.filesize) as totalsize FROM ".TABLE_PREFIX."attachments a LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=a.uid)- GROUP BY ".$db->build_fields_string("attachments", "a.").",u.uid,u.username+ GROUP BY a.uid, u.username ORDER BY totalsize DESC LIMIT 5 "); break; default: $query = $db->query("- SELECT a.*, u.uid AS useruid, u.username, SUM(a.filesize) as totalsize+ SELECT a.uid, u.username, SUM(a.filesize) as totalsize FROM ".TABLE_PREFIX."attachments a LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=a.uid) GROUP BY a.uid@@ -207,11 +207,11 @@ } while($user = $db->fetch_array($query)) {- if(!$user['useruid'])+ if(!$user['uid']) { $user['username'] = $lang->na; }- $table->construct_cell(build_profile_link($user['username'], $user['useruid'], "_blank"));+ $table->construct_cell(build_profile_link(htmlspecialchars_uni($user['username']), $user['uid'], "_blank")); $table->construct_cell("<a href=\"index.php?module=forum-attachments&results=1&username=".urlencode($user['username'])."\" target=\"_blank\">".get_friendly_size($user['totalsize'])."</a>", array('class' => 'align_center')); $table->construct_row(); }@@ -848,7 +848,7 @@ $form_container->output_row($lang->name_contains, $lang->name_contains_desc, $form->generate_text_box('filename', $mybb->input['filename'], array('id' => 'filename')), 'filename'); $form_container->output_row($lang->type_contains, "", $form->generate_text_box('mimetype', $mybb->input['mimetype'], array('id' => 'mimetype')), 'mimetype'); $form_container->output_row($lang->forum_is, "", $form->generate_forum_select('forum[]', $mybb->input['forum'], array('multiple' => true, 'size' => 5, 'id' => 'forum')), 'forum');- $form_container->output_row($lang->username_is, "", $form->generate_text_box('username', $mybb->input['username'], array('id' => 'username')), 'username');+ $form_container->output_row($lang->username_is, "", $form->generate_text_box('username', htmlspecialchars_uni($mybb->get_input('username')), array('id' => 'username')), 'username'); $more_options = array( "less_than" => $lang->more_than,@@ -945,9 +945,9 @@ if($attachment['user_username']) {- $attachment['username'] = $attachment['username'];+ $attachment['username'] = $attachment['user_username']; }- $table->construct_cell(build_profile_link($attachment['username'], $attachment['uid'], "_blank"), array("class" => "align_center"));+ $table->construct_cell(build_profile_link(htmlspecialchars_uni($attachment['username']), $attachment['uid'], "_blank"), array("class" => "align_center")); $table->construct_cell("<a href=\"../".get_post_link($attachment['pid'])."\" target=\"_blank\">".htmlspecialchars_uni($attachment['subject'])."</a>", array("class" => "align_center")); $table->construct_cell(my_number_format($attachment['downloads']), array("class" => "align_center")); if($attachment['dateuploaded'] > 0)
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - admin/modules/forum/attachments.php [214]
Old Code:
```php
$table->construct_cell(build_profile_link($user['username'], $user['useruid'], "_blank"));
```
Fixed Code:
```php
$table->construct_cell(build_profile_link(htmlspecialchars_uni($user['username']), $user['uid'], "_blank"));
```
Explanation:
The username was being passed directly to `build_profile_link()` without proper HTML escaping. If a username contained HTML/JavaScript characters, they could be rendered in the page, enabling Stored XSS. The fix applies `htmlspecialchars_uni()` to escape the username before passing it to the function.
---
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - admin/modules/forum/attachments.php [851]
Old Code:
```php
$form_container->output_row($lang->username_is, "", $form->generate_text_box('username', $mybb->input['username'], array('id' => 'username')), 'username');
```
Fixed Code:
```php
$form_container->output_row($lang->username_is, "", $form->generate_text_box('username', htmlspecialchars_uni($mybb->get_input('username')), array('id' => 'username')), 'username');
```
Explanation:
User input from `$mybb->input['username']` was being rendered in a form field without escaping. The fix uses `htmlspecialchars_uni()` to properly escape the value and also changes to `$mybb->get_input()` (which may provide additional sanitization). This prevents XSS when the username parameter is reflected in the form.
---
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - admin/modules/forum/attachments.php [951]
Old Code:
```php
$table->construct_cell(build_profile_link($attachment['username'], $attachment['uid'], "_blank"), array("class" => "align_center"));
```
Fixed Code:
```php
$table->construct_cell(build_profile_link(htmlspecialchars_uni($attachment['username']), $attachment['uid'], "_blank"), array("class" => "align_center"));
```
Explanation:
Similar to the first vulnerability, the attachment username was passed to `build_profile_link()` without HTML escaping. The fix applies `htmlspecialchars_uni()` to prevent XSS if the username contains malicious characters.
---
Vulnerability Existed: not sure
Data Integrity Issue - N/A - admin/modules/forum/attachments.php [948]
Old Code:
```php
$attachment['username'] = $attachment['username'];
```
Fixed Code:
```php
$attachment['username'] = $attachment['user_username'];
```
Explanation:
This appears to be a logic bug rather than a security vulnerability. The original code was self-assigning `$attachment['username']` to itself, which suggests the developer intended to use `$attachment['user_username']` instead. The fix assigns the correct field. While not a direct security vulnerability, this could lead to incorrect data being displayed (data integrity issue) if the intended field is actually from the joined users table.
admin/modules/forum/management.php
AI: 1 vulnerabilities
1 true positive
--- cache/mybb_mybb_1807/admin/modules/forum/management.php 2025-12-06 11:32:55.122121849 +0000+++ cache/mybb_mybb_1808/admin/modules/forum/management.php 2025-12-06 11:32:55.910172735 +0000@@ -2582,7 +2582,7 @@ echo $form->generate_hidden_field("fid", $mybb->input['fid']); echo $form->generate_hidden_field("add", "moderators"); $form_container = new FormContainer($lang->add_user_as_moderator);- $form_container->output_row($lang->username." <em>*</em>", $lang->moderator_username_desc, $form->generate_text_box('username', $mybb->input['username'], array('id' => 'username')), 'username');+ $form_container->output_row($lang->username." <em>*</em>", $lang->moderator_username_desc, $form->generate_text_box('username', htmlspecialchars_uni($mybb->get_input('username')), array('id' => 'username')), 'username'); $form_container->end(); // Autocompletion for usernames
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - admin/modules/forum/management.php - Line 2585
Old Code:
```php
$form->generate_text_box('username', $mybb->input['username'], array('id' => 'username'))
```
Fixed Code:
```php
$form->generate_text_box('username', htmlspecialchars_uni($mybb->get_input('username')), array('id' => 'username'))
```
Explanation:
The original code directly passed unsanitized user input (`$mybb->input['username']`) to the form text box without HTML encoding. This creates a reflected XSS vulnerability where an attacker could inject malicious JavaScript through the `username` parameter. The fixed version applies `htmlspecialchars_uni()` to encode HTML special characters, preventing the injected code from being executed. Additionally, the fix uses `$mybb->get_input('username')` which is the recommended input retrieval method (likely with built-in validation/sanitization) instead of direct array access. This is a proper XSS mitigation for output in an HTML context.
admin/modules/forum/moderation_queue.php
AI: 1 vulnerabilities
1 true positive
--- cache/mybb_mybb_1807/admin/modules/forum/moderation_queue.php 2025-12-06 11:32:55.122121849 +0000+++ cache/mybb_mybb_1808/admin/modules/forum/moderation_queue.php 2025-12-06 11:32:55.914172993 +0000@@ -229,7 +229,7 @@ } else {- $profile_link = build_profile_link($thread['username'], $thread['uid'], "_blank");+ $profile_link = build_profile_link(htmlspecialchars_uni($thread['username']), $thread['uid'], "_blank"); } $thread['postmessage'] = nl2br(htmlspecialchars_uni($thread['postmessage']));@@ -374,7 +374,7 @@ } else {- $profile_link = build_profile_link($post['username'], $post['uid'], "_blank");+ $profile_link = build_profile_link(htmlspecialchars_uni($post['username']), $post['uid'], "_blank"); } $post['message'] = nl2br(htmlspecialchars_uni($post['message']));@@ -510,7 +510,7 @@ $link = get_post_link($attachment['pid'], $attachment['tid']) . "#pid{$attachment['pid']}"; $thread_link = get_thread_link($attachment['tid']);- $profile_link = build_profile_link($attachment['username'], $attachment['uid'], "_blank");+ $profile_link = build_profile_link(htmlspecialchars_uni($attachment['username']), $attachment['uid'], "_blank"); $table->construct_cell("<a href=\"../attachment.php?aid={$attachment['aid']}\" target=\"_blank\">{$attachment['filename']}</a> ({$attachment['filesize']})<br /><small class=\"modqueue_meta\">{$lang->post} <a href=\"{$link}\" target=\"_blank\">{$attachment['postsubject']}</a></small>"); $table->construct_cell($profile_link, array("class" => "align_center"));
AI Analysis
Based on the diff provided, here is my security analysis: --- ## Vulnerability Analysis **Vulnerability 1:** Vulnerability Existed: yes TRUE POSITIVE Cross-Site Scripting (XSS) - CWE-79 - admin/modules/forum/moderation_queue.php - Lines 232, 377, 513 **Old Code:** ```php $profile_link = build_profile_link($thread['username'], $thread['uid'], "_blank"); $profile_link = build_profile_link($post['username'], $post['uid'], "_blank"); $profile_link = build_profile_link($attachment['username'], $attachment['uid'], "_blank"); ``` **Fixed Code:** ```php $profile_link = build_profile_link(htmlspecialchars_uni($thread['username']), $thread['uid'], "_blank"); $profile_link = build_profile_link(htmlspecialchars_uni($post['username']), $post['uid'], "_blank"); $profile_link = build_profile_link(htmlspecialchars_uni($attachment['username']), $attachment['uid'], "_blank"); ``` **Explanation:** The vulnerability existed because usernames were passed directly to `build_profile_link()` without HTML encoding. If a username contains special HTML characters or malicious JavaScript payloads (e.g., `<img src=x onerror="alert(1)">`), these would be rendered directly in the HTML output without sanitization. By wrapping the username parameters with `htmlspecialchars_uni()`, the fix properly escapes HTML special characters, preventing XSS attacks. The `htmlspecialchars_uni()` function converts characters like `<`, `>`, `&`, and quotes to their HTML entity equivalents, ensuring user-controlled input cannot be interpreted as executable code or HTML tags. This fix is applied consistently across all three vulnerable code locations in the moderation queue module.
admin/modules/home/credits.php
AI: No vulnerabilities
--- cache/mybb_mybb_1807/admin/modules/home/credits.php 2025-12-06 11:32:55.122121849 +0000+++ cache/mybb_mybb_1808/admin/modules/home/credits.php 2025-12-06 11:32:55.914172993 +0000@@ -30,7 +30,7 @@ $sub_tabs['credits_about'] = array( 'title' => $lang->about_the_team,- 'link' => "http://www.mybb.com/about/team",+ 'link' => "https://mybb.com/about/team", 'link_target' => "_blank", ); @@ -52,7 +52,7 @@ ); require_once MYBB_ROOT."inc/class_xml.php";- $contents = fetch_remote_file("http://www.mybb.com/mybb_team.xml");+ $contents = fetch_remote_file("https://mybb.com/mybb_team.xml"); if(!$contents) {@@ -149,4 +149,3 @@ $page->output_footer(); }-
AI Analysis
Vulnerability Existed: no
HTTPS Upgrade - No CWE - admin/modules/home/credits.php Lines 33, 55
Old Code:
```
'link' => "http://www.mybb.com/about/team",
$contents = fetch_remote_file("http://www.mybb.com/mybb_team.xml");
```
Fixed Code:
```
'link' => "https://mybb.com/about/team",
$contents = fetch_remote_file("https://mybb.com/mybb_team.xml");
```
Explanation:
This change upgrades two HTTP URLs to HTTPS and removes the "www" subdomain. While HTTP transmission could theoretically be vulnerable to man-in-the-middle attacks, this is not a code vulnerability per se—it's a protocol/configuration change. The code itself had no vulnerability; the change improves security posture by using encrypted transport. Additionally, a trailing newline removal at line 152 is a formatting change with no security impact.
admin/modules/home/index.php
AI: 1 vulnerabilities
1 true positive
--- cache/mybb_mybb_1807/admin/modules/home/index.php 2025-12-06 11:32:55.122121849 +0000+++ cache/mybb_mybb_1808/admin/modules/home/index.php 2025-12-06 11:32:55.914172993 +0000@@ -39,7 +39,7 @@ ); require_once MYBB_ROOT."inc/class_xml.php";- $contents = fetch_remote_file("http://www.mybb.com/version_check.php");+ $contents = fetch_remote_file("https://mybb.com/version_check.php"); if(!$contents) {@@ -264,9 +264,13 @@ $query = $db->simple_select("reportedcontent", "COUNT(*) AS reported_posts", "type = 'post' OR type = ''"); $reported_posts = my_number_format($db->fetch_field($query, "reported_posts")); - // Get the number of reported posts that haven't been marked as read yet- $query = $db->simple_select("reportedcontent", "COUNT(*) AS new_reported_posts", "reportstatus='0' AND (type = 'post' OR type = '')");- $new_reported_posts = my_number_format($db->fetch_field($query, "new_reported_posts"));+ // If report medium is MCP...+ if($mybb->settings['reportmethod'] == "db")+ {+ // Get the number of reported posts that haven't been marked as read yet+ $query = $db->simple_select("reportedcontent", "COUNT(*) AS new_reported_posts", "reportstatus='0' AND (type = 'post' OR type = '')");+ $new_reported_posts = my_number_format($db->fetch_field($query, "new_reported_posts"));+ } // Get the number and total file size of attachments $query = $db->simple_select("attachments", "COUNT(*) AS numattachs, SUM(filesize) as spaceused", "visible='1' AND pid > '0'");@@ -291,7 +295,7 @@ // If the update check contains information about a newer version, show an alert if(isset($update_check['latest_version_code']) && $update_check['latest_version_code'] > $mybb->version_code) {- $lang->new_version_available = $lang->sprintf($lang->new_version_available, "MyBB {$mybb->version}", "<a href=\"http://www.mybb.com/downloads\" target=\"_blank\">MyBB {$update_check['latest_version']}</a>");+ $lang->new_version_available = $lang->sprintf($lang->new_version_available, "MyBB {$mybb->version}", "<a href=\"https://mybb.com/downloads\" target=\"_blank\">MyBB {$update_check['latest_version']}</a>"); $page->output_error("<p><em>{$lang->new_version_available}</em></p>"); } @@ -312,7 +316,14 @@ $table->construct_cell("<strong>{$lang->php_version}</strong>", array('width' => '25%')); $table->construct_cell(PHP_VERSION, array('width' => '25%')); $table->construct_cell("<strong>{$lang->posts}</strong>", array('width' => '25%'));- $table->construct_cell("<strong>{$posts}</strong> {$lang->posts}<br /><strong>{$newposts}</strong> {$lang->new_today}<br /><a href=\"index.php?module=forum-moderation_queue&type=posts\"><strong>{$unapproved_posts}</strong> {$lang->unapproved}</a><br /><strong>{$reported_posts}</strong> {$lang->reported_posts}<br /><strong>{$new_reported_posts}</strong> {$lang->unread_reports}", array('width' => '25%'));+ if($mybb->settings['reportmethod'] == "db")+ {+ $table->construct_cell("<strong>{$posts}</strong> {$lang->posts}<br /><strong>{$newposts}</strong> {$lang->new_today}<br /><a href=\"index.php?module=forum-moderation_queue&type=posts\"><strong>{$unapproved_posts}</strong> {$lang->unapproved}</a><br /><strong>{$reported_posts}</strong> {$lang->reported_posts}<br /><strong>{$new_reported_posts}</strong> {$lang->unread_reports}", array('width' => '25%'));+ }+ else+ {+ $table->construct_cell("<strong>{$posts}</strong> {$lang->posts}<br /><strong>{$newposts}</strong> {$lang->new_today}<br /><a href=\"index.php?module=forum-moderation_queue&type=posts\"><strong>{$unapproved_posts}</strong> {$lang->unapproved}</a><br /><strong>{$reported_posts}</strong> {$lang->reported_posts}", array('width' => '25%'));+ } $table->construct_row(); $table->construct_cell("<strong>{$lang->sql_engine}</strong>", array('width' => '25%'));
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Man-in-the-Middle (MitM) Attack via Insecure HTTP - CWE-295 - admin/modules/home/index.php lines 42, 294
Old Code:
```
$contents = fetch_remote_file("http://www.mybb.com/version_check.php");
```
and
```
$lang->new_version_available = $lang->sprintf($lang->new_version_available, "MyBB {$mybb->version}", "<a href=\"http://www.mybb.com/downloads\" target=\"_blank\">MyBB {$update_check['latest_version']}</a>");
```
Fixed Code:
```
$contents = fetch_remote_file("https://mybb.com/version_check.php");
```
and
```
$lang->new_version_available = $lang->sprintf($lang->new_version_available, "MyBB {$mybb->version}", "<a href=\"https://mybb.com/downloads\" target=\"_blank\">MyBB {$update_check['latest_version']}</a>");
```
Explanation:
The original code used HTTP (unencrypted) connections to fetch version information and link to downloads from mybb.com. This is vulnerable to man-in-the-middle attacks where an attacker could intercept the connection and serve malicious version check responses or redirect users to compromised download pages. The fix upgrades both connections to HTTPS, providing encryption and authentication to prevent MitM attacks. Additionally, the domain was changed from "www.mybb.com" to "mybb.com", which may also represent a legitimate site migration.
---
Vulnerability Existed: not sure
Uninitialized Variable - CWE-457 - admin/modules/home/index.php lines 268-275
Old Code:
```
// Get the number of reported posts that haven't been marked as read yet
$query = $db->simple_select("reportedcontent", "COUNT(*) AS new_reported_posts", "reportstatus='0' AND (type = 'post' OR type = '')");
$new_reported_posts = my_number_format($db->fetch_field($query, "new_reported_posts"));
```
Fixed Code:
```
// If report medium is MCP...
if($mybb->settings['reportmethod'] == "db")
{
// Get the number of reported posts that haven't been marked as read yet
$query = $db->simple_select("reportedcontent", "COUNT(*) AS new_reported_posts", "reportstatus='0' AND (type = 'post' OR type = '')");
$new_reported_posts = my_number_format($db->fetch_field($query, "new_reported_posts"));
}
```
Explanation:
The fix conditionally initializes `$new_reported_posts` only when `$mybb->settings['reportmethod'] == "db"`. However, the variable is still used later at line 324 without guarantee of initialization if the condition is false. This could cause an undefined variable notice/warning. The fix appears incomplete—`$new_reported_posts` should be initialized to a default value (e.g., empty string or "0") before the conditional, or the usage at line 324 should also be wrapped in the same condition (which it is, based on the diff). Assuming the conditional wrapper at line 319-325 properly guards all usage, this may not be a vulnerability, but it's uncertain without seeing the complete context.
---
Vulnerability Existed: not sure
Logic Error / Incomplete Refactoring - CWE-697 - admin/modules/home/index.php lines 319-325
Old Code:
```
$table->construct_cell("<strong>{$posts}</strong> {$lang->posts}<br /><strong>{$newposts}</strong> {$lang->new_today}<br /><a href=\"index.php?module=forum-moderation_queue&type=posts\"><strong>{$unapproved_posts}</strong> {$lang->unapproved}</a><br /><strong>{$reported_posts}</strong> {$lang->reported_posts}<br /><strong>{$new_reported_posts}</strong> {$lang->unread_reports}", array('width' => '25%'));
```
Fixed Code:
```
if($mybb->settings['reportmethod'] == "db")
{
$table->construct_cell("<strong>{$posts}</strong> {$lang->posts}<br /><strong>{$newposts}</strong> {$lang->new_today}<br /><a href=\"index.php?module=forum-moderation_queue&type=posts\"><strong>{$unapproved_posts}</strong> {$lang->unapproved}</a><br /><strong>{$reported_posts}</strong> {$lang->reported_posts}<br /><strong>{$new_reported_posts}</strong> {$lang->unread_reports}", array('width' => '25%'));
}
else
{
$table->construct_cell("<strong>{$posts}</strong> {$lang->posts}<br /><strong>{$newposts}</strong> {$lang->new_today}<br /><a href=\"index.php?module=forum-moderation_queue&type=posts\"><strong>{$unapproved_posts}</strong> {$lang->unapproved}</a><br /><strong>{$reported_posts}</strong> {$lang->reported_posts}", array('width' => '25%'));
}
```
Explanation:
The fix adds a conditional check that displays different content based on the report method. When the method is not "db", the unread reports line is omitted. This appears to be an intentional feature change rather than a vulnerability fix—it prevents displaying `$new_reported_posts` (which would be undefined) when the report method is not "db". However, without understanding the business logic of what "reportmethod" values are valid and how they affect report handling, it's uncertain whether this conditional logic correctly handles all cases or if there are missing scenarios.
admin/modules/home/module_meta.php
AI: 1 vulnerabilities
1 true positive
--- cache/mybb_mybb_1807/admin/modules/home/module_meta.php 2025-12-06 11:32:55.122121849 +0000+++ cache/mybb_mybb_1808/admin/modules/home/module_meta.php 2025-12-06 11:32:55.914172993 +0000@@ -24,7 +24,7 @@ $sub_menu = array(); $sub_menu['10'] = array("id" => "dashboard", "title" => $lang->dashboard, "link" => "index.php?module=home-dashboard"); $sub_menu['20'] = array("id" => "preferences", "title" => $lang->preferences, "link" => "index.php?module=home-preferences");- $sub_menu['30'] = array("id" => "docs", "title" => $lang->mybb_documentation, "link" => "http://docs.mybb.com");+ $sub_menu['30'] = array("id" => "docs", "title" => $lang->mybb_documentation, "link" => "https://docs.mybb.com"); $sub_menu['40'] = array("id" => "credits", "title" => $lang->mybb_credits, "link" => "index.php?module=home-credits"); $sub_menu = $plugins->run_hooks("admin_home_menu", $sub_menu); @@ -166,7 +166,7 @@ $class = ""; } $ip_address = my_inet_ntop($db->unescape_binary($user['ip']));- $online_users .= "<li title=\"{$lang->ipaddress} {$ip_address}\"{$class}>".build_profile_link($user['username'].' ('.$ip_address.')', $user['uid'], "_blank")."</li>";+ $online_users .= "<li title=\"{$lang->ipaddress} {$ip_address}\"{$class}>".build_profile_link(htmlspecialchars_uni($user['username']).' ('.$ip_address.')', $user['uid'], "_blank")."</li>"; $done_users["{$user['uid']}.{$user['ip']}"] = 1; } }
AI Analysis
Vulnerability Existed: yes
TRUE POSITIVE
Cross-Site Scripting (XSS) - CWE-79 - admin/modules/home/module_meta.php Line 169
Old Code:
```php
$online_users .= "<li title=\"{$lang->ipaddress} {$ip_address}\"{$class}>".build_profile_link($user['username'].' ('.$ip_address.')', $user['uid'], "_blank")."</li>";
```
Fixed Code:
```php
$online_users .= "<li title=\"{$lang->ipaddress} {$ip_address}\"{$class}>".build_profile_link(htmlspecialchars_uni($user['username']).' ('.$ip_address.')', $user['uid'], "_blank")."</li>";
```
Explanation:
The vulnerability existed because `$user['username']` was being directly concatenated into HTML output without escaping. An attacker could register a username containing malicious JavaScript (e.g., `<img src=x onerror=alert('xss')>`) and when the admin viewed the online users list, the script would execute in their browser. The fix applies `htmlspecialchars_uni()` to escape the username, converting special HTML characters to entities so they render as text rather than executable code. Note: `$ip_address` appears to already be safely processed through `my_inet_ntop()` which handles binary IP data, so it's less of a concern, but the username was the primary injection vector here.
---
Vulnerability Existed: no
Unencrypted Connection - CWE-295 - admin/modules/home/module_meta.php Line 27
Old Code:
```php
$sub_menu['30'] = array("id" => "docs", "title" => $lang->mybb_documentation, "link" => "http://docs.mybb.com");
```
Fixed Code:
```php
$sub_menu['30'] = array("id" => "docs", "title" => $lang->mybb_documentation, "link" => "https://docs.mybb.com");
```
Explanation:
While this is a security improvement, it's not fixing a vulnerability that existed in the traditional sense—it's a hardening measure. The old link used unencrypted HTTP, which could theoretically expose the connection to man-in-the-middle attacks. Changing to HTTPS (secure) is a best practice, but the vulnerability would only manifest if an attacker actively intercepted the connection. The fix ensures documentation links use encrypted HTTPS connections, protecting against passive eavesdropping and active interception attacks.
admin/modules/style/templates.php
AI: No vulnerabilities
--- cache/mybb_mybb_1807/admin/modules/style/templates.php 2025-12-06 11:32:55.122121849 +0000+++ cache/mybb_mybb_1808/admin/modules/style/templates.php 2025-12-06 11:32:55.914172993 +0000@@ -264,7 +264,7 @@ <link href="./jscripts/codemirror/addon/dialog/dialog-mybb.css" rel="stylesheet"> <script src="./jscripts/codemirror/addon/dialog/dialog.js"></script> <script src="./jscripts/codemirror/addon/search/searchcursor.js"></script>-<script src="./jscripts/codemirror/addon/search/search.js"></script>+<script src="./jscripts/codemirror/addon/search/search.js?ver=1808"></script> <script src="./jscripts/codemirror/addon/fold/foldcode.js"></script> <script src="./jscripts/codemirror/addon/fold/xml-fold.js"></script> <script src="./jscripts/codemirror/addon/fold/foldgutter.js"></script>@@ -636,7 +636,7 @@ <link href="./jscripts/codemirror/addon/dialog/dialog-mybb.css" rel="stylesheet"> <script src="./jscripts/codemirror/addon/dialog/dialog.js"></script> <script src="./jscripts/codemirror/addon/search/searchcursor.js"></script>-<script src="./jscripts/codemirror/addon/search/search.js"></script>+<script src="./jscripts/codemirror/addon/search/search.js?ver=1808"></script> <script src="./jscripts/codemirror/addon/fold/foldcode.js"></script> <script src="./jscripts/codemirror/addon/fold/xml-fold.js"></script> <script src="./jscripts/codemirror/addon/fold/foldgutter.js"></script>@@ -1176,7 +1176,7 @@ <link href="./jscripts/codemirror/addon/dialog/dialog-mybb.css" rel="stylesheet"> <script src="./jscripts/codemirror/addon/dialog/dialog.js"></script> <script src="./jscripts/codemirror/addon/search/searchcursor.js"></script>-<script src="./jscripts/codemirror/addon/search/search.js"></script>+<script src="./jscripts/codemirror/addon/search/search.js?ver=1808"></script> <script src="./jscripts/codemirror/addon/fold/foldcode.js"></script> <script src="./jscripts/codemirror/addon/fold/xml-fold.js"></script> <script src="./jscripts/codemirror/addon/fold/foldgutter.js"></script>
AI Analysis
Vulnerability Existed: no No Vulnerability - Cache Busting Parameter - File admin/modules/style/templates.php [Lines 267, 639, 1179] Old Code: ``` <script src="./jscripts/codemirror/addon/search/search.js"></script> ``` Fixed Code: ``` <script src="./jscripts/codemirror/addon/search/search.js?ver=1808"></script> ``` Explanation: This change adds a cache-busting query parameter (`?ver=1808`) to a script source URL. This is a **security hardening measure**, not a vulnerability fix. The parameter ensures browsers fetch the latest version of the script file rather than serving a cached version that may contain vulnerabilities or bugs from a previous release. Cache busting is a legitimate technique to force clients to download updated resources after version updates. By appending a version number that changes between releases, the browser's cache key differs, preventing stale code from being used. This is particularly important for security patches where outdated cached JavaScript could expose users to vulnerabilities that have been fixed in newer versions. This change improves security posture by ensuring script updates are not bypassed due to browser caching.
Showing 1 to 20 of 132 results