From 1e61cfc8f39c5c9c8b25bfd107ba77b77f77ece6 Mon Sep 17 00:00:00 2001 From: Marcello Costagliola Date: Tue, 6 Oct 2026 22:53:47 +0200 Subject: [PATCH] Reject a QR code request that can't become a QR code QrCodeController#show is open without signing in and decodes its id as URL-safe base64. An id that isn't base64 raised ArgumentError, and a URL longer than a QR code holds raised QRCodeRunTimeError, so both answered 500 and reached error reporting as server errors. Answer them with 400 instead. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01LwoX7uRy5vFZSNKJhSqMSG --- app/controllers/qr_code_controller.rb | 2 ++ test/controllers/qr_code_controller_test.rb | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/app/controllers/qr_code_controller.rb b/app/controllers/qr_code_controller.rb index bea6dac..22bd37f 100644 --- a/app/controllers/qr_code_controller.rb +++ b/app/controllers/qr_code_controller.rb @@ -7,5 +7,7 @@ class QrCodeController < ApplicationController expires_in 1.year, public: true render plain: qr_code, content_type: "image/svg+xml" + rescue ArgumentError, RQRCodeCore::QRCodeRunTimeError + head :bad_request end end diff --git a/test/controllers/qr_code_controller_test.rb b/test/controllers/qr_code_controller_test.rb index 13144a2..aa926fb 100644 --- a/test/controllers/qr_code_controller_test.rb +++ b/test/controllers/qr_code_controller_test.rb @@ -12,4 +12,18 @@ class QrCodeControllerTest < ActionDispatch::IntegrationTest assert_equal 1.year, response.cache_control[:max_age].to_i assert response.cache_control[:public] end + + test "show rejects an id that isn't base64" do + get qr_code_path("not-base64!") + + assert_response :bad_request + end + + test "show rejects a URL too long for a QR code" do + id = Base64.urlsafe_encode64("http://example.com/" + "a" * 3000) + + get qr_code_path(id) + + assert_response :bad_request + end end