Problema com create_second_factor_totp

Iniciado POST "/u/create_second_factor_totp.json" para 209.249.35.130 em 2020-02-19 14:21:20 +0000
Processando UsersController#create_second_factor_totp como JSON
Concluído 500 Internal Server Error em 5ms (ActiveRecord: 0,0ms | Alocações: 1781)
Addressable::URI::InvalidURIError (Formato de esquema inválido: Our Great Forum)
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/uri.rb:901:in `scheme='
  Renderizando template de texto
  Template de texto renderizado (Duração: 0,0ms | Alocações: 1)

“Our Great Forum” é quase o título do fórum nas configurações do sistema. O valor real é algo como
“Our Great Forum: Our fine tagline”, então o que aparece no log é apenas a parte antes dos dois pontos. Não vejo “Our Great Forum” em nenhum outro lugar nas configurações do sistema, então estou confuso sobre por que estaria lá sem a parte : tagline no log.

Suspiro. Esta é a versão 2.4.0.beta10 (6301477b4c). Vou atualizar e pedir para eles tentarem novamente. Editarei esta mensagem se conseguir que o usuário tente novamente na versão mais recente.

2 curtidas

O que o rastreamento de chamada em /logs lhe diz?

Isso é tudo o que vejo nos logs. Não vejo um backtrace. No entanto, recebo o erro apenas ao clicar em “novo autenticador” na seção “autenticadores baseados em token”.

E continua o mesmo após a última atualização.

Uau. Sim, algo não está certo.

Você pode copiar a solicitação como curl e postá-la (ocultando qualquer PII e tokens/nonces) para que possamos verificar se o problema está no cliente ou no servidor?

5 curtidas

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 curtidas

Isso deve resolver:

9 curtidas

Alterar o emissor muda os valores do token, mas agora estava completamente quebrado para dois pontos, então isso não deve quebrar nada para novos usuários.

Observe que funcionava anteriormente para títulos com dois pontos, como Spaceballs: The Discourse (funcionou bem para mim e eu consegui adicioná-lo ao meu telefone), mas falhava quando havia duas palavras antes dos dois pontos.

(desculpe se não ficou muito claro no meu relatório)

3 curtidas

Estranho, jurei que ambos falharam nos testes. De qualquer forma, essa é uma abordagem melhor.

4 curtidas

Isso é o que realmente importa!

4 curtidas

Você pode confirmar se está tudo bem para o seu site?

2 curtidas

Ainda não recebi confirmação de que funcionou para o usuário que estava reclamando, mas funcionou para mim.

O que eu não entendo, porém, é que entendo que:

  1. isso sempre esteve quebrado para títulos com : neles
  2. se o título do site mudar, o autenticador fica quebrado, pois está vinculado ao título do site
  3. SiteSettings.title não mudou há muito tempo
  4. UserSecondFactor.where(method: 1) retorna várias entradas de agosto passado

Não entendo como todas essas afirmações podem ser verdadeiras. Seria o caso de que a alteração do título do site quebrou todos os UserSecondFactor de autenticador existentes? EDIÇÃO: Não, não quebrou. Acabei de alterar o título e o 2fa do autenticador que criei ontem ainda funciona.

apenas com várias palavras antes do :

apenas o processo de adicionar um novo autenticador TOTP é estava quebrado

2 curtidas

Bem, tenho quase certeza de que o título sempre teve várias palavras e dois pontos (sem alterações nos logs desde pelo menos maio de 2019) e que funcionou tão recentemente quanto agosto do ano passado (porque há tokens de autenticação gerados nessa época), mas enfim. Parece que está funcionando agora e que alterar o título não quebra os tokens existentes, então isso parece ser uma vitória.

Obrigado pela correção rápida!

5 curtidas

Este tópico foi fechado automaticamente dois dias após a última resposta. Novas respostas não são mais permitidas.