mirror of
https://github.com/svm0n/datadeck.git
synced 2026-07-22 08:31:46 +00:00
fix(security): stop rendering CSV cell values via unescaped innerHTML
renderLibrary and renderTasks built their collapsible section headers
with `summary.innerHTML = \`...${genre}...\`` / `...${project}...` —
genre/project come straight from a CSV cell, so a value like
`<img src=x onerror=...>` would execute as markup instead of rendering
as text. Obsidian's plugin review flags raw innerHTML with dynamic
content for exactly this reason. Switched both to createSpan/text,
matching every other render call in the codebase. Layout is unaffected
(both headers are flex containers, so the plain text node between the
two spans was already an anonymous flex item — now it's a real span,
same visual result). Tests: 115 + 112 passed, typecheck clean.
This commit is contained in:
parent
4faff4588e
commit
ccfa983b82
3 changed files with 18 additions and 14 deletions
24
main.js
24
main.js
File diff suppressed because one or more lines are too long
|
|
@ -196,7 +196,9 @@ export function renderLibrary(view: CardView, container: HTMLElement): void {
|
|||
});
|
||||
|
||||
const summary = section.createEl("summary", { cls: "csv-library-section-header" });
|
||||
summary.innerHTML = `<span class="csv-library-arrow">▶</span> ${genre} <span class="csv-library-count">${items.length}</span>`;
|
||||
summary.createSpan({ cls: "csv-library-arrow", text: "▶" });
|
||||
summary.createSpan({ text: ` ${genre} ` });
|
||||
summary.createSpan({ cls: "csv-library-count", text: String(items.length) });
|
||||
|
||||
const grid = section.createDiv({ cls: "csv-library-grid" });
|
||||
|
||||
|
|
|
|||
|
|
@ -314,7 +314,9 @@ function renderSection(
|
|||
const details = section.createEl("details", { cls: "csv-tasks-group" });
|
||||
details.open = true;
|
||||
const summary = details.createEl("summary", { cls: "csv-tasks-group-header" });
|
||||
summary.innerHTML = `<span class="csv-tasks-arrow">▶</span> ${project} <span class="csv-tasks-count">${items.length}</span>`;
|
||||
summary.createSpan({ cls: "csv-tasks-arrow", text: "▶" });
|
||||
summary.createSpan({ text: ` ${project} ` });
|
||||
summary.createSpan({ cls: "csv-tasks-count", text: String(items.length) });
|
||||
const wrapper = details.createDiv({ cls: "csv-tasks-table-wrapper" });
|
||||
const table = wrapper.createEl("table", { cls: "csv-tasks-table" });
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue