Skip to content

Commit

Permalink
Added server-side verification of file ; Fixes #35
Browse files Browse the repository at this point in the history
  • Loading branch information
TheRolfFR committed Sep 24, 2024
1 parent dc56322 commit 9ca53fd
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
133 changes: 133 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
"discord-api-types": "^0.37.100",
"dotenv": "^16.4.5",
"express": "^4.21.0",
"faithful-api": "file:",
"file-type": "^19.5.0",
"firestorm-db": "^1.13.0",
"form-data": "^4.0.0",
"isomorphic-dompurify": "^2.15.0",
Expand Down
23 changes: 23 additions & 0 deletions src/v2/service/addon.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { URL } from "url";
import { APIEmbedField } from "discord-api-types/v10";
import { WriteConfirmation } from "firestorm-db";
import { fileTypeFromBuffer, MimeType } from "file-type";
import { User, UserProfile } from "../interfaces/users";
import { Addons, Addon, AddonStatus, AddonAll, Files, File, FileParent } from "../interfaces";
import { BadRequestError, NotFoundError } from "../tools/errors";
Expand All @@ -17,6 +18,10 @@ import {
import AddonFirestormRepository from "../repository/addon.repository";
import { discordEmbed } from "../tools/discordEmbed";

const HEADER_MIME_TYPES: MimeType[] = ["image/jpeg"];

const SCREENSHOT_MIME_TYPES: MimeType[] = ["image/jpeg"];

// filter & keep only values that are in a-Z & 0-9 & _ or -
const toSlug = (value: string) =>
value
Expand All @@ -31,6 +36,20 @@ export default class AddonService {

private readonly addonRepo = new AddonFirestormRepository();

/**
* Passes MIME type verification
* @param buffer Input file buffer
* @param mime_types_accepted List of accepted mime types
*/
private async verifyFileType(buffer: Buffer, mime_types_accepted: Array<MimeType>) {
const { mime } = await fileTypeFromBuffer(buffer);
if (!mime_types_accepted.includes(mime)) {
throw new BadRequestError(
`Incorrect file header, expected one in ${mime_types_accepted.toString()}, got ${mime}`,
);
}
}

public async getIdFromPath(idOrSlug: string): Promise<[number, Addon | undefined]> {
const intID = Number(idOrSlug);

Expand Down Expand Up @@ -328,6 +347,8 @@ export default class AddonService {
filename: string,
buffer: Buffer,
): Promise<void | File> {
this.verifyFileType(buffer, HEADER_MIME_TYPES);

const [addonID, addon] = await this.getAddonFromSlugOrId(idOrSlug);
const { slug } = addon;

Expand Down Expand Up @@ -373,6 +394,8 @@ export default class AddonService {
filename: string,
buffer: Buffer,
): Promise<void | File> {
this.verifyFileType(buffer, SCREENSHOT_MIME_TYPES);

const [addonID, addon] = await this.getAddonFromSlugOrId(idOrSlug);
const { slug } = addon;

Expand Down

0 comments on commit 9ca53fd

Please sign in to comment.