Navbar Plus
local_navbarplus
Local plugin that adds admin-configured Font Awesome icon links (with optional language, new-window, CSS-class and ID options) and an optional "reset user tour" icon to the Moodle header navbar via the render_navbar_output callback.
The plugin is small (one callback in lib.php, an admin settings page, a single upgrade step, a null privacy provider and Behat tests), and I found no security vulnerabilities.
- The only input is two admin-only settings, gated by
$hassiteconfig. - All rendered values go through
html_writer, which escapes attributes withs(). The icon identifier must match a strictfa-pattern, and link URLs are limited tohttp,https,mailtoor site-relative paths. That blocksjavascript:and protocol-relative URLs, even though only an administrator can enter them. - The plugin has no endpoints, database writes, file handling or outbound HTTP. Its privacy declaration is accurate.
The only finding is an info-level note about markup: an invalid alt attribute on an anchor and a hand-written icon tag. It has no security or functional impact.
Navbar Plus (local_navbarplus) is a small plugin for Moodle 5.3. One render_navbar_output callback turns an admin-configured textarea into Font Awesome icon links in the header navbar. An optional "reset user tour" icon can also be added. Besides that callback, the plugin has a settings page, one upgrade step that rewrites the stored setting, a null privacy provider and Behat step definitions.
The security posture is clean. Both settings can only be changed by site administrators. Every value printed in the navbar goes through html_writer, so attributes are escaped. The icon identifier must match a fa- pattern. URLs are parsed with \core\url and only http, https, mailto or site-relative paths are accepted, so javascript:, data: and protocol-relative URLs are rejected. There are no endpoints, form handlers, database queries, file operations or outbound requests.
The only finding is an info-level note on the reset-tour link: it sets an invalid alt attribute on an anchor and builds its icon as raw HTML. Neither affects security or behaviour, and no action is needed.
Findings
The reset-user-tour link sets an alt attribute on an <a> element, which is not a valid attribute for anchors. Browsers and assistive technology ignore it, so it does nothing. The <i> icon is a hard-coded HTML string. Unlike the configured icons a few lines above, it has no aria-hidden and does not go through html_writer. The link still gets its accessible name from title, so this is only a markup and consistency issue. The function also declares global $OUTPUT; but never uses it.
No risk. All strings are static or come from language packs, and nothing in them is user-controlled. This is a markup and accessibility tidy-up only.
local_navbarplus_render_navbar_output() runs on every page render. When the resetusertours setting is on, a logged-in non-guest user is on the page and a user tour matches it, the function appends a link with the id resetpagetour, which core's tool_usertours JavaScript listens for.
$itemicon = '<i class="icon fa fa-map fa-fw"></i>';
$itemicon = html_writer::tag('i', '', ['class' => 'icon fa fa-map fa-fw', 'aria-hidden' => 'true']);
$attributes = ['alt' => $resetstring, 'title' => $resetstring . ' ' . $resethint,
'id' => 'resetpagetour', ];
$attributes = ['aria-label' => $resetstring, 'title' => $resetstring . ' ' . $resethint,
'id' => 'resetpagetour', ];
Admin-only input with careful URL handling. The inserticonswithlinks textarea is stored as PARAM_RAW, but only site administrators can edit it. On output, every value is escaped by html_writer::attribute() through s(). The URL scheme allow-list in lib.php also handles the case where javascript:1/alert(1) is parsed as a host and port by rejecting any URL that has a host but no scheme.