mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-06 20:16:57 +00:00
implement ApResolver.secureResolve to use a provided object only if the authority matches
This commit is contained in:
parent
1ed2f207f7
commit
ad49faa956
2 changed files with 36 additions and 2 deletions
|
@ -23,7 +23,7 @@ import { getApId, getNullableApId, isCollectionOrOrderedCollection } from './typ
|
|||
import { ApDbResolverService } from './ApDbResolverService.js';
|
||||
import { ApRendererService } from './ApRendererService.js';
|
||||
import { ApRequestService } from './ApRequestService.js';
|
||||
import type { IObject, ICollection, IOrderedCollection } from './type.js';
|
||||
import type { IObject, ICollection, IOrderedCollection, ApObject } from './type.js';
|
||||
|
||||
export class Resolver {
|
||||
private history: Set<string>;
|
||||
|
@ -76,6 +76,33 @@ export class Resolver {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Securely resolves an AP object or URL that has been sent from another instance.
|
||||
* An input object is trusted if and only if its ID matches the authority of sentFromUri.
|
||||
* In all other cases, the object is re-fetched from remote by input string or object ID.
|
||||
*/
|
||||
@bindThis
|
||||
public async secureResolve(input: ApObject, sentFromUri: string): Promise<IObject> {
|
||||
// Unpack arrays to get the value element.
|
||||
const value = fromTuple(input);
|
||||
if (value == null) {
|
||||
throw new IdentifiableError('20058164-9de1-4573-8715-425753a21c1d', 'Cannot resolve null input');
|
||||
}
|
||||
|
||||
// This will throw if the input has no ID, which is good because we can't verify an anonymous object anyway.
|
||||
const id = getApId(value);
|
||||
|
||||
// Check if we can use the provided object as-is.
|
||||
// Our security requires that the object ID matches the host authority that sent it, otherwise it can't be trusted.
|
||||
// A mismatch isn't necessarily malicious, it just means we can't use the object we were given.
|
||||
if (typeof(value) === 'object' && this.apUtilityService.haveSameAuthority(id, sentFromUri)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// If the checks didn't pass, then we must fetch the object and use that.
|
||||
return await this.resolve(id);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async resolve(value: string | IObject | [string | IObject]): Promise<IObject> {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
export function fromTuple<T>(value: T | [T]): T {
|
||||
/*
|
||||
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export function fromTuple<T>(value: T | [T]): T;
|
||||
export function fromTuple<T>(value: T | [T] | T[]): T | undefined;
|
||||
export function fromTuple<T>(value: T | [T] | T[]): T | undefined {
|
||||
if (Array.isArray(value)) {
|
||||
return value[0];
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue