diff --git a/packages/loot-core/src/mocks/files/html-vals.qfx b/packages/loot-core/src/mocks/files/html-vals.qfx
new file mode 100644
index 0000000000000000000000000000000000000000..0e3b2a5a2e01d214f8927e38349a5665b702af5c
--- /dev/null
+++ b/packages/loot-core/src/mocks/files/html-vals.qfx
@@ -0,0 +1,17 @@
+OFXHEADER:100
+DATA:OFXSGML
+VERSION:102
+SECURITY:NONE
+ENCODING:USASCII
+CHARSET:1252
+COMPRESSION:NONE
+OLDFILEUID:NONE
+NEWFILEUID:NONE
+
+<OFX><SIGNONMSGSRSV1><SONRS><STATUS><CODE>0<SEVERITY>INFO<MESSAGE>OK</STATUS><DTSERVER>20231106023518<LANGUAGE>ENG<DTPROFUP>20231106023518<DTACCTUP>20231106023518<INTU.BID>00005</SONRS></SIGNONMSGSRSV1>
+<BANKMSGSRSV1><STMTTRNRS><TRNUID>20231106023518<STATUS><CODE>0<SEVERITY>INFO<MESSAGE>OK</STATUS>
+<STMTRS><CURDEF>CAD<BANKACCTFROM><BANKID>000000000<ACCTID>00000 00-00000<ACCTTYPE>CHECKING</BANKACCTFROM>
+<BANKTRANLIST><DTSTART>20190731120000<DTEND>20231031120000
+<STMTTRN><TRNTYPE>DEBIT<DTPOSTED>20230509120000.000[-5:EST]<TRNAMT>-1.00<FITID>23129130032333396279270000<NAME>000000000000000<MEMO>PREAUTHORIZED DEBIT;B.C. HYDRO &amp; POWER AUTHORITY;Electronic Funds Transfer</STMTTRN>
+<STMTTRN><TRNTYPE>DEBIT<DTPOSTED>20230301120000.000[-5:EST]<TRNAMT>-1.00<FITID>23060061032549554596530000<NAME>TPAY &amp;lt;DEFTPYMT&amp;gt;<MEMO>PREAUTHORIZED DEBIT;LUXMORE REALTY PPTY MGMT;Electronic Funds Transfer</STMTTRN>
+</BANKTRANLIST><LEDGERBAL><BALAMT>1111.11<DTASOF>20231106023518</LEDGERBAL><AVAILBAL><BALAMT>1111.11<DTASOF>20231106023518</AVAILBAL></STMTRS></STMTTRNRS></BANKMSGSRSV1></OFX>
diff --git a/packages/loot-core/src/server/accounts/__snapshots__/parse-file.test.ts.snap b/packages/loot-core/src/server/accounts/__snapshots__/parse-file.test.ts.snap
index 72b569a02516bc3b90f3ec301dd0b6b76b5dcad1..5e325d19b8e547c564e236d804b4534754d898f9 100644
--- a/packages/loot-core/src/server/accounts/__snapshots__/parse-file.test.ts.snap
+++ b/packages/loot-core/src/server/accounts/__snapshots__/parse-file.test.ts.snap
@@ -1,5 +1,60 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`File import handles html escaped plaintext 1`] = `
+Array [
+  Object {
+    "acct": "one",
+    "amount": -100,
+    "category": null,
+    "cleared": 1,
+    "date": 20230509,
+    "description": "id2",
+    "error": null,
+    "financial_id": "23129130032333396279270000",
+    "id": "id4",
+    "imported_description": "000000000000000",
+    "isChild": 0,
+    "isParent": 0,
+    "location": null,
+    "notes": "PREAUTHORIZED DEBIT;B.C. HYDRO & POWER AUTHORITY;Electronic Funds Transfer",
+    "parent_id": null,
+    "pending": 0,
+    "reconciled": 0,
+    "schedule": null,
+    "sort_order": 123456789,
+    "starting_balance_flag": 0,
+    "tombstone": 0,
+    "transferred_id": null,
+    "type": null,
+  },
+  Object {
+    "acct": "one",
+    "amount": -100,
+    "category": null,
+    "cleared": 1,
+    "date": 20230301,
+    "description": "id3",
+    "error": null,
+    "financial_id": "23060061032549554596530000",
+    "id": "id5",
+    "imported_description": "TPAY <DEFTPYMT>",
+    "isChild": 0,
+    "isParent": 0,
+    "location": null,
+    "notes": "PREAUTHORIZED DEBIT;LUXMORE REALTY PPTY MGMT;Electronic Funds Transfer",
+    "parent_id": null,
+    "pending": 0,
+    "reconciled": 0,
+    "schedule": null,
+    "sort_order": 123456789,
+    "starting_balance_flag": 0,
+    "tombstone": 0,
+    "transferred_id": null,
+    "type": null,
+  },
+]
+`;
+
 exports[`File import handles non-ASCII characters 1`] = `
 Array [
   Object {
diff --git a/packages/loot-core/src/server/accounts/ofx2json.ts b/packages/loot-core/src/server/accounts/ofx2json.ts
index 91e1f50b4e1682722d5a45f43265c07c8a2d7e83..b5ad38faa88823a9eccd6e386b05b873a2a9e04d 100644
--- a/packages/loot-core/src/server/accounts/ofx2json.ts
+++ b/packages/loot-core/src/server/accounts/ofx2json.ts
@@ -29,6 +29,16 @@ function sgml2Xml(sgml) {
     .replace(/<\/<added>(\w+?)>(<\/\1>)?/g, '</$1>'); // Remove duplicate end-tags
 }
 
+function html2Plain(value) {
+  return value
+    ?.replace(/&amp;/g, '&') // ampersands
+    .replace(/&#038;/g, '&') // other ampersands
+    .replace(/&lt;/g, '<') // lessthan
+    .replace(/&gt;/g, '>') // greaterthan
+    .replace(/&#39;/g, "'") // eslint-disable-line rulesdir/typography
+    .replace(/&quot;/g, '"'); // eslint-disable-line rulesdir/typography
+}
+
 async function parseXml(content) {
   return await parseStringPromise(content, { explicitArray: false });
 }
@@ -106,8 +116,8 @@ function mapOfxTransaction(stmtTrn): OFXTransaction {
     type: stmtTrn['TRNTYPE'],
     fitId: stmtTrn['FITID'],
     date: dayFromDate(transactionDate),
-    name: stmtTrn['NAME'],
-    memo: stmtTrn['MEMO'],
+    name: html2Plain(stmtTrn['NAME']),
+    memo: html2Plain(stmtTrn['MEMO']),
   };
 }
 
diff --git a/packages/loot-core/src/server/accounts/parse-file.test.ts b/packages/loot-core/src/server/accounts/parse-file.test.ts
index 95bcf6fff059f56c7831e658d44c30a5b869375b..edd472d2ab0eb2c022533a19f7c25480b4519a54 100644
--- a/packages/loot-core/src/server/accounts/parse-file.test.ts
+++ b/packages/loot-core/src/server/accounts/parse-file.test.ts
@@ -142,4 +142,17 @@ describe('File import', () => {
     expect(errors.length).toBe(0);
     expect(await getTransactions('one')).toMatchSnapshot();
   });
+
+  test('handles html escaped plaintext', async () => {
+    prefs.loadPrefs();
+    await db.insertAccount({ id: 'one', name: 'one' });
+
+    const { errors } = await importFileWithRealTime(
+      'one',
+      __dirname + '/../../mocks/files/html-vals.qfx',
+      'yyyy-MM-dd',
+    );
+    expect(errors.length).toBe(0);
+    expect(await getTransactions('one')).toMatchSnapshot();
+  });
 });
diff --git a/upcoming-release-notes/2364.md b/upcoming-release-notes/2364.md
new file mode 100644
index 0000000000000000000000000000000000000000..92b4ecb8045c362227e896ee734632340fcba1fb
--- /dev/null
+++ b/upcoming-release-notes/2364.md
@@ -0,0 +1,6 @@
+---
+category: Bugfix
+authors: [twk3]
+---
+
+Convert html special characters in ofx imports to plaintext.