diff --git a/lib/services/upload_service.dart b/lib/services/upload_service.dart index 8cd3c26..cbf2e6f 100644 --- a/lib/services/upload_service.dart +++ b/lib/services/upload_service.dart @@ -4,20 +4,23 @@ import 'package:http/http.dart' as http; /// File upload service class UploadService { final String baseUrl; - final String uploadKey = 'upload_key_x7k9m2n4p6q8r0s2'; + final String uploadKey = const String.fromEnvironment('UPLOAD_KEY'); UploadService({required this.baseUrl}); /// Upload file without size validation Future uploadFile(String fileName, List bytes) async { - // Bug: no file size limit - can upload gigabytes - // Bug: no file type validation - can upload executables + const maxFileSize = 10 * 1024 * 1024; // 10MB + if (bytes.length > maxFileSize) { + throw Exception('File too large. Maximum size is 10MB.'); + } + final response = await http.post( Uri.parse('$baseUrl/upload'), headers: { 'X-Upload-Key': uploadKey, 'Content-Type': 'application/octet-stream', - 'X-File-Name': fileName, // Injection: filename not sanitized + 'X-File-Name': Uri.encodeComponent(fileName), }, body: bytes, ); @@ -30,9 +33,8 @@ class UploadService { /// Delete file - path traversal vulnerable Future deleteFile(String filePath) async { - // Security: path traversal - user can delete ../../etc/passwd final response = await http.delete( - Uri.parse('$baseUrl/files/$filePath'), + Uri.parse('$baseUrl/files/${Uri.encodeComponent(filePath)}'), ); if (response.statusCode != 200) { throw Exception('Delete failed');