Problème avec create_second_factor_totp

Début de la requête POST "/u/create_second_factor_totp.json" depuis 209.249.35.130 le 2020-02-19 à 14:21:20 +0000
Traitement par UsersController#create_second_factor_totp au format JSON
Terminé avec une erreur 500 Internal Server Error en 5 ms (ActiveRecord : 0,0 ms | Allocations : 1781)
Addressable::URI::InvalidURIError (Format de schéma invalide : Our Great Forum)
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/uri.rb:901:in `scheme='
  Rendu du modèle texte
  Modèle texte rendu (Durée : 0,0 ms | Allocations : 1)

« Our Great Forum » est presque le titre du forum défini dans les paramètres système. La valeur réelle ressemble à quelque chose comme « Our Great Forum : Our fine tagline », donc ce qui apparaît dans le journal n’est que la partie avant les deux-points. Je ne vois pas « Our Great Forum » ailleurs dans les paramètres système, donc je suis perplexe quant à la raison pour laquelle il apparaîtrait sans la partie : tagline dans le journal.

Soupir. Il s’agit de la version 2.4.0.beta10 (6301477b4c). Je vais procéder à la mise à jour et leur demander de réessayer. Je modifierai ce message si je parviens à faire essayer à l’utilisateur la dernière version.

2 « J'aime »

Que vous indique la trace d’exécution dans /logs ?

C’est tout ce que je vois dans les journaux. Je ne vois pas de trace d’exécution. Cependant, j’obtiens l’erreur simplement en cliquant sur « nouveau authentificateur » dans la section « authentificateurs basés sur des jetons ».

Et c’est la même chose après la dernière mise à niveau.

Ouh là. Oui, il y a quelque chose qui ne va pas.

Pourriez-vous copier la requête sous forme de curl et la poster (en masquant tout PII et les jetons/nonces) afin que nous puissions déterminer si le problème vient du client ou du serveur ?

5 « J'aime »

Can confirm that if you have a title with a space before a colon this causes a failure on latest:

with SiteSetting.title = "It's Spaceballs: The Discourse" I get an error clicking on:
image

Addressable::URI::InvalidURIError in UsersController#create_second_factor_totp

Invalid scheme format: It's Spaceballs
Extracted source (around line #901):

#899       end
#900       if new_scheme && new_scheme !~ /\A[a-z][a-z0-9\.\+\-]*\z/i
*901         raise InvalidURIError, "Invalid scheme format: #{new_scheme}"
#902       end
#903       @scheme = new_scheme
#904       @scheme = nil if @scheme.to_s.strip.empty?

Extracted source (around line #826):

#824         # Bunch of crazy logic required because of the composite components
#825         # like userinfo and authority.
*826         self.scheme = options[:scheme] if options[:scheme]
#827         self.user = options[:user] if options[:user]
#828         self.password = options[:password] if options[:password]
#829         self.userinfo = options[:userinfo] if options[:userinfo]

Extracted source (around line #2392):

#2390       raise LocalJumpError, "No block given." unless block_given?
#2391       @validation_deferred = true
*2392       yield
#2393       @validation_deferred = false
#2394       validate
#2395       return nil


Rails.root: /home/michael/prog/Discourse/discourse

Application Trace
app/models/concerns/second_factor_manager.rb:27:in `totp_provisioning_uri'
app/controllers/users_controller.rb:1148:in `create_second_factor_totp'
lib/middleware/omniauth_bypass_middleware.rb:68:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
config/initializers/100-quiet_logger.rb:18:in `call'
config/initializers/100-silence_logger.rb:31:in `call'
lib/middleware/missing_avatars.rb:23:in `call'
lib/middleware/turbo_dev.rb:34:in `call'

Framework Trace
addressable (2.7.0) lib/addressable/uri.rb:901:in `scheme='
addressable (2.7.0) lib/addressable/uri.rb:826:in `block in initialize'
addressable (2.7.0) lib/addressable/uri.rb:2392:in `defer_validation'
addressable (2.7.0) lib/addressable/uri.rb:823:in `initialize'
addressable (2.7.0) lib/addressable/uri.rb:138:in `new'
addressable (2.7.0) lib/addressable/uri.rb:138:in `parse'
addressable (2.7.0) lib/addressable/uri.rb:607:in `encode'
rotp (5.1.0) lib/rotp/totp.rb:61:in `provisioning_uri'
actionpack (6.0.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (6.0.1) lib/abstract_controller/base.rb:196:in `process_action'
actionpack (6.0.1) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (6.0.1) lib/abstract_controller/callbacks.rb:42:in `block in process_action'
activesupport (6.0.1) lib/active_support/callbacks.rb:135:in `run_callbacks'
actionpack (6.0.1) lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack (6.0.1) lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack (6.0.1) lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
activesupport (6.0.1) lib/active_support/notifications.rb:180:in `block in instrument'
activesupport (6.0.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (6.0.1) lib/active_support/notifications.rb:180:in `instrument'
actionpack (6.0.1) lib/action_controller/metal/instrumentation.rb:32:in `process_action'
actionpack (6.0.1) lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
activerecord (6.0.1) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (6.0.1) lib/abstract_controller/base.rb:136:in `process'
actionview (6.0.1) lib/action_view/rendering.rb:39:in `process'
rack-mini-profiler (1.1.6) lib/mini_profiler/profiling_methods.rb:104:in `block in profile_method'
actionpack (6.0.1) lib/action_controller/metal.rb:191:in `dispatch'
actionpack (6.0.1) lib/action_controller/metal.rb:252:in `dispatch'
actionpack (6.0.1) lib/action_dispatch/routing/route_set.rb:51:in `dispatch'
actionpack (6.0.1) lib/action_dispatch/routing/route_set.rb:33:in `serve'
actionpack (6.0.1) lib/action_dispatch/journey/router.rb:49:in `block in serve'
actionpack (6.0.1) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (6.0.1) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (6.0.1) lib/action_dispatch/routing/route_set.rb:837:in `call'
rack (2.0.8) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.0.8) lib/rack/conditional_get.rb:38:in `call'
rack (2.0.8) lib/rack/head.rb:12:in `call'
rack (2.0.8) lib/rack/session/abstract/id.rb:259:in `context'
rack (2.0.8) lib/rack/session/abstract/id.rb:253:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/cookies.rb:648:in `call'
activerecord (6.0.1) lib/active_record/migration.rb:567:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (6.0.1) lib/active_support/callbacks.rb:101:in `run_callbacks'
actionpack (6.0.1) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
logster (2.6.3) lib/logster/middleware/reporter.rb:43:in `call'
railties (6.0.1) lib/rails/rack/logger.rb:38:in `call_app'
railties (6.0.1) lib/rails/rack/logger.rb:28:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.0.8) lib/rack/method_override.rb:22:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/static.rb:126:in `call'
rack (2.0.8) lib/rack/sendfile.rb:111:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/host_authorization.rb:83:in `call'
rack-mini-profiler (1.1.6) lib/mini_profiler/profiler.rb:296:in `call'
message_bus (2.2.3) lib/message_bus/rack/middleware.rb:57:in `call'
railties (6.0.1) lib/rails/engine.rb:526:in `call'
railties (6.0.1) lib/rails/railtie.rb:190:in `public_send'
railties (6.0.1) lib/rails/railtie.rb:190:in `method_missing'
rack (2.0.8) lib/rack/urlmap.rb:68:in `block in call'
rack (2.0.8) lib/rack/urlmap.rb:53:in `each'
rack (2.0.8) lib/rack/urlmap.rb:53:in `call'
unicorn (5.5.3) lib/unicorn/http_server.rb:605:in `process_client'
unicorn (5.5.3) lib/unicorn/http_server.rb:700:in `worker_loop'
unicorn (5.5.3) lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
unicorn (5.5.3) lib/unicorn/http_server.rb:144:in `start'
unicorn (5.5.3) bin/unicorn:128:in `<top (required)>'
bin/unicorn:87:in `load'
bin/unicorn:87:in `block in <main>'
bin/unicorn:86:in `fork'
bin/unicorn:86:in `<main>'

Full Trace
addressable (2.7.0) lib/addressable/uri.rb:901:in `scheme='
addressable (2.7.0) lib/addressable/uri.rb:826:in `block in initialize'
addressable (2.7.0) lib/addressable/uri.rb:2392:in `defer_validation'
addressable (2.7.0) lib/addressable/uri.rb:823:in `initialize'
addressable (2.7.0) lib/addressable/uri.rb:138:in `new'
addressable (2.7.0) lib/addressable/uri.rb:138:in `parse'
addressable (2.7.0) lib/addressable/uri.rb:607:in `encode'
rotp (5.1.0) lib/rotp/totp.rb:61:in `provisioning_uri'
app/models/concerns/second_factor_manager.rb:27:in `totp_provisioning_uri'
app/controllers/users_controller.rb:1148:in `create_second_factor_totp'
actionpack (6.0.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (6.0.1) lib/abstract_controller/base.rb:196:in `process_action'
actionpack (6.0.1) lib/action_controller/metal/rendering.rb:30:in `process_action'
actionpack (6.0.1) lib/abstract_controller/callbacks.rb:42:in `block in process_action'
activesupport (6.0.1) lib/active_support/callbacks.rb:135:in `run_callbacks'
actionpack (6.0.1) lib/abstract_controller/callbacks.rb:41:in `process_action'
actionpack (6.0.1) lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack (6.0.1) lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
activesupport (6.0.1) lib/active_support/notifications.rb:180:in `block in instrument'
activesupport (6.0.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (6.0.1) lib/active_support/notifications.rb:180:in `instrument'
actionpack (6.0.1) lib/action_controller/metal/instrumentation.rb:32:in `process_action'
actionpack (6.0.1) lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
activerecord (6.0.1) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (6.0.1) lib/abstract_controller/base.rb:136:in `process'
actionview (6.0.1) lib/action_view/rendering.rb:39:in `process'
rack-mini-profiler (1.1.6) lib/mini_profiler/profiling_methods.rb:104:in `block in profile_method'
actionpack (6.0.1) lib/action_controller/metal.rb:191:in `dispatch'
actionpack (6.0.1) lib/action_controller/metal.rb:252:in `dispatch'
actionpack (6.0.1) lib/action_dispatch/routing/route_set.rb:51:in `dispatch'
actionpack (6.0.1) lib/action_dispatch/routing/route_set.rb:33:in `serve'
actionpack (6.0.1) lib/action_dispatch/journey/router.rb:49:in `block in serve'
actionpack (6.0.1) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (6.0.1) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (6.0.1) lib/action_dispatch/routing/route_set.rb:837:in `call'
lib/middleware/omniauth_bypass_middleware.rb:68:in `call'
rack (2.0.8) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.0.8) lib/rack/conditional_get.rb:38:in `call'
rack (2.0.8) lib/rack/head.rb:12:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
rack (2.0.8) lib/rack/session/abstract/id.rb:259:in `context'
rack (2.0.8) lib/rack/session/abstract/id.rb:253:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/cookies.rb:648:in `call'
activerecord (6.0.1) lib/active_record/migration.rb:567:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (6.0.1) lib/active_support/callbacks.rb:101:in `run_callbacks'
actionpack (6.0.1) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/debug_exceptions.rb:32:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
logster (2.6.3) lib/logster/middleware/reporter.rb:43:in `call'
railties (6.0.1) lib/rails/rack/logger.rb:38:in `call_app'
railties (6.0.1) lib/rails/rack/logger.rb:28:in `call'
config/initializers/100-quiet_logger.rb:18:in `call'
config/initializers/100-silence_logger.rb:31:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/request_id.rb:27:in `call'
rack (2.0.8) lib/rack/method_override.rb:22:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/static.rb:126:in `call'
rack (2.0.8) lib/rack/sendfile.rb:111:in `call'
actionpack (6.0.1) lib/action_dispatch/middleware/host_authorization.rb:83:in `call'
lib/middleware/missing_avatars.rb:23:in `call'
lib/middleware/turbo_dev.rb:34:in `call'
rack-mini-profiler (1.1.6) lib/mini_profiler/profiler.rb:296:in `call'
message_bus (2.2.3) lib/message_bus/rack/middleware.rb:57:in `call'
railties (6.0.1) lib/rails/engine.rb:526:in `call'
railties (6.0.1) lib/rails/railtie.rb:190:in `public_send'
railties (6.0.1) lib/rails/railtie.rb:190:in `method_missing'
rack (2.0.8) lib/rack/urlmap.rb:68:in `block in call'
rack (2.0.8) lib/rack/urlmap.rb:53:in `each'
rack (2.0.8) lib/rack/urlmap.rb:53:in `call'
unicorn (5.5.3) lib/unicorn/http_server.rb:605:in `process_client'
unicorn (5.5.3) lib/unicorn/http_server.rb:700:in `worker_loop'
unicorn (5.5.3) lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
unicorn (5.5.3) lib/unicorn/http_server.rb:144:in `start'
unicorn (5.5.3) bin/unicorn:128:in `<top (required)>'
bin/unicorn:87:in `load'
bin/unicorn:87:in `block in <main>'
bin/unicorn:86:in `fork'
bin/unicorn:86:in `<main>'



Request parameters
{"format"=>"json"}

Session dump
_csrf_token: "lk/NmJ0SlnTWvQ3HeeP22fzMicKdW/pPwzlLgi0tgY="
secure_session_id: "a16cc4e497b750f5bb1a310612427e54"
session_id: "4f2f8c8f2610c51914ff03a8e3e5f053"

Env dump
HTTP_ACCEPT: "*/*"
HTTP_ACCEPT_ENCODING: "gzip, deflate, br"
HTTP_ACCEPT_LANGUAGE: "en-GB,en-US;q=0.9,en;q=0.8,fr-CA;q=0.7,fr;q=0.6"
HTTP_ORIGIN: "http://localhost:3000"
HTTP_VERSION: "HTTP/1.1"
HTTP_X_CSRF_TOKEN: "Sv2Q7IKSgtoO7bd4aApBiX/qyGqJHknnTjncA9yNMzaevU0MGI5HHlIx/3hS65tsO01xqmnLc15RFuUa0TsEsA=="
ORIGINAL_SCRIPT_NAME: ""
REMOTE_ADDR: "127.0.0.1"
SERVER_NAME: "localhost"
SERVER_PROTOCOL: "HTTP/1.1"

Response headers
None

Here’s a failing spec:

diff --git a/spec/components/concern/second_factor_manager_spec.rb b/spec/components/concern/second_factor_manager_spec.rb
index 36e4f066ce..a657a0fdc8 100644
--- a/spec/components/concern/second_factor_manager_spec.rb
+++ b/spec/components/concern/second_factor_manager_spec.rb
@@ -47,6 +47,18 @@ RSpec.describe SecondFactorManager do
         "otpauth://totp/#{SiteSetting.title}:#{user.email}?secret=#{user_second_factor_totp.data}&issuer=#{SiteSetting.title}"
       )
     end
+    it 'should handle a colon in the site title' do
+      SiteSetting.title = 'Spaceballs: The Discourse'
+      expect(user.user_second_factors.totps.first.totp_provisioning_uri).to eq(
+        "otpauth://totp/#{URI::escape SiteSetting.title}:#{user.email}?secret=#{user_second_factor_totp.data}&issuer=#{CGI::escape SiteSetting.title}"
+      )
+    end
+    it 'should handle a space before a colon in the site title' do
+      SiteSetting.title = 'Our Spaceballs: The Discourse'
+      expect(user.user_second_factors.totps.first.totp_provisioning_uri).to eq(
+        "otpauth://totp/#{URI::escape SiteSetting.title}:#{user.email}?secret=#{user_second_factor_totp.data}&issuer=#{CGI::escape SiteSetting.title}"
+      )
+    end
   end
 
   describe '#authenticate_totp' do
→ RAILS_ENV=test rspec ./spec/components/concern/second_factor_manager_spec.rb

Randomized with seed 47333
...................F......................

Failures:

  1) SecondFactorManager#totp_provisioning_uri should handle a space before a colon in the site title
     Failure/Error: totp_object.provisioning_uri(user.email)
     
     Addressable::URI::InvalidURIError:
       Invalid scheme format: Our Spaceballs
     # /home/michael/.rvm/gems/ruby-2.6.3/gems/addressable-2.7.0/lib/addressable/uri.rb:901:in `scheme='
     # /home/michael/.rvm/gems/ruby-2.6.3/gems/addressable-2.7.0/lib/addressable/uri.rb:826:in `block in initialize'
     # /home/michael/.rvm/gems/ruby-2.6.3/gems/addressable-2.7.0/lib/addressable/uri.rb:2392:in `defer_validation'
     # /home/michael/.rvm/gems/ruby-2.6.3/gems/addressable-2.7.0/lib/addressable/uri.rb:823:in `initialize'
     # /home/michael/.rvm/gems/ruby-2.6.3/gems/addressable-2.7.0/lib/addressable/uri.rb:138:in `new'
     # /home/michael/.rvm/gems/ruby-2.6.3/gems/addressable-2.7.0/lib/addressable/uri.rb:138:in `parse'
     # /home/michael/.rvm/gems/ruby-2.6.3/gems/addressable-2.7.0/lib/addressable/uri.rb:607:in `encode'
     # /home/michael/.rvm/gems/ruby-2.6.3/gems/rotp-5.1.0/lib/rotp/totp.rb:61:in `provisioning_uri'
     # ./app/models/user_second_factor.rb:32:in `totp_provisioning_uri'
     # ./spec/components/concern/second_factor_manager_spec.rb:58:in `block (3 levels) in <top (required)>'

