mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
feat: restrict access to ap.probe method to registered users, add rate limiting protection
This commit is contained in:
@@ -27,6 +27,9 @@ const probeCache = ttl({
|
||||
max: 500,
|
||||
ttl: 1000 * 60 * 60, // 1 hour
|
||||
});
|
||||
const probeRateLimit = ttl({
|
||||
ttl: 1000 * 3, // 3 seconds
|
||||
});
|
||||
|
||||
const ActivityPub = module.exports;
|
||||
|
||||
@@ -506,6 +509,13 @@ ActivityPub.probe = async ({ uid, url }) => {
|
||||
* - Returns a relative path if already available, true if not, and false otherwise.
|
||||
*/
|
||||
|
||||
// Disable on config setting; restrict lookups to HTTPS-enabled URLs only
|
||||
const { activitypubProbe } = meta.config;
|
||||
const { protocol } = new URL(url);
|
||||
if (!activitypubProbe || protocol !== 'https:') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Known resources
|
||||
const [isNote, isMessage, isActor, isActorUrl] = await Promise.all([
|
||||
posts.exists(url),
|
||||
@@ -541,6 +551,17 @@ ActivityPub.probe = async ({ uid, url }) => {
|
||||
}
|
||||
}
|
||||
|
||||
// Guests not allowed to use expensive logic path
|
||||
if (!uid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// One request allowed every 3 seconds (configured at top)
|
||||
const limited = probeRateLimit.get(uid);
|
||||
if (limited) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cached result
|
||||
if (probeCache.has(url)) {
|
||||
return probeCache.get(url);
|
||||
@@ -572,6 +593,7 @@ ActivityPub.probe = async ({ uid, url }) => {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
probeRateLimit.set(uid, true);
|
||||
return await checkHeader(meta.config.activitypubProbeTimeout || 2000);
|
||||
} catch (e) {
|
||||
if (e.name === 'TimeoutError') {
|
||||
|
||||
@@ -31,7 +31,7 @@ Controller.fetch = async (req, res, next) => {
|
||||
if (typeof result === 'string') {
|
||||
return helpers.redirect(res, result);
|
||||
} else if (result) {
|
||||
const { id, type } = await activitypub.get('uid', req.uid || 0, url.href);
|
||||
const { id, type } = await activitypub.get('uid', req.uid, url.href);
|
||||
switch (true) {
|
||||
case activitypub._constants.acceptedPostTypes.includes(type): {
|
||||
return helpers.redirect(res, `/post/${encodeURIComponent(id)}`);
|
||||
|
||||
Reference in New Issue
Block a user