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
8 changed files with 44 additions and 5 deletions
|
@ -111,6 +111,16 @@ export async function createNote(
|
||||||
|
|
||||||
const note: IPost = object;
|
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.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`);
|
||||||
|
|
||||||
logger.info(`Creating the Note: ${note.id}`);
|
logger.info(`Creating the Note: ${note.id}`);
|
||||||
|
@ -345,7 +355,7 @@ export async function createNote(
|
||||||
apEmojis,
|
apEmojis,
|
||||||
poll,
|
poll,
|
||||||
uri: note.id,
|
uri: note.id,
|
||||||
url: getOneApHrefNullable(note.url),
|
url: url,
|
||||||
},
|
},
|
||||||
silent,
|
silent,
|
||||||
);
|
);
|
||||||
|
|
|
@ -195,6 +195,12 @@ export async function createPerson(
|
||||||
|
|
||||||
const bday = person["vcard:bday"]?.match(/^\d{4}-\d{2}-\d{2}/);
|
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
|
// Create user
|
||||||
let user: IRemoteUser;
|
let user: IRemoteUser;
|
||||||
try {
|
try {
|
||||||
|
@ -237,7 +243,7 @@ export async function createPerson(
|
||||||
description: person.summary
|
description: person.summary
|
||||||
? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
|
? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
|
||||||
: null,
|
: null,
|
||||||
url: getOneApHrefNullable(person.url),
|
url: url,
|
||||||
fields,
|
fields,
|
||||||
birthday: bday ? bday[0] : null,
|
birthday: bday ? bday[0] : null,
|
||||||
location: person["vcard:Address"] || 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 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 = {
|
const updates = {
|
||||||
lastFetchedAt: new Date(),
|
lastFetchedAt: new Date(),
|
||||||
inbox: person.inbox,
|
inbox: person.inbox,
|
||||||
|
@ -430,7 +442,7 @@ export async function updatePerson(
|
||||||
await UserProfiles.update(
|
await UserProfiles.update(
|
||||||
{ userId: exist.id },
|
{ userId: exist.id },
|
||||||
{
|
{
|
||||||
url: getOneApHrefNullable(person.url),
|
url: url,
|
||||||
fields,
|
fields,
|
||||||
description: person.summary
|
description: person.summary
|
||||||
? htmlToMfm(truncate(person.summary, summaryLength), person.tag)
|
? 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}`);
|
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);
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ const embedId = `embed${Math.random().toString().replace(/\D/,'')}`;
|
||||||
let tweetHeight = $ref(150);
|
let tweetHeight = $ref(150);
|
||||||
|
|
||||||
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 === 'twitter.com' || requestUrl.hostname === 'mobile.twitter.com') {
|
if (requestUrl.hostname === 'twitter.com' || requestUrl.hostname === 'mobile.twitter.com') {
|
||||||
const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/);
|
const m = requestUrl.pathname.match(/^\/.+\/status(?:es)?\/(\d+)/);
|
||||||
|
|
|
@ -33,6 +33,7 @@ const props = defineProps<{
|
||||||
|
|
||||||
const self = props.url.startsWith(local);
|
const self = props.url.startsWith(local);
|
||||||
const url = new URL(props.url);
|
const url = new URL(props.url);
|
||||||
|
if (!['http:', 'https:'].includes(url.protocol)) throw new Error('invalid url');
|
||||||
const el = ref();
|
const el = ref();
|
||||||
|
|
||||||
useTooltip(el, (showing) => {
|
useTooltip(el, (showing) => {
|
||||||
|
|
|
@ -80,6 +80,8 @@ export default defineComponent({
|
||||||
this.state = 'accepted';
|
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; }, {});
|
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) {
|
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 || ''}`;
|
location.href = `${this.session.app.callbackUrl}?token=${this.session.token}&code=${this.session.token}&state=${getUrlParams().state || ''}`;
|
||||||
}
|
}
|
||||||
}, onLogin(res) {
|
}, onLogin(res) {
|
||||||
|
|
|
@ -70,13 +70,14 @@ async function accept(): Promise<void> {
|
||||||
|
|
||||||
state = 'accepted';
|
state = 'accepted';
|
||||||
if (props.callback) {
|
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({
|
location.href = appendQuery(props.callback, query({
|
||||||
session: props.session,
|
session: props.session,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deny(): void {
|
|
||||||
state = 'denied';
|
state = 'denied';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,11 @@ export function createAiScriptEnv(opts) {
|
||||||
return confirm.canceled ? values.FALSE : values.TRUE;
|
return confirm.canceled ? values.FALSE : values.TRUE;
|
||||||
}),
|
}),
|
||||||
"Mk:api": values.FN_NATIVE(async ([ep, param, token]) => {
|
"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++;
|
apiRequests++;
|
||||||
if (apiRequests > 16) return values.NULL;
|
if (apiRequests > 16) return values.NULL;
|
||||||
const res = await os.api(
|
const res = await os.api(
|
||||||
|
|
Loading…
Reference in a new issue