Просмотр исходного кода

Make sure only mime types in allow list can be set to inline

arvid-e 8 месяцев назад
Родитель
Сommit
e93b962d49

+ 16 - 10
apps/app/src/server/service/file-uploader/utils/headers.ts

@@ -48,23 +48,29 @@ export class ContentHeaders implements IContentHeaders {
       value: actualContentTypeString,
     };
 
-    const requestedInline = opts?.inline ?? false;
     const configKey = `attachments:contentDisposition:${actualContentTypeString}:inline` as ConfigKey;
+    const rawConfigValue = await instance.configManager.getConfig(configKey);
+
+    const requestedInline = opts?.inline ?? false;
 
-    // AWAIT the config value here
-    const rawConfigValue = await instance.configManager.getConfig(configKey); // Use instance's configManager
+    let systemAllowsInline: boolean;
 
-    let isConfiguredInline: boolean;
-    if (typeof rawConfigValue === 'boolean') {
-      isConfiguredInline = rawConfigValue;
+    const ALL_POSSIBLE_INLINE_MIME_TYPES = new Set<string>([
+      ...DEFAULT_ALLOWLIST_MIME_TYPES,
+      ...SAFE_INLINE_CONFIGURABLE_MIME_TYPES,
+    ]);
+
+    if (!ALL_POSSIBLE_INLINE_MIME_TYPES.has(actualContentTypeString)) {
+      systemAllowsInline = false;
+    }
+    else if (typeof rawConfigValue === 'boolean') {
+      systemAllowsInline = rawConfigValue;
     }
     else {
-      isConfiguredInline = DEFAULT_ALLOWLIST_MIME_TYPES.has(actualContentTypeString);
+      systemAllowsInline = DEFAULT_ALLOWLIST_MIME_TYPES.has(actualContentTypeString);
     }
 
-    const shouldBeInline = requestedInline
-      && isConfiguredInline
-      && SAFE_INLINE_CONFIGURABLE_MIME_TYPES.has(actualContentTypeString);
+    const shouldBeInline = requestedInline && systemAllowsInline;
 
     instance.contentDisposition = {
       field: 'Content-Disposition',

+ 53 - 1
apps/app/src/server/service/file-uploader/utils/security.ts

@@ -4,16 +4,37 @@
  * their file extension or sniffed content.
  */
 export const DEFAULT_ALLOWLIST_MIME_TYPES = new Set<string>([
+  // Common Image Types (generally safe for inline display)
   'image/png',
   'image/jpeg',
   'image/gif',
   'image/webp',
   'image/bmp',
+  'image/tiff',
   'image/x-icon',
+
+  // Common Audio Types (generally safe for inline display)
+  'audio/mpeg',
+  'audio/ogg',
+  'audio/wav',
+  'audio/aac',
+  'audio/webm',
+
+  // Common Video Types (generally safe for inline display)
+  'video/mp4',
+  'video/webm',
+  'video/ogg',
+
+  // Basic Text (generally safe for inline display)
+  'text/plain',
+  'text/markdown', // Assuming markdown rendering is safe
 ]);
 
 /**
  * Defines safe MIME types that can be set to inline by the admin.
+ * This set includes types that are generally safe, but might be explicitly forced
+ * to 'attachment' by default for security or user experience reasons,
+ * and the admin has the option to enable inline display.
  */
 export const SAFE_INLINE_CONFIGURABLE_MIME_TYPES = new Set<string>([
   // --- Images ---
@@ -24,6 +45,7 @@ export const SAFE_INLINE_CONFIGURABLE_MIME_TYPES = new Set<string>([
   'image/bmp',
   'image/tiff',
   'image/x-icon',
+  'image/svg+xml',
 
   // --- Audio ---
   'audio/mpeg',
@@ -40,8 +62,38 @@ export const SAFE_INLINE_CONFIGURABLE_MIME_TYPES = new Set<string>([
   // --- Documents / Text ---
   'application/pdf',
   'text/plain',
-  'text/markdown', // Assumes GROWI's markdown rendering is safe and isolated
+  'text/markdown',
   'text/css',
   'text/csv',
   'text/tab-separated-values',
+  'application/xml', // XML can sometimes be rendered inline, but care is needed
+  'application/json',
+
+  // --- Other potentially renderable, but generally safer as attachment by default
+  'application/msword',
+  'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // .docx
+  'application/vnd.ms-excel',
+  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
+  'application/vnd.ms-powerpoint',
+  'application/vnd.openxmlformats-officedocument.presentationml.presentation', // .pptx
+  'application/zip',
+  'application/x-rar-compressed',
+]);
+
+// Types that are generally NOT safe for inline display and should always default to attachment
+export const NOT_SAFE_INLINE_MIME_TYPES = new Set<string>([
+  'text/html',
+  'text/javascript',
+  'application/javascript',
+  'application/x-sh',
+  'application/x-msdownload',
+  'application/octet-stream',
+]);
+
+// This set is for internal use to define all configurable types for the API and settings.
+// It combines all types that can be handled for disposition settings.
+export const CONFIGURABLE_MIME_TYPES_FOR_DISPOSITION = new Set<string>([
+  ...DEFAULT_ALLOWLIST_MIME_TYPES,
+  ...SAFE_INLINE_CONFIGURABLE_MIME_TYPES,
+  ...NOT_SAFE_INLINE_MIME_TYPES,
 ]);