class Phlex::CSV
def call(buffer = +"", view_context: nil)
def call(buffer = +"", view_context: nil) unless escape_csv_injection? == true || escape_csv_injection? == false raise <<~MESSAGE You need to define escape_csv_injection? in #{self.class.name}, returning either `true` or `false`. CSV injection is a security vulnerability where malicious spreadsheet formulae are used to execute code or exfiltrate data when a CSV is opened in a spreadsheet program such as Microsoft Excel or Google Sheets. For more information, see https://owasp.org/www-community/attacks/CSV_Injection If you're sure this CSV will never be opened in a spreadsheet program, you can disable CSV injection escapes: def escape_csv_injection? = false This is useful when using CSVs for byte-for-byte data exchange between secure systems. Alternatively, you can enable CSV injection escapes at the cost of data integrity: def escape_csv_injection? = true Note: Enabling the CSV injection escapes will prefix any values that start with `=`, `+`, `-`, `@`, `\\t`, or `\\r` with a single quote `'` to prevent them from being interpreted as formulae by spreadsheet programs. Unfortunately, there is no one-size-fits-all solution to CSV injection. You need to decide based on your specific use case. MESSAGE end @_view_context = view_context each_item do |record| yielder(record) do |*args, **kwargs| view_template(*args, **kwargs) if @_first && render_headers? buffer << @_headers.join(",") << "\n" end buffer << @_current_row.join(",") << "\n" @_current_column_index = 0 @_current_row.clear end @_first = false end buffer end