CVE-2024-23649 (TypeScript, published 2024-01-24T18:15Z)
Description: value: Lemmy is a link aggregator and forum for the fediverse. Starting in version 0.17.0 and prior to version 0.19.1, users can report private messages, even when they're neither sender nor recipient of the message. The API response to creating a private message report contains the private message itself, which means any user can just iterate over message ids to (loudly) obtain all private messages of an instance. A user with instance admin privileges can also abuse this if the private message is removed from the response, as they're able to see the resulting reports.

Creating a private message report by POSTing to `/api/v3/private_message/report` does not validate whether the reporter is the recipient of the message. lemmy-ui does not allow the sender to report the message; the API method should likely be restricted to accessible to recipients only. The API response when creating a report contains the `private_message_report_view` with all the details of the report, including the private message that has been reported:

Any authenticated user can obtain arbitrary (untargeted) private message contents. Privileges required depend on the instance configuration; when registrations are enabled without application system, the privileges required are practically none. When registration applications are required, privileges required could be considered low, but this assessment heavily varies by instance.

Version 0.19.1 contains a patch for this issue. A workaround is available. If an update to a fixed Lemmy version is not immediately possible, the API route can be blocked in the reverse proxy. This will prevent anyone from reporting private messages, but it will also prevent exploitation before the update has been applied.
Severity: nan (CVSS v3 base score: 6.5)
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/LemmyNet/lemmy
Files changed:
api_tests/prepare-drone-federation-test.sh
api_tests/src/private_message.spec.ts
api_tests/src/shared.ts
crates/api/src/private_message_report/create.rs
Commit message: Fixing private message reports. (#4279)



Vulnerable code:
if ! [ -f "pict-rs" ]; then

Fixed code:
if [ ! -f "pict-rs" ]; then
  reportPrivateMessage,

test("Create a private message report", async () => {
  let pmRes = await createPrivateMessage(alpha, recipient_id);
  let betaPms1 = await waitUntil(
    () => listPrivateMessages(beta),
    m =>
      !!m.private_messages.find(
        e =>
          e.private_message.ap_id ===
          pmRes.private_message_view.private_message.ap_id,
      ),
  );
  let betaPm = betaPms1.private_messages[0];
  expect(betaPm).toBeDefined();

  // Make sure that only the recipient can report it, so this should fail
  await expect(
    reportPrivateMessage(
      alpha,
      pmRes.private_message_view.private_message.id,
      "a reason",
    ),
  ).rejects.toStrictEqual(Error("couldnt_create_report"));

  // This one should pass
  let reason = "another reason";
  let report = await reportPrivateMessage(
    beta,
    betaPm.private_message.id,
    reason,
  );

  expect(report.private_message_report_view.private_message.id).toBe(
    betaPm.private_message.id,
  );
  expect(report.private_message_report_view.private_message_report.reason).toBe(
    reason,
  );
});
  CreatePrivateMessageReport,
  PrivateMessageReportResponse,
export async function reportPrivateMessage(
  api: LemmyHttp,
  private_message_id: number,
  reason: string,
): Promise<PrivateMessageReportResponse> {
  let form: CreatePrivateMessageReport = {
    private_message_id,
    reason,
  };
  return api.createPrivateMessageReport(form);
}

  // Make sure that only the recipient of the private message can create a report
  if person_id != private_message.recipient_id {
    Err(LemmyErrorType::CouldntCreateReport)?
  }