mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
fix(api): 🔒 Replace bad webfinger regex with good one
This commit is contained in:
parent
9ad0f88ff2
commit
4f070c9b65
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { mentionValidator } from "@api";
|
||||||
import markdownItTaskLists from "@hackmd/markdown-it-task-lists";
|
import markdownItTaskLists from "@hackmd/markdown-it-task-lists";
|
||||||
import { dualLogger } from "@loggers";
|
import { dualLogger } from "@loggers";
|
||||||
import { sanitizeHtml, sanitizeHtmlInline } from "@sanitization";
|
import { sanitizeHtml, sanitizeHtmlInline } from "@sanitization";
|
||||||
|
|
@ -365,26 +366,13 @@ export const resolveNote = async (
|
||||||
return createdNote;
|
return createdNote;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createMentionRegExp = () =>
|
|
||||||
createRegExp(
|
|
||||||
exactly("@"),
|
|
||||||
oneOrMore(anyOf(letter.lowercase, digit, charIn("-"))).groupedAs(
|
|
||||||
"username",
|
|
||||||
),
|
|
||||||
maybe(
|
|
||||||
exactly("@"),
|
|
||||||
oneOrMore(anyOf(letter, digit, charIn("_-.:"))).groupedAs("domain"),
|
|
||||||
),
|
|
||||||
[global],
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get people mentioned in the content (match @username or @username@domain.com mentions)
|
* Get people mentioned in the content (match @username or @username@domain.com mentions)
|
||||||
* @param text The text to parse mentions from.
|
* @param text The text to parse mentions from.
|
||||||
* @returns An array of users mentioned in the text.
|
* @returns An array of users mentioned in the text.
|
||||||
*/
|
*/
|
||||||
export const parseTextMentions = async (text: string): Promise<User[]> => {
|
export const parseTextMentions = async (text: string): Promise<User[]> => {
|
||||||
const mentionedPeople = [...text.matchAll(createMentionRegExp())] ?? [];
|
const mentionedPeople = [...text.matchAll(mentionValidator)] ?? [];
|
||||||
if (mentionedPeople.length === 0) return [];
|
if (mentionedPeople.length === 0) return [];
|
||||||
|
|
||||||
const baseUrlHost = new URL(config.http.base_url).host;
|
const baseUrlHost = new URL(config.http.base_url).host;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
import { applyConfig, handleZodError, idValidator } from "@api";
|
import {
|
||||||
|
applyConfig,
|
||||||
|
handleZodError,
|
||||||
|
idValidator,
|
||||||
|
webfingerMention,
|
||||||
|
} from "@api";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { errorResponse, jsonResponse } from "@response";
|
import { errorResponse, jsonResponse } from "@response";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
|
|
@ -36,7 +41,7 @@ export default (app: Hono) =>
|
||||||
const { resource } = context.req.valid("query");
|
const { resource } = context.req.valid("query");
|
||||||
|
|
||||||
// Check if resource is in the correct format (acct:uuid/username@domain)
|
// Check if resource is in the correct format (acct:uuid/username@domain)
|
||||||
if (!resource.match(/^acct:[a-zA-Z0-9-]+@[a-zA-Z0-9.-:]+$/)) {
|
if (!resource.match(webfingerMention)) {
|
||||||
return errorResponse(
|
return errorResponse(
|
||||||
"Invalid resource (should be acct:(id or username)@domain)",
|
"Invalid resource (should be acct:(id or username)@domain)",
|
||||||
400,
|
400,
|
||||||
|
|
|
||||||
24
utils/api.ts
24
utils/api.ts
|
|
@ -11,7 +11,9 @@ import {
|
||||||
createRegExp,
|
createRegExp,
|
||||||
digit,
|
digit,
|
||||||
exactly,
|
exactly,
|
||||||
|
global,
|
||||||
letter,
|
letter,
|
||||||
|
maybe,
|
||||||
oneOrMore,
|
oneOrMore,
|
||||||
} from "magic-regexp";
|
} from "magic-regexp";
|
||||||
import { parse } from "qs";
|
import { parse } from "qs";
|
||||||
|
|
@ -64,6 +66,28 @@ export const emojiValidatorWithColons = createRegExp(
|
||||||
[caseInsensitive],
|
[caseInsensitive],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const mentionValidator = createRegExp(
|
||||||
|
exactly("@"),
|
||||||
|
oneOrMore(anyOf(letter.lowercase, digit, charIn("-"))).groupedAs(
|
||||||
|
"username",
|
||||||
|
),
|
||||||
|
maybe(
|
||||||
|
exactly("@"),
|
||||||
|
oneOrMore(anyOf(letter, digit, charIn("_-.:"))).groupedAs("domain"),
|
||||||
|
),
|
||||||
|
[global],
|
||||||
|
);
|
||||||
|
|
||||||
|
export const webfingerMention = createRegExp(
|
||||||
|
exactly("acct:"),
|
||||||
|
oneOrMore(anyOf(letter, digit, charIn("-"))).groupedAs("username"),
|
||||||
|
maybe(
|
||||||
|
exactly("@"),
|
||||||
|
oneOrMore(anyOf(letter, digit, charIn("_-.:"))).groupedAs("domain"),
|
||||||
|
),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
export const handleZodError = (
|
export const handleZodError = (
|
||||||
result:
|
result:
|
||||||
| { success: true; data?: object }
|
| { success: true; data?: object }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue