{"record":{"id":"0f406d39871b4a58","repo":"carrierwaveuploader/carrierwave","slug":"invalid-filename","errorCode":null,"errorMessage":"invalid filename","messagePattern":"invalid filename","errorType":"exception","errorClass":"CarrierWave::InvalidParameter","httpStatus":null,"severity":"error","filePath":"lib/carrierwave/uploader/cache.rb","lineNumber":209,"sourceCode":"      attr_reader :cache_id\n\n    private\n\n      def workfile_path(for_file=original_filename)\n        File.join(CarrierWave.tmp_path, @cache_id, version_name.to_s, for_file)\n      end\n\n      attr_reader :original_filename\n\n      def cache_id=(cache_id)\n        # Earlier version used 3 part cache_id. Thus we should allow for\n        # the cache_id to have both 3 part and 4 part formats.\n        raise CarrierWave::InvalidParameter, \"invalid cache id\" unless cache_id =~ /\\A(-)?[\\d]+\\-[\\d]+(\\-[\\d]{4})?\\-[\\d]{4}\\z/\n        @cache_id = cache_id\n      end\n\n      def original_filename=(filename)\n        raise CarrierWave::InvalidParameter, \"invalid filename\" if filename =~ CarrierWave::SanitizedFile.sanitize_regexp\n        @original_filename = filename\n      end\n\n      def cache_storage\n        @cache_storage ||= (self.class.cache_storage || self.class.storage).new(self)\n      end\n\n      # We can override the full_original_filename method in other modules\n      def full_original_filename\n        forcing_extension(original_filename)\n      end\n    end # Cache\n  end # Uploader\nend # CarrierWave\n","sourceCodeStart":191,"sourceCodeEnd":224,"githubUrl":"https://github.com/carrierwaveuploader/carrierwave/blob/b5f0abe10ecf6500309fc83e0e8969cf57ba690e/lib/carrierwave/uploader/cache.rb#L191-L224","documentation":"Raised as CarrierWave::InvalidParameter by Uploader::Cache#original_filename= when the filename portion contains characters matched by CarrierWave::SanitizedFile.sanitize_regexp (/[^[:word:]\\.\\-+]/) — i.e. anything other than letters, digits, underscore, dot, dash, or plus. This guards the cache path against filenames that could escape or corrupt the cache directory (slashes, '../', spaces, parentheses, null bytes).","triggerScenarios":"retrieve_from_cache!(cache_name) where the part after the slash contains unsafe characters (e.g. '../evil.php', 'my photo (1).jpg'), or any code assigning uploader.original_filename = with a raw user-supplied name. The normal cache! flow is safe because it wraps files in SanitizedFile which replaces such characters before this setter runs.","commonSituations":"Tampered hidden cache field replaying a filename with traversal characters; client code rebuilding cache names from user input; middleware or JS upload widgets that re-encode the filename and introduce characters outside the allowed set.","solutions":["Validate/sanitize the filename before retrieve: filename.gsub(/[^[:word:]\\.\\-+]/, '_')","Pass through the untouched uploader-provided cache_name instead of reconstructing it client-side","Rescue CarrierWave::InvalidParameter and reject the request as malformed"],"exampleFix":"# before\ncache_name = \"#{params[:cache_id]}/#{params[:filename]}\"\nuploader.retrieve_from_cache!(cache_name) # 'my photo.jpg' -> InvalidParameter\n\n# after\nsafe_name = params[:filename].to_s.gsub(/[^[:word:]\\.\\-+]/, '_')\nuploader.retrieve_from_cache!(\"#{params[:cache_id]}/#{safe_name}\")","handlingStrategy":"validation","validationCode":"UNSAFE_FILENAME = /[^[:word:]\\.\\-+]/\n\ndef sanitize_upload_filename(name)\n  File.basename(name.to_s).gsub(UNSAFE_FILENAME, '_')\nend\n\ncache_name = \"#{params[:cache_id]}/#{sanitize_upload_filename(params[:filename])}\"","typeGuard":"def safe_filename?(name)\n  !name.to_s.match?(CarrierWave::SanitizedFile.sanitize_regexp)\nend","tryCatchPattern":"begin\n  uploader.retrieve_from_cache!(cache_name)\nrescue CarrierWave::InvalidParameter\n  head :bad_request # treat tampered cache field as malformed input\nend","preventionTips":["Round-trip the exact uploader-provided cache_name; never reconstruct the filename portion from user input","Strip/replace characters outside [word . - +] in any filename you feed into retrieve_from_cache!","Treat CarrierWave::InvalidParameter on cache retrieval as hostile input: log and reject, do not retry"],"tags":["carrierwave","filename","sanitization","security","cache"],"backgroundTag":"filename-sanitization","analyzedSha":"b5f0abe10ecf6500309fc83e0e8969cf57ba690e","analyzedAt":"2026-08-21T18:07:27.715Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}