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
4 changes: 2 additions & 2 deletions extension/chrome/elements/attachment.ts
Comment thread
martgil marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export class AttachmentDownloadView extends View {
Failed to decrypt.
<details ${this.errorDetailsOpened ? 'open' : ''}>
<summary>see error details</summary>
<pre data-test="error-details">${e.stack}\n\nDecryptError:\n${JSON.stringify(e.decryptError, undefined, 2)}</pre>
<pre data-test="error-details">${Xss.escape(String(e.stack ?? e))}\n\nDecryptError:\n${Xss.escape(JSON.stringify(e.decryptError, undefined, 2))}</pre>
</details>
`
);
Expand All @@ -195,7 +195,7 @@ export class AttachmentDownloadView extends View {

private renderHeader = () => {
const span = $(`<span>${this.isEncrypted ? 'ENCRYPTED\n' : 'PLAIN\n'} FILE</span>`);
this.header.empty().append(span); // xss-escaped
this.header.empty().append(span); // xss-direct
};

private getFileIconSrc = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,11 @@ export class ComposeQuoteModule extends ViewModule<ComposeView> {
const header =
`<div ${dirAttr}>` +
`---------- Forwarded message ---------<br/>` +
`From: ${from}<br>` +
`Date: ${dateStr}<br>` +
`Subject: ${this.messageToReplyOrForward.headers.subject}<br>` +
`To: ${this.messageToReplyOrForward.headers.to.join(', ')}<br>` +
(this.messageToReplyOrForward.headers.cc?.length ? `Cc: ${this.messageToReplyOrForward.headers.cc?.join(', ')}` : '') +
`From: ${Xss.escape(from || '')}<br>` +
`Date: ${Xss.escape(dateStr)}<br>` +
Comment thread
martgil marked this conversation as resolved.
`Subject: ${Xss.escape(this.messageToReplyOrForward.headers.subject || '')}<br>` +
`To: ${Xss.escape(this.messageToReplyOrForward.headers.to.join(', '))}<br>` +
(this.messageToReplyOrForward.headers.cc?.length ? `Cc: ${Xss.escape(this.messageToReplyOrForward.headers.cc.join(', '))}` : '') +
`</div>`;
return `${header}<br><br>${escapedText}`;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ export class ComposeRecipientsModule extends ViewModule<ComposeView> {
ulHtml += '<img class="loading-icon" data-test="pgp-loading-icon" src="/img/svgs/spinner-green-small.svg" />';
contact.pgpLoading
.then(hasPgp => {
Xss.replaceElementDANGEROUSLY($(`[email="${contact.email}"] .loading-icon`)[0], this.getPgpIconHtml(hasPgp)); // xss-escaped
Xss.replaceElementDANGEROUSLY($(`[email="${contact.email}"] .loading-icon`)[0], this.getPgpIconHtml(hasPgp)); // xss-direct
})
.catch(() => {
this.failedLookupEmails.push(contact.email);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class PgpBlockViewPrintModule {
html = policy.createHTML(html);
}
if (w?.document?.body) {
w.document.body.innerHTML = html; // xss-escaped
w.document.body.innerHTML = html; // xss-reinsert
}
// Give some time for above dom to load in print dialog
// https://stackoverflow.com/questions/31725373/google-chrome-not-showing-image-in-print-preview
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ export class InboxActiveThreadModule extends ViewModule<InboxView> {
}
const exportBtn = this.debugEmails.includes(this.view.acctEmail) ? '<a href="#" class="action-export">download api export</a>' : '';
const r =
`<p class="message_header" data-test="container-msg-header">From: ${Xss.escape(messageInfo.from?.full || 'unknown')} <span style="float:right;">${
`<p class="message_header" data-test="container-msg-header">From: ${Xss.escape(messageInfo.from?.full || 'unknown')} <span style="float:right;">${Xss.escape(
GmailParser.findHeader(msg, 'Date') ?? ''
} ${exportBtn}</p>` + // xss-direct
)} ${exportBtn}</p>` + // xss-direct
loaderContext.getRenderedMessageXssSafe() +
loaderContext.getRenderedAttachmentsXssSafe();
$('.thread').append(this.wrapMsg(htmlId, r)); // xss-safe-value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
'use strict';

import { Catch } from '../../../../js/common/platform/catch.js';
import { Dict } from '../../../../js/common/core/common.js';
import { checkValidURL, Dict } from '../../../../js/common/core/common.js';
import { GmailRes } from '../../../../js/common/api/email-provider/gmail/gmail-parser.js';
import { Google } from '../../../../js/common/api/email-provider/gmail/google.js';
import { InboxView } from '../inbox.js';
Expand Down Expand Up @@ -122,7 +122,7 @@ export class InboxMenuModule extends ViewModule<InboxView> {
if (chooseAccountEl) {
chooseAccountEl.title = this.view.acctEmail;
}
if (this.view.picture) {
if (this.view.picture && checkValidURL(this.view.picture)) {
$('img.main-profile-img')
.attr('src', this.view.picture)
.on(
Expand Down
4 changes: 2 additions & 2 deletions extension/chrome/settings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { Bm, BrowserMsg } from '../../js/common/browser/browser-msg.js';
import { Ui } from '../../js/common/browser/ui.js';
import { KeyUtil, KeyInfoWithIdentity } from '../../js/common/core/crypto/key.js';
import { Str, Url, UrlParams } from '../../js/common/core/common.js';
import { checkValidURL, Str, Url, UrlParams } from '../../js/common/core/common.js';
import { ApiErr, EnterpriseServerAuthErr } from '../../js/common/api/shared/api-error.js';
import { Assert } from '../../js/common/assert.js';

Expand Down Expand Up @@ -300,7 +300,7 @@ View.run(
}
this.checkGoogleAcct().catch(Catch.reportErr);
this.checkFcAcctAndContactPage().catch(Catch.reportErr);
if (storage.picture) {
if (storage.picture && checkValidURL(storage.picture)) {
$('img.main-profile-img')
.attr('src', storage.picture)
.on(
Expand Down
2 changes: 1 addition & 1 deletion extension/js/common/ui/key-import-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export class KeyImportUi {
for (const option of ['generate_private_key', 'submit_pubkey']) {
const dataTestValue = `input-email-alias-${option}-${e.replace(/[^a-z0-9]+/g, '')}`;
$(`.${option}_addresses`).append(
`<label><input type="checkbox" class="input_email_alias_${option}" data-email="${Xss.escape(e)}" data-name="${sendAs?.[e].name ?? ''}" data-test="${dataTestValue}" />${Xss.escape(e)}</label><br/>`
`<label><input type="checkbox" class="input_email_alias_${option}" data-email="${Xss.escape(e)}" data-name="${Xss.escape(sendAs?.[e].name ?? '')}" data-test="${dataTestValue}" />${Xss.escape(e)}</label><br/>`
); // xss-escaped
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class ThunderbirdElementReplacer extends WebmailElementReplacer {
}
}
const pgpBlock = this.generatePgpBlockTemplate(encryptionStatus, verificationStatus, decryptedMsg);
$('body').html(pgpBlock); // xss-sanitized
$('body').html(pgpBlock); // xss-escaped
} else {
const decryptErr = result as DecryptError;
let decryptionErrorMsg = '';
Expand All @@ -68,7 +68,7 @@ export class ThunderbirdElementReplacer extends WebmailElementReplacer {
decryptionErrorMsg = `decrypt error: ${(result as DecryptError).error.message}`;
}
const pgpBlock = this.generatePgpBlockTemplate(decryptionErrorMsg, 'not signed', this.emailBodyFromThunderbirdMail);
$('body').html(pgpBlock); // xss-sanitized
$('body').html(pgpBlock); // xss-escaped
}
} else if (this.isCleartextMsg(fullMsg)) {
const message = await openpgp.readCleartextMessage({ cleartextMessage: this.emailBodyFromThunderbirdMail });
Expand All @@ -82,7 +82,7 @@ export class ThunderbirdElementReplacer extends WebmailElementReplacer {
verificationStatus = `could not verify signature: ${result.error}`;
}
const pgpBlock = this.generatePgpBlockTemplate('not encrypted', verificationStatus, signedMessage);
$('body').html(pgpBlock); // xss-sanitized
$('body').html(pgpBlock); // xss-escaped
}
// todo: detached signed message via https://github.com/FlowCrypt/flowcrypt-browser/issues/5668
}
Expand All @@ -93,8 +93,8 @@ export class ThunderbirdElementReplacer extends WebmailElementReplacer {
return `
<div ${encryptionStatus === 'encrypted' ? 'class="pgp_secure"' : 'class="pgp_neutral"'}>
<div>
<div id="pgp_encryption" class="pgp_badge short ${encryptionStatus === 'encrypted' ? 'green_label' : 'red_label'}">${encryptionStatus}</div>
<div id="pgp_signature" class="pgp_badge short ${verificationStatus === 'signed' ? 'green_label' : 'red_label'}">${verificationStatus}</div>
<div id="pgp_encryption" class="pgp_badge short ${encryptionStatus === 'encrypted' ? 'green_label' : 'red_label'}">${Xss.escape(encryptionStatus)}</div>
<div id="pgp_signature" class="pgp_badge short ${verificationStatus === 'signed' ? 'green_label' : 'red_label'}">${Xss.escape(verificationStatus)}</div>
</div>
<div class="pgp_block">
<pre>${Xss.escape(messageToRender)}</pre>
Expand Down
Loading