@@ -10,6 +10,7 @@ import path from "path"
1010
1111const SUPPORTED_BACKUP_VERSIONS = [ "1.0" ]
1212const REMOVE_EXISTING_DATA = true
13+ const MAX_BACKUP_SIZE = 256 * 1024 * 1024 // 256MB
1314
1415export async function restoreBackupAction ( prevState : any , formData : FormData ) {
1516 const user = await getCurrentUser ( )
@@ -20,6 +21,10 @@ export async function restoreBackupAction(prevState: any, formData: FormData) {
2021 return { success : false , error : "No file provided" }
2122 }
2223
24+ if ( file . size > MAX_BACKUP_SIZE ) {
25+ return { success : false , error : `Backup file too large. Maximum size is ${ MAX_BACKUP_SIZE / 1024 / 1024 } MB` }
26+ }
27+
2328 // Read zip archive
2429 let zip : JSZip
2530 try {
@@ -88,20 +93,24 @@ export async function restoreBackupAction(prevState: any, formData: FormData) {
8893 const userUploadsDirectory = await getUserUploadsDirectory ( user )
8994
9095 for ( const file of files ) {
91- const filePathWithoutPrefix = file . path . replace ( / ^ .* \/ u p l o a d s \/ / , "" )
96+ const filePathWithoutPrefix = path . normalize ( file . path . replace ( / ^ .* \/ u p l o a d s \/ / , "" ) )
9297 const zipFilePath = path . join ( "data/uploads" , filePathWithoutPrefix )
9398 const zipFile = zip . file ( zipFilePath )
9499 if ( ! zipFile ) {
95100 console . log ( `File ${ file . path } not found in backup` )
96101 continue
97102 }
98103
104+ const fileContents = await zipFile . async ( "nodebuffer" )
99105 const fullFilePath = path . join ( userUploadsDirectory , filePathWithoutPrefix )
100- const fileContent = await zipFile . async ( "nodebuffer" )
106+ if ( ! fullFilePath . startsWith ( path . normalize ( userUploadsDirectory ) ) ) {
107+ console . error ( `Attempted path traversal detected for file ${ file . path } ` )
108+ continue
109+ }
101110
102111 try {
103112 await fs . mkdir ( path . dirname ( fullFilePath ) , { recursive : true } )
104- await fs . writeFile ( fullFilePath , fileContent )
113+ await fs . writeFile ( fullFilePath , fileContents )
105114 restoredFilesCount ++
106115 } catch ( error ) {
107116 console . error ( `Error writing file ${ fullFilePath } :` , error )
0 commit comments