Run the custom policy in a worker for security
This commit is contained in:
parent
6a1b8b0943
commit
9e9ab40886
|
@ -1,7 +1,7 @@
|
|||
FROM denoland/deno:1.43.3
|
||||
EXPOSE 4036
|
||||
WORKDIR /app
|
||||
RUN mkdir -p data && chown -R deno data
|
||||
RUN mkdir -p data/policy && chown -R deno data
|
||||
USER deno
|
||||
COPY . .
|
||||
RUN deno cache src/server.ts
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
*
|
||||
!.gitignore
|
||||
!.gitignore
|
||||
!/policy
|
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
|
@ -13,7 +13,7 @@
|
|||
"admin:role": "deno run -A scripts/admin-role.ts",
|
||||
"stats:recompute": "deno run -A scripts/stats-recompute.ts"
|
||||
},
|
||||
"unstable": ["ffi", "kv"],
|
||||
"unstable": ["ffi", "kv", "worker-options"],
|
||||
"exclude": ["./public"],
|
||||
"imports": {
|
||||
"@/": "./src/",
|
||||
|
|
|
@ -221,7 +221,7 @@ class Conf {
|
|||
}
|
||||
/** Path to the custom policy module. Must be an absolute path, https:, npm:, or jsr: URI. */
|
||||
static get policy(): string {
|
||||
return Deno.env.get('DITTO_POLICY') || new URL('../data/policy.ts', import.meta.url).toString();
|
||||
return Deno.env.get('DITTO_POLICY') || new URL('../data/policy.ts', import.meta.url).pathname;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import { Storages } from '@/storages.ts';
|
|||
import { getTagSet } from '@/tags.ts';
|
||||
import { eventAge, nostrDate, nostrNow, parseNip05, Time } from '@/utils.ts';
|
||||
import { fetchWorker } from '@/workers/fetch.ts';
|
||||
import { policyWorker } from '@/workers/policy.ts';
|
||||
import { TrendsWorker } from '@/workers/trends.ts';
|
||||
import { verifyEventWorker } from '@/workers/verify.ts';
|
||||
import { AdminSigner } from '@/signers/AdminSigner.ts';
|
||||
|
@ -62,11 +63,11 @@ async function policyFilter(event: NostrEvent): Promise<void> {
|
|||
];
|
||||
|
||||
try {
|
||||
const CustomPolicy = (await import(Conf.policy)).default;
|
||||
policies.push(new CustomPolicy());
|
||||
await policyWorker.import(Conf.policy);
|
||||
policies.push(policyWorker);
|
||||
debug(`Using custom policy: ${Conf.policy}`);
|
||||
} catch (e) {
|
||||
if (e.code === 'ERR_MODULE_NOT_FOUND') {
|
||||
if (e.message.includes('Module not found')) {
|
||||
debug('Custom policy not found <https://docs.soapbox.pub/ditto/policies/>');
|
||||
} else {
|
||||
console.error(`DITTO_POLICY (error importing policy): ${Conf.policy}`, e);
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import * as Comlink from 'comlink';
|
||||
|
||||
import { Conf } from '@/config.ts';
|
||||
import type { CustomPolicy } from '@/workers/policy.worker.ts';
|
||||
|
||||
const policyDir = new URL('../../data/policy', import.meta.url).pathname;
|
||||
|
||||
export const policyWorker = Comlink.wrap<CustomPolicy>(
|
||||
new Worker(
|
||||
new URL('./policy.worker.ts', import.meta.url),
|
||||
{
|
||||
type: 'module',
|
||||
deno: {
|
||||
permissions: {
|
||||
read: [Conf.policy, policyDir],
|
||||
write: [policyDir],
|
||||
net: 'inherit',
|
||||
env: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
);
|
|
@ -0,0 +1,19 @@
|
|||
import { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/nostrify';
|
||||
import { ReadOnlyPolicy } from '@nostrify/nostrify/policies';
|
||||
import * as Comlink from 'comlink';
|
||||
|
||||
export class CustomPolicy implements NPolicy {
|
||||
private policy: NPolicy = new ReadOnlyPolicy();
|
||||
|
||||
// deno-lint-ignore require-await
|
||||
async call(event: NostrEvent): Promise<NostrRelayOK> {
|
||||
return this.policy.call(event);
|
||||
}
|
||||
|
||||
async import(path: string): Promise<void> {
|
||||
const Policy = (await import(path)).default;
|
||||
this.policy = new Policy();
|
||||
}
|
||||
}
|
||||
|
||||
Comlink.expose(new CustomPolicy());
|
Loading…
Reference in New Issue