forked from FoundKeyGang/FoundKey
security: check schema for URL previews
Changelog: Fixed
This commit is contained in:
parent
48fd543d0f
commit
27b912b9b0
3 changed files with 19 additions and 9 deletions
|
@ -38,6 +38,14 @@ export const urlPreviewHandler = async (ctx: Koa.Context): Promise<void> => {
|
||||||
|
|
||||||
logger.succ(`Got preview of ${url}: ${summary.title}`);
|
logger.succ(`Got preview of ${url}: ${summary.title}`);
|
||||||
|
|
||||||
|
if (summary.url && !(summary.url.startsWith('http://') || summary.url.startsWith('https://'))) {
|
||||||
|
throw new Error('unsupported schema included');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (summary.player?.url && !(summary.player.url.startsWith('http://') || summary.player.url.startsWith('https://'))) {
|
||||||
|
throw new Error('unsupported schema included');
|
||||||
|
}
|
||||||
|
|
||||||
summary.icon = wrap(summary.icon);
|
summary.icon = wrap(summary.icon);
|
||||||
summary.thumbnail = wrap(summary.thumbnail);
|
summary.thumbnail = wrap(summary.thumbnail);
|
||||||
|
|
||||||
|
@ -54,12 +62,10 @@ export const urlPreviewHandler = async (ctx: Koa.Context): Promise<void> => {
|
||||||
};
|
};
|
||||||
|
|
||||||
function wrap(url?: string): string | null {
|
function wrap(url?: string): string | null {
|
||||||
return url != null
|
if (url == null) return null;
|
||||||
? url.match(/^https?:\/\//)
|
if (!['http:', 'https:'].includes(new URL(url).protocol)) return null;
|
||||||
? `${config.url}/proxy/preview.webp?${query({
|
return config.url + '/proxy/preview.webp?' + query({
|
||||||
url,
|
url,
|
||||||
preview: '1',
|
preview: '1',
|
||||||
})}`
|
});
|
||||||
: url
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ const props = withDefaults(defineProps<{
|
||||||
|
|
||||||
const self = props.url.startsWith(local);
|
const self = props.url.startsWith(local);
|
||||||
const uri = new URL(props.url);
|
const uri = new URL(props.url);
|
||||||
|
if (!['http:', 'https:'].includes(url.protocol)) throw new Error('invalid url');
|
||||||
let el: HTMLElement | null = $ref(null);
|
let el: HTMLElement | null = $ref(null);
|
||||||
|
|
||||||
let schema = $ref(uri.protocol);
|
let schema = $ref(uri.protocol);
|
||||||
|
|
|
@ -54,6 +54,7 @@ let player = $ref({
|
||||||
let playerEnabled = $ref(false);
|
let playerEnabled = $ref(false);
|
||||||
|
|
||||||
const requestUrl = new URL(props.url);
|
const requestUrl = new URL(props.url);
|
||||||
|
if(!['http:', 'https:].includes(requestUrl.protocol)) throw new Error('invalid url');
|
||||||
|
|
||||||
if (requestUrl.hostname === 'music.youtube.com' && requestUrl.pathname.match('^/(?:watch|channel)')) {
|
if (requestUrl.hostname === 'music.youtube.com' && requestUrl.pathname.match('^/(?:watch|channel)')) {
|
||||||
requestUrl.hostname = 'www.youtube.com';
|
requestUrl.hostname = 'www.youtube.com';
|
||||||
|
@ -72,7 +73,9 @@ fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${requestLang}`).the
|
||||||
icon = info.icon;
|
icon = info.icon;
|
||||||
sitename = info.sitename;
|
sitename = info.sitename;
|
||||||
fetching = false;
|
fetching = false;
|
||||||
player = info.player;
|
if (['http:', 'https:'].includes(new URL(info.player.url).protocol)) {
|
||||||
|
player = info.player;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in a new issue