Finished in 0.75471 seconds (files took 2.18 seconds to load)
42 examples, 1 failure

Failed examples:

rspec ./spec/components/concern/second_factor_manager_spec.rb:56 # SecondFactorManager#totp_provisioning_uri should handle a space before a colon in the site title

Randomized with seed 47333
5 « J'aime »

Cela devrait régler le problème :

9 « J'aime »

Changer l’émetteur modifie les valeurs du jeton, mais comme cela était complètement cassé pour les deux-points, cela ne devrait pas impacter de nouveaux utilisateurs.

Notez que cela fonctionnait auparavant pour les titres contenant un deux-points, comme Spaceballs: The Discourse (cela a bien fonctionné pour moi et j’ai pu l’ajouter à mon téléphone), mais échouait lorsqu’il y avait deux mots avant le deux-points.

(désolé si ce n’était pas très clair dans mon rapport)

3 « J'aime »

Étrange, j’étais persuadé que ces deux tests avaient échoué. Quoi qu’il en soit, c’est une meilleure approche.

4 « J'aime »

C’est ce qui compte vraiment !

4 « J'aime »

Pouvez-vous confirmer que tout va mieux pour votre site ?

2 « J'aime »

Je n’ai pas encore eu confirmation que cela a fonctionné pour l’utilisateur qui se plaignait, mais cela a fonctionné pour moi.

