CVE-2024-27296: Insufficient Information (NVD-CWE-noinfo)
value: Directus is a real-time API and App dashboard for managing SQL database content. Prior to version 10.8.3, the exact Directus version number was being shipped in compiled JS bundles which are accessible without authentication. With this information a malicious attacker can trivially look for known vulnerabilities in Directus core or any of its shipped dependencies in that specific running version. The problem has been resolved in versions 10.8.3 and newer.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-03-01T16:15Z
Repository: https://github.com/directus/directus
Language: TypeScript
Files changed: app/env.d.ts, app/src/main.ts, app/src/modules/settings/components/navigation.vue, app/src/stores/server.ts, app/vite.config.js
Commit date: 2023-12-20 17:58:44 -0500
Commit message: replaced hardcoded versions in the app

Diff: diff --git a/app/env.d.ts b/app/env.d.ts
index 2cdd5b7fcf..1142a7d787 100644
--- a/app/env.d.ts
+++ b/app/env.d.ts
@@ -1,4 +1,2 @@
 /// <reference types="vite/client" />
 /// <reference types="@histoire/plugin-vue/components" />
-
-declare const __DIRECTUS_VERSION__: string;
diff --git a/app/src/main.ts b/app/src/main.ts
index 1676fbc28e..428eea8638 100644
--- a/app/src/main.ts
+++ b/app/src/main.ts
@@ -15,23 +15,17 @@ import './styles/main.scss';
 import { registerViews } from './views/register';
 
 init();
 
 async function init() {
-	const version = __DIRECTUS_VERSION__;
-
 	console.log(DIRECTUS_LOGO);
 
 	console.info(
 		`Hey! Interested in helping build this open-source data management platform?\nIf so, join our growing team of contributors at: https://directus.chat`,
 	);
 
-	if (import.meta.env.DEV) {
-		console.info(`%c🐰 Starting Directus v${version}...`, 'color:Green');
-	} else {
-		console.info(`%c🐰 Starting Directus...`, 'color:Green');
-	}
+	console.info(`%c🐰 Starting Directus...`, 'color:Green');
 
 	console.time('🕓 Application Loaded');
 
 	const app = createApp(App);
 
diff --git a/app/src/modules/settings/components/navigation.vue b/app/src/modules/settings/components/navigation.vue
index 9bd3b99831..345f4c965d 100644
--- a/app/src/modules/settings/components/navigation.vue
+++ b/app/src/modules/settings/components/navigation.vue
@@ -1,12 +1,12 @@
 <script setup lang="ts">
+import { useServerStore } from '@/stores/server';
 import { computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 
-const version = __DIRECTUS_VERSION__;
-
 const { t } = useI18n();
+const { info } = useServerStore();
 
 const dataItems = [
 	{
 		icon: 'database',
 		name: t('settings_data_model'),
@@ -101,11 +101,11 @@ const externalItems = computed(() => {
 		</v-list-item>
 
 		<v-list-item href="https://github.com/directus/directus/releases" class="version">
 			<v-list-item-icon><v-icon name="directus" /></v-list-item-icon>
 			<v-list-item-content>
-				<v-text-overflow class="version" :text="`Directus ${version}`" />
+				<v-text-overflow class="version" :text="`Directus ${info.version}`" />
 			</v-list-item-content>
 		</v-list-item>
 	</v-list>
 </template>
 
diff --git a/app/src/stores/server.ts b/app/src/stores/server.ts
index b5f0e748d3..825cb6181a 100644
--- a/app/src/stores/server.ts
+++ b/app/src/stores/server.ts
@@ -41,10 +41,11 @@ export type Info = {
 		  };
 	queryLimit?: {
 		default: number;
 		max: number;
 	};
+	version?: string;
 };
 
 export type Auth = {
 	providers: AuthProvider[];
 	disableDefault: boolean;
@@ -81,10 +82,11 @@ export const useServerStore = defineStore('serverStore', () => {
 	const hydrate = async (options?: HydrateOptions) => {
 		const [serverInfoResponse, authResponse] = await Promise.all([api.get(`/server/info`), api.get('/auth')]);
 
 		info.project = serverInfoResponse.data.data?.project;
 		info.queryLimit = serverInfoResponse.data.data?.queryLimit;
+		info.version = serverInfoResponse.data.data?.version;
 
 		auth.providers = authResponse.data.data;
 		auth.disableDefault = authResponse.data.disableDefault;
 
 		const { currentUser } = useUserStore();
diff --git a/app/vite.config.js b/app/vite.config.js
index a4539db135..cde9d49ac9 100644
--- a/app/vite.config.js
+++ b/app/vite.config.js
@@ -16,20 +16,16 @@ import UnheadVite from '@unhead/addons/vite';
 import vue from '@vitejs/plugin-vue';
 import fs from 'node:fs';
 import path from 'node:path';
 import { searchForWorkspaceRoot } from 'vite';
 import { defineConfig } from 'vitest/config';
-import { version } from '../directus/package.json';
 
 const API_PATH = path.join('..', 'api');
 const EXTENSIONS_PATH = path.join(API_PATH, 'extensions');
 
 // https://vitejs.dev/config/
 export default defineConfig({
-	define: {
-		__DIRECTUS_VERSION__: JSON.stringify(version),
-	},
 	plugins: [
 		directusExtensions(),
 		vue(),
 		UnheadVite(),
 		yaml({

Vulnerable code: 
declare const __DIRECTUS_VERSION__: string;
	const version = __DIRECTUS_VERSION__;

	if (import.meta.env.DEV) {
		console.info(`%c🐰 Starting Directus v${version}...`, 'color:Green');
	} else {
		console.info(`%c🐰 Starting Directus...`, 'color:Green');
	}
const version = __DIRECTUS_VERSION__;

				<v-text-overflow class="version" :text="`Directus ${version}`" />
import { version } from '../directus/package.json';
	define: {
		__DIRECTUS_VERSION__: JSON.stringify(version),
	},
Fixed code: 	console.info(`%c🐰 Starting Directus...`, 'color:Green');
import { useServerStore } from '@/stores/server';
const { info } = useServerStore();
				<v-text-overflow class="version" :text="`Directus ${info.version}`" />
	version?: string;
		info.version = serverInfoResponse.data.data?.version;