0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-03 23:00:14 -05:00

🔒 Limited permissions for uploaded files to 0644 (#21841)

Fixes
https://linear.app/ghost/issue/ENG-1010/uploaded-file-permission-security-improvement

- This commit ensures all files uploaded to Ghost via importer are set
with 0644 permissions to improve security.
- Uploaded files previously retained their original permissions, which
could leave them executable.
- This commit prevents files from being inadvertently executable.
This commit is contained in:
Princi Vershwal 2024-12-10 12:41:48 +05:30 committed by GitHub
parent c38e83d50d
commit 9476afb876
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 0 deletions

View file

@ -225,6 +225,10 @@ class ImportManager {
try {
await extract(filePath, tmpDir);
// Set permissions for all extracted files
const files = glob.sync('**/*', {cwd: tmpDir, nodir: true});
await Promise.all(files.map(file => fs.chmod(path.join(tmpDir, file), 0o644)));
} catch (err) {
if (err.message.startsWith('ENAMETOOLONG:')) {
// The file was probably zipped with MacOS zip utility. Which doesn't correctly set UTF-8 encoding flag.

View file

@ -0,0 +1,25 @@
const should = require('should');
const fs = require('fs-extra');
const path = require('path');
const glob = require('glob');
const importManager = require('../../../../../core/server/data/importer/import-manager');
describe('Import Manager', function () {
describe('extractZip', function () {
it('extracts zip file and sets correct file permissions', async function () {
const zipPath = path.join(__dirname, '/test.zip');
const extractedPath = await importManager.extractZip(zipPath);
try {
const files = glob.sync('**/*', {cwd: extractedPath, nodir: true});
files.forEach((file) => {
const filePath = path.join(extractedPath, file);
const stats = fs.statSync(filePath);
const fileMode = stats.mode & 0o777;
should.equal(fileMode, 0o644, `File ${file} should have 0644 permissions`);
});
} finally {
await fs.remove(extractedPath);
}
});
});
});

Binary file not shown.