Merge pull request #1052 from ethereum/enforce-checks

Restrict file operations to workspace / shared folder.
pull/1027/head
David Disu 4 years ago committed by GitHub
commit 3328087fd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      apps/remix-ide/src/app/files/workspaceFileProvider.js
  2. 47
      libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
  3. 16
      libs/remixd/src/utils.ts
  4. 4
      package.json

@ -1,6 +1,7 @@
'use strict'
const FileProvider = require('./fileProvider')
const pathModule = require('path')
class WorkspaceFileProvider extends FileProvider {
constructor () {
@ -32,8 +33,19 @@ class WorkspaceFileProvider extends FileProvider {
if (path.startsWith(this.workspacesPath + '/' + this.workspace)) return path
if (path.startsWith(this.workspace)) return this.workspacesPath + '/' + this.workspace
path = super.removePrefix(path)
const ret = this.workspacesPath + '/' + this.workspace + '/' + (path === '/' ? '' : path)
return ret.replace(/^\/|\/$/g, '')
let ret = this.workspacesPath + '/' + this.workspace + '/' + (path === '/' ? '' : path)
ret = ret.replace(/^\/|\/$/g, '')
if (!this.isSubDirectory(this.workspacesPath + '/' + this.workspace, ret)) throw new Error('Cannot read/write to path outside workspace')
return ret
}
isSubDirectory (parent, child) {
if (!parent) return false
if (parent === child) return true
const relative = pathModule.relative(parent, child)
return !!relative && relative.split(pathModule.sep)[0] !== '..'
}
resolveDirectory (path, callback) {

@ -314,25 +314,32 @@ export const FileExplorer = (props: FileExplorerProps) => {
const createNewFile = (newFilePath: string) => {
const fileManager = state.fileManager
helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => {
if (error) {
modal('Create File Failed', error, {
label: 'Close',
fn: async () => {}
}, null)
} else {
const createFile = await fileManager.writeFile(newName, '')
if (!createFile) {
return toast('Failed to create file ' + newName)
try {
helper.createNonClashingName(newFilePath, filesProvider, async (error, newName) => {
if (error) {
modal('Create File Failed', error, {
label: 'Close',
fn: async () => {}
}, null)
} else {
await fileManager.open(newName)
setState(prevState => {
return { ...prevState, focusElement: [{ key: newName, type: 'file' }] }
})
const createFile = await fileManager.writeFile(newName, '')
if (!createFile) {
return toast('Failed to create file ' + newName)
} else {
await fileManager.open(newName)
setState(prevState => {
return { ...prevState, focusElement: [{ key: newName, type: 'file' }] }
})
}
}
}
})
})
} catch (error) {
return modal('File Creation Failed', error.message, {
label: 'Close',
fn: async () => {}
}, null)
}
}
const createNewFolder = async (newFolderPath: string) => {
@ -353,8 +360,10 @@ export const FileExplorer = (props: FileExplorerProps) => {
return { ...prevState, focusElement: [{ key: newFolderPath, type: 'folder' }] }
})
} catch (e) {
console.log('error: ', e)
toast('Failed to create folder: ' + newFolderPath)
return modal('Folder Creation Failed', e.message, {
label: 'Close',
fn: async () => {}
}, null)
}
}

@ -12,9 +12,25 @@ import * as pathModule from 'path'
function absolutePath (path: string, sharedFolder:string): string {
path = normalizePath(path)
path = pathModule.resolve(sharedFolder, path)
if (!isSubDirectory(pathModule.resolve(process.cwd(), sharedFolder), path)) throw new Error('Cannot read/write to path outside shared folder.')
return path
}
/**
* returns a true if child is sub-directory of parent.
*
* @param {String} parent - path to parent directory
* @param {String} child - child path
* @return {Boolean}
*/
function isSubDirectory (parent: string, child: string) {
if (!parent) return false
if (parent === child) return true
const relative = pathModule.relative(parent, child)
return !!relative && relative.split(pathModule.sep)[0] !== '..'
}
/**
* return the relative path of the given @arg path
*

@ -67,7 +67,7 @@
"nightwatch_local_signingMessage": "npm run build:e2e & nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/signingMessage.test.js --env=chrome",
"nightwatch_local_specialFunctions": "npm run build:e2e & nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/specialFunctions.test.js --env=chrome",
"nightwatch_local_solidityUnitTests": "npm run build:e2e & nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/solidityUnittests.test.js --env=chrome",
"nightwatch_local_remixd": "npm run build:e2e & nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/remixd.test.js --env=chrome",
"nightwatch_local_remixd": "npm run build:e2e && nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/remixd.test.js --env=chrome",
"nightwatch_local_terminal": "npm run build:e2e & nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/terminal.test.js --env=chrome",
"nightwatch_local_gist": "npm run build:e2e & nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/gist.test.js --env=chrome",
"nightwatch_local_workspace": "npm run build:e2e & nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/workspace.test.js --env=chrome",
@ -85,7 +85,7 @@
"nightwatch_local_url": "npm run build:e2e & nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/url.test.js --env=chrome",
"nightwatch_local_verticalIconscontextmenu": "npm run build:e2e & nightwatch --config dist/apps/remix-ide-e2e/nightwatch.js dist/apps/remix-ide-e2e/src/tests/verticalIconsPanel.test.js --env=chrome",
"onchange": "onchange apps/remix-ide/build/app.js -- npm-run-all lint",
"remixd": "nx build remixd & nx serve remixd --folder=./apps/remix-ide/contracts --remixide=http://127.0.0.1:8080",
"remixd": "nx build remixd && nx serve remixd --folder=./apps/remix-ide/contracts --remixide=http://127.0.0.1:8080",
"selenium": "selenium-standalone start",
"selenium-install": "selenium-standalone install",
"sourcemap": "exorcist --root ../ apps/remix-ide/build/app.js.map > apps/remix-ide/build/app.js",

Loading…
Cancel
Save