fix(previews): no genuine preview card for a site a deceptive link only pretends to be (#286)
CI / Build & Quality Checks (pull_request) Successful in 3m6s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 9s
CI / Playwright smoke (e2e) (pull_request) Successful in 21m16s
CI / Build & Quality Checks (pull_request) Successful in 3m6s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 9s
CI / Playwright smoke (e2e) (pull_request) Successful in 21m16s
Previews are built from the plain body, clicks follow formatted_body's hrefs, and a sender controls both: text "https://paypal.com" linked to evil.example showed a real PayPal card. Drop body URLs whose site is only claimed by the visible text of a mismatched link (linkSafety). Fixes #286 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
906a034e26
commit
7b3d1bad8f
@@ -40,6 +40,7 @@ import { parseGeoUri, scaleYDimension } from '../../utils/common';
|
||||
import { formatAccuracy } from '../../utils/geoShare';
|
||||
import { Attachment, AttachmentBox, AttachmentContent, AttachmentHeader } from './attachment';
|
||||
import { FileHeader, FileDownloadButton } from './FileHeader';
|
||||
import { previewUrlsFor } from '../../utils/linkSafety';
|
||||
|
||||
// ≈ 20 lines; in rem so a larger font setting doesn't show fewer lines (Gitea #343).
|
||||
const COLLAPSE_MAX_HEIGHT_REM = 20;
|
||||
@@ -343,7 +344,13 @@ export function MText({
|
||||
if (typeof body !== 'string') return <BrokenContent />;
|
||||
const trimmedBody = trimReplyFromBody(body);
|
||||
const urlsMatch = renderUrlsPreview && trimmedBody.match(URL_REG);
|
||||
const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined;
|
||||
// [Gitea #286] no genuine card for a site a deceptive link only pretends to be
|
||||
const urls = urlsMatch
|
||||
? previewUrlsFor(
|
||||
[...new Set(urlsMatch)],
|
||||
typeof customBody === 'string' ? customBody : undefined,
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -401,7 +408,13 @@ export function MEmote({
|
||||
if (typeof body !== 'string') return <BrokenContent />;
|
||||
const trimmedBody = trimReplyFromBody(body);
|
||||
const urlsMatch = renderUrlsPreview && trimmedBody.match(URL_REG);
|
||||
const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined;
|
||||
// [Gitea #286] no genuine card for a site a deceptive link only pretends to be
|
||||
const urls = urlsMatch
|
||||
? previewUrlsFor(
|
||||
[...new Set(urlsMatch)],
|
||||
typeof customBody === 'string' ? customBody : undefined,
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -458,7 +471,13 @@ export function MNotice({
|
||||
if (typeof body !== 'string') return <BrokenContent />;
|
||||
const trimmedBody = trimReplyFromBody(body);
|
||||
const urlsMatch = renderUrlsPreview && trimmedBody.match(URL_REG);
|
||||
const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined;
|
||||
// [Gitea #286] no genuine card for a site a deceptive link only pretends to be
|
||||
const urls = urlsMatch
|
||||
? previewUrlsFor(
|
||||
[...new Set(urlsMatch)],
|
||||
typeof customBody === 'string' ? customBody : undefined,
|
||||
)
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user