fix(security): safe links and security headers (FLAW-28, FLAW-29)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m48s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m48s
safeHref lets only http, https and mailto become links (Markdown viewer, outliner, legal links); javascript: and friends show as text. A middleware sets a Content-Security-Policy (scripts only from MindSift, no framing, connections only to this server), X-Frame-Options, nosniff, Referrer-Policy and a Permissions-Policy. The two inline scripts of index.html moved to files so script-src stays 'self'. The second inline script also deleted every cache on each page load, which undermined the offline start; it is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3ca4ff7bce
commit
b2ecda9896
13 files changed
+175
-28
No files matched your search
@@ -25,6 +25,7 @@ import { DocumentBlock, BlockType } from '../../lib/types';
|
||||
import { LinkModal } from './LinkModal';
|
||||
import { renderInlineMarkdown } from '../../lib/markdown';
|
||||
import { api } from '../../lib/api';
|
||||
import { safeHref } from '../../lib/safeUrl';
|
||||
|
||||
export interface SlashCommand {
|
||||
type: BlockType | 'link';
|
||||
@@ -1001,9 +1002,9 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
|
||||
);
|
||||
}
|
||||
const mdMatch = part.match(/^\[(.*?)\]\((https?:\/\/.*?)\)$/);
|
||||
if (mdMatch) {
|
||||
if (mdMatch && safeHref(mdMatch[2])) {
|
||||
const label = mdMatch[1];
|
||||
const url = mdMatch[2];
|
||||
const url = safeHref(mdMatch[2]) as string;
|
||||
return (
|
||||
<a
|
||||
key={idx}
|
||||
@@ -1018,11 +1019,11 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
|
||||
</a>
|
||||
);
|
||||
}
|
||||
if (/^https?:\/\//.test(part)) {
|
||||
if (/^https?:\/\//.test(part) && safeHref(part)) {
|
||||
return (
|
||||
<a
|
||||
key={idx}
|
||||
href={part}
|
||||
href={safeHref(part) as string}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[10px] font-medium text-status-ok bg-status-ok/10 hover:bg-status-ok/20 rounded-btn transition-colors"
|
||||
|
||||
Reference in new issue
Block a user