Ce que je ne comprends pas, cependant, c’est que je sais que :

  1. cela a toujours été cassé pour les titres contenant :
  2. si le titre du site change, l’authentificateur est cassé, car il est lié au titre du site
  3. SiteSettings.title n’a pas changé depuis longtemps
  4. UserSecondFactor.where(method: 1) renvoie un tas d’entrées d’août dernier

Je ne comprends pas comment tout cela peut être vrai. Est-ce que changer le titre du site a cassé tous les UserSecondFactor d’authentificateur existants ? ÉDIT : Non, ce n’est pas le cas. Je viens de changer le titre et l’authentificateur 2FA que j’ai créé hier fonctionne toujours.

seulement avec plusieurs mots avant le :

seul le processus d’ajout d’un nouvel authentificateur TOTP est était cassé

2 « J'aime »

Bon, je suis assez certain que le titre contenait plusieurs mots et un deux-points depuis toujours (aucune modification dans les journaux depuis au moins mai 2019) et que cela fonctionnait encore en août dernier (car des jetons d’authentification ont été générés à cette époque), mais peu importe. Cela semble fonctionner maintenant et le fait de modifier le titre ne rompt pas les jetons existants, ce qui semble être une victoire.

Merci pour la correction rapide !

5 « J'aime »

Ce sujet a été automatiquement fermé 2 jours après la dernière réponse. De nouvelles réponses ne sont plus autorisées.