Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions web/guac/templates/guac/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@
<div id="terminal"></div>
<div id="launch_error" style="display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1002;max-width:440px;width:100%;">
<div style="background:#212529;border:1px solid #495057;border-radius:8px;padding:20px;box-shadow:0 0 30px rgba(0,0,0,0.8);color:#fff;">
<h6 id="dialog-heading" class="mb-2" style="color:#fff;"><i class="fas fa-exclamation-triangle me-1 text-danger"></i>Session Error</h6>
<p class="message mb-1 small" style="color:#adb5bd;"></p>
<p class="error_msg mb-2 small" style="color:#6c757d;"></p>
<h6 id="dialog-heading" class="mb-2" style="color:#fff;">Session Ended</h6>
<p id="dialog-message" class="mb-2 small" style="color:#6c757d;"></p>
<a id="taskStatus" href="/submit/status/{{ task_id }}/" class="btn btn-sm btn-outline-light"><i class="fas fa-tasks me-1"></i>View Task</a>
</div>
</div>
Expand Down
28 changes: 22 additions & 6 deletions web/static/js/guac-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const PASTE_DELAY_MS = 50;

const NON_FATAL_STATUS_CODES = new Set([0, 256]);

const ICON_ERROR = 'fas fa-exclamation-circle text-danger';
const ICON_WARNING = 'fas fa-exclamation-triangle text-warning';
const ICON_SUCCESS = 'fas fa-check-circle text-success';

class GuacSession {
constructor(element, config) {
this.config = config;
Expand Down Expand Up @@ -153,14 +157,27 @@ class GuacSession {
});
}

_showError(title, detail) {
_showDialog(title, detail, icon) {
const dialog = $('#launch_error');
dialog.find('.message').html(title);
dialog.find('.error_msg').html(detail);
const iconHtml = icon ? `<i class="${icon} me-1"></i>` : '';
dialog.find('#dialog-heading').html(`${iconHtml}${title}`);
dialog.find('#dialog-message').html(detail);
Comment on lines +163 to +164
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

Using .html() to inject title and detail can lead to Cross-Site Scripting (XSS) vulnerabilities. This is particularly concerning for the detail parameter, which can contain error messages originating from the server (e.g., via the Guacamole protocol). It is safer to use .text() for text content. For the heading, you can set the icon HTML and then append the title as a text node to ensure any malicious characters in the title are not executed.

Suggested change
dialog.find('#dialog-heading').html(`${iconHtml}${title}`);
dialog.find('#dialog-message').html(detail);
dialog.find('#dialog-heading').html(iconHtml).append(document.createTextNode(title));
dialog.find('#dialog-message').text(detail);

dialog.dialog({ dialogClass: 'no-close' });
dialog.dialog(this.dialogContainer);
}

_showError(title, detail) {
this._showDialog(title, detail, ICON_ERROR);
}

_showWarning(title, detail) {
this._showDialog(title, detail, ICON_WARNING);
}

_showSuccess(title, detail) {
this._showDialog(title, detail, ICON_SUCCESS);
}

_setupErrorHandler() {
const handler = (error) => {
console.log(`guac error ${error.code}: ${error.message}`);
Expand All @@ -174,9 +191,9 @@ class GuacSession {
if (error.code === 514) {
this._showError("Connection error", "Server timeout.");
} else if (error.code === 515) {
this._showError("Session complete", "Backing VM has disconnected.");
this._showSuccess("Session complete", "Backing VM has disconnected.");
} else if (error.code === 522) {
this._showError("Session ended", "Session timed out due to inactivity.");
this._showWarning("Session ended", "Session timed out due to inactivity.");
} else {
const _msg = `An unexpected error occurred: ${error.message}`;
this._showError("Connection error", _msg);
Expand Down Expand Up @@ -228,7 +245,6 @@ function stopTask(taskId, onSuccess, onError) {

const apiUrl = location.origin + "/apiv2/tasks/status/" + taskId + "/";

var apiUrl = location.origin + "/apiv2/tasks/status/" + taskId + "/";
fetch(apiUrl, {
method: 'POST',
headers: {
Expand Down
Loading