mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 04:26:58 +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 { ApDbResolverService } from './ApDbResolverService.js';
|
||||||
import { ApRendererService } from './ApRendererService.js';
|
import { ApRendererService } from './ApRendererService.js';
|
||||||
import { ApRequestService } from './ApRequestService.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 {
|
export class Resolver {
|
||||||
private history: Set<string>;
|
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
|
@bindThis
|
||||||
public async resolve(value: string | IObject | [string | IObject]): Promise<IObject> {
|
public async resolve(value: string | IObject | [string | IObject]): Promise<IObject> {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// 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)) {
|
if (Array.isArray(value)) {
|
||||||
return value[0];
|
return value[0];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue