CVE-2024-32479 (PHP, published 2024-04-22T22:15Z)
Description: value: LibreNMS is an open-source, PHP/MySQL/SNMP-based network monitoring system. Prior to version 24.4.0, there is improper sanitization on the `Service` template name, which can lead to stored Cross-site Scripting. Version 24.4.0 fixes this vulnerability.
Severity: nan (CVSS v3 base score: )
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/librenms/librenms
Files changed:
resources/views/service-template/index.blade.php
Commit message: Fix JS injection in Service Templates (#15954)

You can't put user data in any "onwhatever" attributes, there is no way to sanitize it there.
Use data attributes instead.

Vulnerable code:
                            onclick="applyAll_st(this, '{{ route('services.templates.applyAll') }}')">
                                <button type="button" title="{{ __('Apply Services for this Service Template') }}" class="btn btn-success btn-sm" aria-label="{{ __('Apply') }}"
                                    onclick="apply_st(this, '{{ $template->name }}', '{{ $template->id }}', '{{ route('services.templates.apply', $template->id) }}')">
                                    <i class="fa fa-refresh" aria-hidden="true"></i></button>
                                <button type="button" title="{{ __('Remove Services for this Service Template') }}" class="btn btn-warning btn-sm" aria-label="{{ __('Remove') }}"
                                    onclick="remove_st(this, '{{ $template->name }}', '{{ $template->id }}', '{{ route('services.templates.remove', $template->id) }}')">
                                    <i class="fa fa-ban" aria-hidden="true"></i></button>
                                <a type="button" title="{{ __('Edit Service Template') }}" class="btn btn-primary btn-sm" aria-label="{{ __('Edit') }}"
                                    href="{{ route('services.templates.edit', $template->id) }}">
                                    <i class="fa fa-pencil" aria-hidden="true"></i></a>
                                <button type="button" class="btn btn-danger btn-sm" title="{{ __('Delete Service Template') }}" aria-label="{{ __('Delete') }}"
                                    onclick="delete_st(this, '{{ $template->name }}', '{{ $template->id }}', '{{ route('services.templates.destroy', $template->id) }}')">
                                    <i class="fa fa-trash" aria-hidden="true"></i></button>
        function apply_st(button, name, id, url) {
        function applyAll_st(button, url) {
        function remove_st(button, name, id, url) {
        function delete_st(button, name, id, url) {

Fixed code:
                            onclick="applyAll_st(this)">
                                <button type="button" title="{{ __('Apply Services for this Service Template') }}"
                                        class="btn btn-success btn-sm" aria-label="{{ __('Apply') }}"
                                        data-template-name="{{ $template->name }}"
                                        data-template-id="{{ $template->id }}"
                                        onclick="apply_st(this)">
                                    <i class="fa fa-refresh" aria-hidden="true"></i>
                                </button>
                                <button type="button" title="{{ __('Remove Services for this Service Template') }}"
                                        class="btn btn-warning btn-sm" aria-label="{{ __('Remove') }}"
                                        data-template-name="{{ $template->name }}"
                                        data-template-id="{{ $template->id }}"
                                        onclick="remove_st(this)">
                                    <i class="fa fa-ban" aria-hidden="true"></i>
                                </button>
                                <a type="button" title="{{ __('Edit Service Template') }}"
                                   class="btn btn-primary btn-sm" aria-label="{{ __('Edit') }}"
                                   href="{{ route('services.templates.edit', $template->id) }}">
                                    <i class="fa fa-pencil" aria-hidden="true"></i>
                                </a>
                                <button type="button" class="btn btn-danger btn-sm"
                                        title="{{ __('Delete Service Template') }}" aria-label="{{ __('Delete') }}"
                                        data-template-name="{{ $template->name }}"
                                        data-template-id="{{ $template->id }}"
                                        onclick="delete_st(this)">
                                    <i class="fa fa-trash" aria-hidden="true"></i>
                                </button>
        function apply_st(button) {
            var id = button.dataset.templateId;
            var name = button.dataset.templateName;
            var url = "{{ route('services.templates.apply', ':template-id') }}".replace(':template-id', id);

        function applyAll_st(button) {
            var url = "{{ route('services.templates.applyAll') }}";

        function remove_st(button) {
            var id = button.dataset.templateId;
            var name = button.dataset.templateName;
            var url = "{{ route('services.templates.remove', ':template-id') }}".replace(':template-id', id);

        function delete_st(button) {
            var id = button.dataset.templateId;
            var name = button.dataset.templateName;
            var url = "{{ route('services.templates.destroy', ':template-id') }}".replace(':template-id', id);