security: verify relay events and stop image referrer leaks
This commit is contained in:
parent
b180d136c3
commit
7b2fd3993a
5 changed files with 8 additions and 4 deletions
|
|
@ -14,7 +14,7 @@
|
||||||
Content-Security-Policy = "default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' https://fonts.gstatic.com data:; connect-src 'self' https: wss:; media-src 'self' blob: https:; frame-src 'self' https:; worker-src 'self' blob:; manifest-src 'self'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests"
|
Content-Security-Policy = "default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' https://fonts.gstatic.com data:; connect-src 'self' https: wss:; media-src 'self' blob: https:; frame-src 'self' https:; worker-src 'self' blob:; manifest-src 'self'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests"
|
||||||
X-Frame-Options = "DENY"
|
X-Frame-Options = "DENY"
|
||||||
X-Content-Type-Options = "nosniff"
|
X-Content-Type-Options = "nosniff"
|
||||||
Referrer-Policy = "strict-origin-when-cross-origin"
|
Referrer-Policy = "no-referrer"
|
||||||
Permissions-Policy = "geolocation=(self), camera=(self), microphone=()"
|
Permissions-Policy = "geolocation=(self), camera=(self), microphone=()"
|
||||||
|
|
||||||
[[headers]]
|
[[headers]]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
Content-Security-Policy: default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' https://fonts.gstatic.com data:; connect-src 'self' https: wss:; media-src 'self' blob: https:; frame-src 'self' https:; worker-src 'self' blob:; manifest-src 'self'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests
|
Content-Security-Policy: default-src 'none'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self' https://fonts.gstatic.com data:; connect-src 'self' https: wss:; media-src 'self' blob: https:; frame-src 'self' https:; worker-src 'self' blob:; manifest-src 'self'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'; upgrade-insecure-requests
|
||||||
X-Content-Type-Options: nosniff
|
X-Content-Type-Options: nosniff
|
||||||
X-Frame-Options: DENY
|
X-Frame-Options: DENY
|
||||||
Referrer-Policy: strict-origin-when-cross-origin
|
Referrer-Policy: no-referrer
|
||||||
Permissions-Policy: geolocation=(self), camera=(self), microphone=()
|
Permissions-Policy: geolocation=(self), camera=(self), microphone=()
|
||||||
|
|
||||||
# Cache the proxied mint directory so we don't hammer the rate-limited API.
|
# Cache the proxied mint directory so we don't hammer the rate-limited API.
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ export function ImageWithFallback({
|
||||||
onError,
|
onError,
|
||||||
loading = 'lazy',
|
loading = 'lazy',
|
||||||
decoding = 'async',
|
decoding = 'async',
|
||||||
|
referrerPolicy = 'no-referrer',
|
||||||
...props
|
...props
|
||||||
}: ImageWithFallbackProps) {
|
}: ImageWithFallbackProps) {
|
||||||
const candidates = useMemo(() => imageCandidates(src), [src]);
|
const candidates = useMemo(() => imageCandidates(src), [src]);
|
||||||
|
|
@ -67,6 +68,7 @@ export function ImageWithFallback({
|
||||||
className={className}
|
className={className}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
decoding={decoding}
|
decoding={decoding}
|
||||||
|
referrerPolicy={referrerPolicy}
|
||||||
onError={(event) => {
|
onError={(event) => {
|
||||||
if (index + 1 < candidates.length) {
|
if (index + 1 < candidates.length) {
|
||||||
setIndex(index + 1);
|
setIndex(index + 1);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ const AvatarImage = React.forwardRef<
|
||||||
<AvatarPrimitive.Image
|
<AvatarPrimitive.Image
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn("aspect-square h-full w-full object-cover", className)}
|
className={cn("aspect-square h-full w-full object-cover", className)}
|
||||||
|
referrerPolicy="no-referrer"
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { useCitrine } from '@/hooks/useCitrine';
|
||||||
import { SKATE_RELAY } from '@/lib/types';
|
import { SKATE_RELAY } from '@/lib/types';
|
||||||
import { mergeEvents } from '@/lib/eventMerge';
|
import { mergeEvents } from '@/lib/eventMerge';
|
||||||
import { getLocalDeletions } from '@/lib/localDeletions';
|
import { getLocalDeletions } from '@/lib/localDeletions';
|
||||||
|
import { onlyVerified } from '@/lib/verifyEvents';
|
||||||
import type { NostrEvent, NostrFilter } from '@nostrify/nostrify';
|
import type { NostrEvent, NostrFilter } from '@nostrify/nostrify';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -139,7 +140,7 @@ export function useSkateRelays() {
|
||||||
throw new Error('No relay could be reached');
|
throw new Error('No relay could be reached');
|
||||||
}
|
}
|
||||||
|
|
||||||
const allEvents = results.flat();
|
const allEvents = onlyVerified(results.flat());
|
||||||
|
|
||||||
return dedupeEvents(allEvents);
|
return dedupeEvents(allEvents);
|
||||||
};
|
};
|
||||||
|
|
@ -161,7 +162,7 @@ export function useSkateRelays() {
|
||||||
const relay = nostr.relay(SKATE_RELAY);
|
const relay = nostr.relay(SKATE_RELAY);
|
||||||
const events = await relay.query(filters, { signal: options.signal });
|
const events = await relay.query(filters, { signal: options.signal });
|
||||||
|
|
||||||
return dedupeEvents(events);
|
return dedupeEvents(onlyVerified(events));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// See querySkateContent: an outage must not look like "empty".
|
// See querySkateContent: an outage must not look like "empty".
|
||||||
options.onError?.();
|
options.onError?.();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue