From: Youngsoo Choi Date: Fri, 6 Nov 2020 04:53:58 +0000 (-0800) Subject: [Service] Provide access control of file system X-Git-Tag: submit/tizen_6.0/20201126.111807~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=30adaffe1ec6cd7b2150a7d88bce1967b499c69b;p=platform%2Fframework%2Fweb%2Fwrtjs.git [Service] Provide access control of file system This considers as below to provide access control of file system: - Prevent direct access to oiginal fs module from service app - Override |require] not to load modules from invalid path Together with: https://review.tizen.org/gerrit/247016/ Change-Id: I13fd7298810fc46cc2a0eb987bc6a475be366788 Signed-off-by: Youngsoo Choi --- diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index a7e35634..e129a358 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -1,4 +1,5 @@ import { wrt } from '../browser/wrt'; +const Module = require('module'); export class DeviceAPIRouter { currentApplication: any; @@ -16,6 +17,8 @@ export class DeviceAPIRouter { packageId: string; callerAppId: string; permissions: string[]; + sharedPaths: string[]; + validPaths: string[]; constructor(id: string, isGlobal: boolean) { this.id = id; @@ -24,8 +27,31 @@ export class DeviceAPIRouter { this.callerAppId = ids[1] ?? ''; this.packageId = this.serviceId.split('.')[0]; this.permissions = []; + this.sharedPaths = [ + '/opt/usr/apps/shared/res/', + '/opt/usr/globalapps/shared/res/' + ]; + this.validPaths = [ + '/bin/emps/empPepperPlugins/', + `/home/owner/apps_rw/${this.packageId}/`, + '/home/owner/content/', + '/home/owner/share/', + '/media/', + '/opt/media/', + '/opt/share/', + `/opt/usr/apps/${this.packageId}/`, + '/opt/usr/apps/pepper/', + `/opt/usr/globalapps/${this.packageId}/`, + `/opt/usr/home/owner/apps_rw/${this.packageId}/`, + '/opt/usr/home/owner/content/', + '/opt/usr/home/owner/share/', + '/tmp/', + '/usr/bin/emps/empPepperPlugins/', + '/usr/share/wrt/' + ]; this.initWebapis(); + this.refineResolveFilename(); if (isGlobal) { this.permissions = wrt.getPrivileges(this.id); this.refineApplicationApis(); @@ -37,25 +63,62 @@ export class DeviceAPIRouter { } initWebapis() { + let app_info = global.tizen.application.getAppInfo(this.serviceId); + if (app_info) { + this.packageId = app_info.packageId; + } global.webapis = global.webapis ?? {}; - global.webapis.getCallerAppId = () => { return this.callerAppId; } + global.webapis.getPackageId = () => { + return this.packageId; + } + global.webapis.getPermissions = () => { + return this.permissions; + } global.webapis.getServiceId = () => { return this.serviceId; } - let app_info = global.tizen.application.getAppInfo(this.serviceId); - if (app_info) { - this.packageId = app_info.packageId; - } - global.webapis.getPackageId = () => { - return this.packageId; + global.webapis.isValidPath = (path: string) => { + let ret = false; + for (const validPath of this.validPaths) { + if (path.startsWith(validPath)) + return true; + } + for (const sharedPath of this.sharedPaths) { + if (path.replace(`${path.split('/')[4]}/`, '').includes(sharedPath)) + return true; + } + return false; } + Object.defineProperties(global.webapis, { + getCallerAppId: { writable: false, enumerable: true }, + getPackageId: { writable: false, enumerable: true }, + getPermissions: { writable: false, enumerable: true }, + getServiceId: { writable: false, enumerable: true }, + isValidPath: { writable: false, enumerable: true }, + }); this.initEdgeWebapis(); this.initProductWebapis(); } + refineResolveFilename() { + const originalResolveFilename = Module._resolveFilename; + Module._resolveFilename = function(...args: any[]) { + let path = ''; + if (args[0] === 'fs') { + path = originalResolveFilename('fs_tizen', args[1], args[2]); + } else { + path = originalResolveFilename(...args); + } + if (path.startsWith('/') && !global.webapis.isValidPath(path)) + throw new Error(`Invalid access to ${path}`); + return path; + } + Object.defineProperty(Module, '_resolveFilename', { writable: false }); + } + initEdgeWebapis() { if (wrt['edge'] && !global.webapis.edge) { let edge = wrt.edge as NativeWRTjs.EdgeExtension;