fix: escape formula characters in CSAT CSV export (#15335)
## Description The CSAT survey response CSV export builds rows with the standard library `CSV`, writing values verbatim, including the feedback message, which is free text submitted by end users. When a cell begins with a formula character (`=`, `+`, `-`, `@`, and tab/CR), spreadsheet applications interpret it as a formula on open. This switches the three `CSV.generate_line` calls in the export template to `CSVSafe.generate_line` (the `csv-safe` gem already used by the v2 report exports), which prefixes such fields so they are treated as text. No new dependency, no behavioural change beyond neutralising formula-leading cells. Ref https://linear.app/chatwoot/issue/CW-7473 ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? `bundle exec rspec spec/controllers/api/v1/accounts/csat_survey_responses_controller_spec.rb` — added a case asserting a formula-leading feedback value is neutralised in the downloaded CSV. ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
]
|
||||
headers << I18n.t('reports.csat.headers.review_notes') if ChatwootApp.enterprise?
|
||||
-%>
|
||||
<%= CSV.generate_line(headers) -%>
|
||||
<%= CSVSafe.generate_line(headers) -%>
|
||||
<% @csat_survey_responses.each do |csat_response| %>
|
||||
<% assigned_agent = csat_response.assigned_agent %>
|
||||
<% contact = csat_response.contact %>
|
||||
@@ -29,10 +29,10 @@
|
||||
]
|
||||
row << csat_response.csat_review_notes if ChatwootApp.enterprise?
|
||||
-%>
|
||||
<%= CSV.generate_line(row).html_safe -%>
|
||||
<%= CSVSafe.generate_line(row).html_safe -%>
|
||||
<% end %>
|
||||
<%=
|
||||
CSV.generate_line([
|
||||
CSVSafe.generate_line([
|
||||
I18n.t(
|
||||
'reports.period',
|
||||
since: Date.strptime(params[:since], '%s'),
|
||||
|
||||
@@ -183,6 +183,18 @@ RSpec.describe 'CSAT Survey Responses API', type: :request do
|
||||
expect(content[1][1]).to eq '1'
|
||||
expect(content.length).to eq 3
|
||||
end
|
||||
|
||||
it 'neutralises formula-leading characters in the feedback column' do
|
||||
create(:csat_survey_response, account: account, feedback_message: '=1+1', created_at: 1.day.ago)
|
||||
|
||||
get "/api/v1/accounts/#{account.id}/csat_survey_responses/download",
|
||||
params: params,
|
||||
headers: administrator.create_new_auth_token
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
injected = CSV.parse(response.body).map { |row| row[2] }.find { |value| value.to_s.include?('1+1') }
|
||||
expect(injected).to start_with("'")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user