🔐 fix: Enhance Message & Image Access Security (#3363)

* chore: slight refactor

* fix: prevent message updates unless explicitly owned

* refactor: rethrow errors, update deleteMessagesSince (not used), add basic tests

* fix: Add path normalization and validation to image request middleware

* fix: image validation path security
This commit is contained in:
Danny Avila 2024-07-17 09:51:03 -04:00 committed by GitHub
parent 0a1d38e318
commit d5d188eebf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 595 additions and 229 deletions

View file

@ -51,7 +51,7 @@ router.post('/', setHeaders, async (req, res) => {
});
if (!overrideParentMessageId) {
await saveMessage({ ...userMessage, user: req.user.id });
await saveMessage(req, { ...userMessage, user: req.user.id });
await saveConvo(req.user.id, {
...userMessage,
...endpointOption,
@ -93,7 +93,7 @@ const ask = async ({
const currentTimestamp = Date.now();
if (currentTimestamp - lastSavedTimestamp > 500) {
lastSavedTimestamp = currentTimestamp;
saveMessage({
saveMessage(req, {
messageId: responseMessageId,
sender: endpointOption?.jailbreak ? 'Sydney' : 'BingAI',
conversationId,
@ -159,7 +159,7 @@ const ask = async ({
isCreatedByUser: false,
};
await saveMessage({ ...responseMessage, user });
await saveMessage(req, { ...responseMessage, user });
responseMessage.messageId = newResponseMessageId;
// STEP2 update the conversation
@ -192,7 +192,7 @@ const ask = async ({
// If response has parentMessageId, the fake userMessage.messageId should be updated to the real one.
if (!overrideParentMessageId) {
await saveMessage({
await saveMessage(req, {
...userMessage,
user,
messageId: userMessageId,
@ -229,7 +229,7 @@ const ask = async ({
isCreatedByUser: false,
text: `${getPartialMessage() ?? ''}\n\nError message: "${error.message}"`,
};
await saveMessage({ ...errorMessage, user });
await saveMessage(req, { ...errorMessage, user });
handleError(res, errorMessage);
}
};

View file

@ -70,7 +70,7 @@ router.post('/', setHeaders, async (req, res) => {
});
if (!overrideParentMessageId) {
await saveMessage({ ...userMessage, user: req.user.id });
await saveMessage(req, { ...userMessage, user: req.user.id });
await saveConvo(req.user.id, {
...userMessage,
...endpointOption,
@ -118,7 +118,7 @@ const ask = async ({
const currentTimestamp = Date.now();
if (currentTimestamp - lastSavedTimestamp > 500) {
lastSavedTimestamp = currentTimestamp;
saveMessage({
saveMessage(req, {
messageId: responseMessageId,
sender: model,
conversationId,
@ -197,7 +197,7 @@ const ask = async ({
isCreatedByUser: false,
};
await saveMessage({ ...responseMessage, user });
await saveMessage(req, { ...responseMessage, user });
responseMessage.messageId = newResponseMessageId;
let conversationUpdate = {
@ -221,7 +221,7 @@ const ask = async ({
// If response has parentMessageId, the fake userMessage.messageId should be updated to the real one.
if (!overrideParentMessageId) {
await saveMessage({
await saveMessage(req, {
...userMessage,
user,
messageId: userMessageId,
@ -266,7 +266,7 @@ const ask = async ({
isCreatedByUser: false,
};
saveMessage({ ...responseMessage, user });
saveMessage(req, { ...responseMessage, user });
return {
title: await getConvoTitle(user, conversationId),
@ -288,7 +288,7 @@ const ask = async ({
model,
isCreatedByUser: false,
};
await saveMessage({ ...errorMessage, user });
await saveMessage(req, { ...errorMessage, user });
handleError(res, errorMessage);
}
}

View file

@ -85,7 +85,7 @@ router.post(
clearTimeout(timer);
}
throttledSaveMessage({
throttledSaveMessage(req, {
messageId: responseMessageId,
sender,
conversationId,
@ -170,7 +170,7 @@ router.post(
const onChainEnd = () => {
if (!client.skipSaveUserMessage) {
saveMessage({ ...userMessage, user });
saveMessage(req, { ...userMessage, user });
}
sendIntermediateMessage(res, {
plugins,
@ -208,7 +208,7 @@ router.post(
logger.debug('[/ask/gptPlugins]', response);
response.plugins = plugins.map((p) => ({ ...p, loading: false }));
await saveMessage({ ...response, user });
await saveMessage(req, { ...response, user });
const { conversation = {} } = await client.responsePromise;
conversation.title =