Merge pull request 'fix/security' (#9600) from fix/security into develop
Reviewed-on: https://codeberg.org/calckey/calckey/pulls/9600
This commit is contained in:
commit
d1dda3a178
|
@ -111,6 +111,16 @@ export async function createNote(
|
|||
|
||||
const note: IPost = object;
|
||||
|
||||
if (note.id && !note.id.startsWith('https://')) {
|
||||
throw new Error(`unexpected shcema of note.id: ${note.id}`);
|
||||
}
|
||||
|
||||
const url = getOneApHrefNullable(note.url);
|
||||
|
||||
if (url && !url.startsWith('https://')) {
|
||||
throw new Error(`unexpected shcema of note url: ${url}`);
|
||||
}
|
||||
|
||||
logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`);
|
||||
|
||||
logger.info(`Creating the Note: ${note.id}`);
|
||||
|
@ -345,7 +355,7 @@ export async function createNote(
|
|||
apEmojis,
|
||||
poll,
|
||||
uri: note.id,
|
||||
url: getOneApHrefNullable(note.url),
|
||||
url: url,
|
||||
},
|
||||
silent,
|
||||
);
|
||||
|
|
|
@ -195,6 +195,12 @@ export async function createPerson(
|
|||
|
||||
const bday = person["vcard:bday"]?.match(/^\d{4}-\d{2}-\d{2}/);
|
||||
|
||||
const url = getOneApHrefNullable(person.url);
|
||||
|
||||
if (url && !url.startsWith('https://')) {
|
||||
throw new Error(`unexpected shcema of person url: ${url}`);
|
||||
}
|
||||
|
||||
// Create user
|
||||
let user: IRemoteUser;
|
||||
try {
|
||||
|
@ -237,7 +243,7 @@ export async function createPerson(
|
|||
description: person.summary
|
||||
? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
|
||||
: null,
|
||||
url: getOneApHrefNullable(person.url),
|
||||
url: url,
|
||||
fields,
|
||||
birthday: bday ? bday[0] : null,
|
||||
location: person["vcard:Address"] || null,
|
||||
|
@ -387,6 +393,12 @@ export async function updatePerson(
|
|||
|
||||
const bday = person["vcard:bday"]?.match(/^\d{4}-\d{2}-\d{2}/);
|
||||
|
||||
const url = getOneApHrefNullable(person.url);
|
||||
|
||||
if (url && !url.startsWith('https://')) {
|
||||
throw new Error(`unexpected shcema of person url: ${url}`);
|
||||
}
|
||||
|
||||
const updates = {
|
||||
lastFetchedAt: new Date(),
|
||||
inbox: person.inbox,
|
||||
|
@ -430,7 +442,7 @@ export async function updatePerson(
|
|||
await UserProfiles.update(
|
||||
{ userId: exist.id },
|
||||
{
|
||||
url: getOneApHrefNullable(person.url),
|
||||
url: url,
|
||||
fields,
|
||||
description: person.summary
|
||||
? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
|
||||
|
|
|
@ -44,6 +44,14 @@ export const urlPreviewHandler = async (ctx: Koa.Context) => {
|
|||
|
||||
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.thumbnail = wrap(summary.thumbnail);
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ const embedId = `embed${Math.random().toString().replace(/\D/,'')}`;
|
|||
let tweetHeight = $ref(150);
|
||||
|
||||
const requestUrl = new URL(props.url);
|
||||
if (!['http:', 'https:'].includes(requestUrl.protocol)) throw new Error('invalid url');
|
||||
|
||||
if (requestUrl.hostname === 'twitter.com' || requestUrl.hostname === 'mobile.twitter.com') {
|
||||
const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/);
|
||||
|
|
|
@ -33,6 +33,7 @@ const props = defineProps<{
|
|||
|
||||
const self = props.url.startsWith(local);
|
||||
const url = new URL(props.url);
|
||||
if (!['http:', 'https:'].includes(url.protocol)) throw new Error('invalid url');
|
||||
const el = ref();
|
||||
|
||||
useTooltip(el, (showing) => {
|
||||
|
|
|
@ -80,6 +80,8 @@ export default defineComponent({
|
|||
this.state = 'accepted';
|
||||
const getUrlParams = () => window.location.search.substring(1).split('&').reduce((result, query) => { const [k, v] = query.split('='); result[k] = decodeURI(v); return result; }, {});
|
||||
if (this.session.app.callbackUrl) {
|
||||
const url = new URL(this.session.app.callbackUrl);
|
||||
if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(url.protocol)) throw new Error('invalid url');
|
||||
location.href = `${this.session.app.callbackUrl}?token=${this.session.token}&code=${this.session.token}&state=${getUrlParams().state || ''}`;
|
||||
}
|
||||
}, onLogin(res) {
|
||||
|
|
|
@ -70,13 +70,14 @@ async function accept(): Promise<void> {
|
|||
|
||||
state = 'accepted';
|
||||
if (props.callback) {
|
||||
const cbUrl = new URL(props.callback);
|
||||
if (['javascript:', 'file:', 'data:', 'mailto:', 'tel:'].includes(cbUrl.protocol)) throw new Error('invalid url');
|
||||
location.href = appendQuery(props.callback, query({
|
||||
session: props.session,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
function deny(): void {
|
||||
state = 'denied';
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,11 @@ export function createAiScriptEnv(opts) {
|
|||
return confirm.canceled ? values.FALSE : values.TRUE;
|
||||
}),
|
||||
"Mk:api": values.FN_NATIVE(async ([ep, param, token]) => {
|
||||
if (token) utils.assertString(token);
|
||||
if (token) {
|
||||
utils.assertString(token);
|
||||
// バグがあればundefinedもあり得るため念のため
|
||||
if (typeof token.value !== 'string') throw new Error('invalid token');
|
||||
}
|
||||
apiRequests++;
|
||||
if (apiRequests > 16) return values.NULL;
|
||||
const res = await os.api(
|
||||
|
|
Loading…
Reference in New Issue