Skip to content

Commit 3968ec0

Browse files
committed
Restrict file creation to workspace
1 parent b9f3b13 commit 3968ec0

File tree

3 files changed

+43
-32
lines changed

3 files changed

+43
-32
lines changed

apps/remix-ide/src/app/files/fileManager.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ const globalRegistry = require('../../global/registry')
99
const toaster = require('../ui/tooltip')
1010
const modalDialogCustom = require('../ui/modal-dialog-custom')
1111
const helper = require('../../lib/helper.js')
12-
const path = require('path')
1312

1413
/*
1514
attach to files event (removed renamed)
@@ -59,14 +58,7 @@ class FileManager extends Plugin {
5958
}
6059

6160
limitPluginScope (path) {
62-
const workspace = this.fileManager.currentWorkspace()
63-
64-
if (workspace) {
65-
66-
} else {
67-
68-
}
69-
61+
return path.replace(/^\/browser\//, '').replace(/^browser\//, '') // forbids plugin to access the root filesystem
7062
}
7163

7264
/**

apps/remix-ide/src/app/files/workspaceFileProvider.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
const FileProvider = require('./fileProvider')
4+
const path = require('path')
45

56
class WorkspaceFileProvider extends FileProvider {
67
constructor () {
@@ -32,8 +33,19 @@ class WorkspaceFileProvider extends FileProvider {
3233
if (path.startsWith(this.workspacesPath + '/' + this.workspace)) return path
3334
if (path.startsWith(this.workspace)) return this.workspacesPath + '/' + this.workspace
3435
path = super.removePrefix(path)
35-
const ret = this.workspacesPath + '/' + this.workspace + '/' + (path === '/' ? '' : path)
36-
return ret.replace(/^\/|\/$/g, '')
36+
let ret = this.workspacesPath + '/' + this.workspace + '/' + (path === '/' ? '' : path)
37+
38+
ret = ret.replace(/^\/|\/$/g, '')
39+
if (!this.isSubDirectory(this.workspacesPath + '/' + this.workspace, ret)) throw new Error('Cannot read/write to path outside workspace')
40+
return ret
41+
}
42+
43+
isSubDirectory (parent, child) {
44+
if (!parent) return false
45+
if (parent === child) return true
46+
const relative = path.relative(parent, child)
47+
48+
return !!relative && relative.split(path.sep)[0] !== '..'
3749
}
3850

3951
resolveDirectory (path, callback) {

libs/remix-ui/file-explorer/src/lib/file-explorer.tsx

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -314,26 +314,32 @@ export const FileExplorer = (props: FileExplorerProps) => {
314314
const createNewFile = (newFilePath: string) => {
315315
const fileManager = state.fileManager
316316

317-
if (helper.checkSpecialChars(newFilePath) || helper.checkSlash(newFilePath)) return toast('special characters are not allowed')
318-
helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => {
319-
if (error) {
320-
modal('Create File Failed', error, {
321-
label: 'Close',
322-
fn: async () => {}
323-
}, null)
324-
} else {
325-
const createFile = await fileManager.writeFile(newName, '')
326-
327-
if (!createFile) {
328-
return toast('Failed to create file ' + newName)
317+
try {
318+
helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => {
319+
if (error) {
320+
modal('Create File Failed', error, {
321+
label: 'Close',
322+
fn: async () => {}
323+
}, null)
329324
} else {
330-
await fileManager.open(newName)
331-
setState(prevState => {
332-
return { ...prevState, focusElement: [{ key: newName, type: 'file' }] }
333-
})
325+
const createFile = await fileManager.writeFile(newName, '')
326+
327+
if (!createFile) {
328+
return toast('Failed to create file ' + newName)
329+
} else {
330+
await fileManager.open(newName)
331+
setState(prevState => {
332+
return { ...prevState, focusElement: [{ key: newName, type: 'file' }] }
333+
})
334+
}
334335
}
335-
}
336-
})
336+
})
337+
} catch (error) {
338+
return modal('File Creation Failed', error.message, {
339+
label: 'Close',
340+
fn: async () => {}
341+
}, null)
342+
}
337343
}
338344

339345
const createNewFolder = async (newFolderPath: string) => {
@@ -354,8 +360,10 @@ export const FileExplorer = (props: FileExplorerProps) => {
354360
return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] }
355361
})
356362
} catch (e) {
357-
console.log('error: ', e)
358-
toast('Failed to create folder: ' + newFolderPath)
363+
return modal('File Creation Failed', e.message, {
364+
label: 'Close',
365+
fn: async () => {}
366+
}, null)
359367
}
360368
}
361369

@@ -393,7 +401,6 @@ export const FileExplorer = (props: FileExplorerProps) => {
393401
fn: () => {}
394402
}, null)
395403
} else {
396-
if (helper.checkSpecialChars(newPath) || helper.checkSlash(newPath)) throw new Error('special characters are not allowed')
397404
await fileManager.rename(oldPath, newPath)
398405
}
399406
} catch (error) {

0 commit comments

Comments
 (0)