[backend] Stricter validation of activity identifiers

This resolves a security issue that was disclosed on 2024-03-24 & patched in coordination with other affected software on 2024-03-30.
Huge thanks to Oneric for the detailed security disclosure.
This commit is contained in:
Laura Hausmann 2024-03-24 19:08:08 +01:00
parent 74df0b3602
commit ac57c58ecf
No known key found for this signature in database
GPG key ID: D044E84C5BE01605

View file

@ -122,12 +122,29 @@ export default class Resolver {
apLogger.debug("Getting object from remote, authenticated as user:"); apLogger.debug("Getting object from remote, authenticated as user:");
apLogger.debug(JSON.stringify(this.user, null, 2)); apLogger.debug(JSON.stringify(this.user, null, 2));
const res = ( const {res, object} = await this.doFetch(value);
if (object.id == null) return object;
if (res.finalUrl === object.id) return object;
if (new URL(res.finalUrl).host !== new URL(object.id).host)
throw new Error("Object ID host doesn't match final url host");
const {res: finalRes, object: finalObject} = await this.doFetch(object.id);
if (finalRes.finalUrl !== finalObject.id)
throw new Error("Object ID still doesn't match final URL after second fetch attempt")
return finalObject;
}
private async doFetch(uri: string) {
let res = (
this.user this.user
? await signedGet(value, this.user) ? await signedGet(uri, this.user)
: await getJsonActivity(value) : await getJsonActivity(uri)
); );
const object = res.content as IObject; let object = res.content as IObject;
if ( if (
object == null || object == null ||
@ -140,10 +157,7 @@ export default class Resolver {
throw new Error("invalid response"); throw new Error("invalid response");
} }
if (object.id != null && new URL(res.finalUrl).host != new URL(object.id).host) return {res, object};
throw new Error("Object ID host doesn't match final url host");
return object;
} }
private resolveLocal(url: string): Promise<IObject> { private resolveLocal(url: string): Promise<IObject> {