mirror of
https://github.com/chatwoot/chatwoot.git
synced 2026-06-04 21:02:35 +08:00
This hardens the development/test Swagger docs endpoint by ensuring requested files are resolved only within the `swagger/` directory. This did not affect production security because the Swagger controller only renders files in development or test environments; production already returns `404`. The change still closes the scanner finding and prevents future automated reports from flagging the development-only path. ## Closes Addresses: GHSA-xhp7-ggjq-p2rg ## How to reproduce 1. Start Chatwoot locally in development. 2. Visit `/swagger/%2Fetc%2Fpasswd`. 3. Before this change, the endpoint could render files outside the Swagger directory in development/test. ## What changed - Resolve Swagger file requests relative to `Rails.root/swagger`. - Return `404` when the resolved path is outside the Swagger directory or does not point to a file. - Strip leading slashes from derived request paths. - Add a request spec for the encoded absolute-path case. ## How to test 1. Start the app locally. 2. Visit `/swagger` and confirm the ReDoc page loads. 3. Visit `/swagger/swagger.json` and confirm the Swagger JSON loads. 4. Visit `/swagger/%2Fetc%2Fpasswd` and confirm it returns `404` with no file contents. Note: `bundle exec rspec spec/controllers/swagger_controller_spec.rb` was passing locally earlier during this fix. A final rerun before opening the PR was blocked because local Postgres on `localhost:5432` was not accepting connections. Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
18 lines
492 B
Ruby
18 lines
492 B
Ruby
require 'rails_helper'
|
|
|
|
describe '/swagger', type: :request do
|
|
describe 'GET /swagger' do
|
|
it 'renders swagger index.html' do
|
|
get '/swagger'
|
|
expect(response).to have_http_status(:success)
|
|
expect(response.body).to include('redoc')
|
|
expect(response.body).to include('/swagger.json')
|
|
end
|
|
|
|
it 'does not render files outside the swagger directory' do
|
|
get '/swagger/%2Fetc%2Fpasswd'
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
end
|
|
end
|