Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion 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 @@ -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 @@ -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