vert-core 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3aa9021ca1d0ff2ab76b8b4fd026b939a0d44baebb72e5c9b8da18f8d5b9980e
4
- data.tar.gz: d9ee8170d903c549fe6364937ea5354d661065edc37a1e2ebfb641a1010fe1db
3
+ metadata.gz: 3cd14af74495d17174f61ed390691b90f01b5897ffc368e804cc6155ffc7e70d
4
+ data.tar.gz: 0fdad12a722f1f876349b3a1f93cef84a1307a34fb96f2587ab429d0b6d4320f
5
5
  SHA512:
6
- metadata.gz: 022de5e26283b3bbe93b8398b16dd476523be37a46e6272967fde2306cb8f8d8568d808fe6bfa4f97ef3913446bf7a188fa81a9efa66c9641d1b762c982015b7
7
- data.tar.gz: 02aa04cef9c9d94381199d6f1a152b5f6e635a743655dc6f628664cd729ea6b543b6c9a70a96d8341ce88fab29acb6cce7ce5e03dcec35bc41fdff7f77ad4049
6
+ metadata.gz: ca0ffeea71830f7f2f26028bd4b8bf269ed7d15138f7971846c72d15bb8b70ef9dfedc6afa118e98f7ecbbe63ff1dc8bdf15782836ffb62b216086e87006772d
7
+ data.tar.gz: 8427a308b31890c81df7cc7bcbd2ba7a867e8067bede7e45ad5e16c19f6880d9a3f27be033863467ad960dc98e901708c27b86277d6d7b65d79ef9cdda538d9b
data/README.md CHANGED
@@ -121,6 +121,12 @@ class MyJob < ApplicationJob
121
121
  end
122
122
  ```
123
123
 
124
+ ## Produção e segurança
125
+
126
+ - Defina sempre via **variáveis de ambiente** em produção: `RABBITMQ_URL`, `DOCUMENT_SERVICE_URL`, `REDIS_URL`. Os valores padrão (guest/localhost) são apenas para desenvolvimento.
127
+ - Serviços que publicam mensagens nas filas consumidas com `Vert::Rls::ConsumerContext` podem definir o contexto (tenant_id, user_id) via headers; garanta que apenas serviços confiáveis publiquem nessas filas.
128
+ - Para mais detalhes, veja `SECURITY_AND_QUALITY_AUDIT.md` no repositório.
129
+
124
130
  ## Licença
125
131
 
126
132
  MIT.
@@ -0,0 +1,98 @@
1
+ # Auditoria de Qualidade e Segurança — Gem vert-core
2
+
3
+ **Data:** 2025-03
4
+ **Escopo:** `services/00-gems/vert` (publicada no RubyGems como `vert-core`)
5
+ **Objetivo:** Garantir segurança e confiabilidade para uso em produção.
6
+
7
+ ---
8
+
9
+ ## 1. Resumo executivo
10
+
11
+ | Categoria | Status | Observação |
12
+ |------------------|--------|------------|
13
+ | Segurança | ✅ Aprovado com ressalvas | Sem vulnerabilidades críticas; ver itens 2.x |
14
+ | Qualidade | ✅ Bom | Código consistente; ver itens 3.x |
15
+ | Dependências | ✅ OK | Rails 7–9, Sidekiq, Bunny, Discard — versões declaradas |
16
+ | Publicação | ⚠️ Ajuste | CI usa Ruby 2.6; gemspec exige >= 3.2 |
17
+
18
+ ---
19
+
20
+ ## 2. Segurança
21
+
22
+ ### 2.1 Pontos positivos
23
+
24
+ - **SQL:** Uso de `ActiveRecord::Base.sanitize_sql` em `ConnectionHandler` para `SET LOCAL` (tenant_id, company_id, user_id). Nenhuma concatenação direta de input em SQL.
25
+ - **Autorização:** Queries em `PermissionResolver` usam placeholders (`?`). Nenhum `eval`, `YAML.load` ou `Marshal.load` em dados de usuário ou mensagens.
26
+ - **Contexto de job:** `Vert::Current.serialize/deserialize` só manipula Hash com atributos primitivos (tenant_id, user_id, company_id, request_id). Não há deserialização insegura.
27
+ - **Constantes:** `Object.const_get` em `PolicyFinder` e `OutboxEvent` usa apenas nomes derivados do modelo/record da aplicação, não de input do usuário.
28
+ - **Secrets:** Nenhuma senha, token ou API key hardcoded. URLs e credenciais vêm de `Vert.config` ou `ENV`.
29
+
30
+ ### 2.2 Riscos e recomendações
31
+
32
+ | Risco | Severidade | Recomendação |
33
+ |-------|------------|--------------|
34
+ | **Defaults de conexão** | Baixo | `Configuration` usa `ENV.fetch(..., "amqp://guest:guest@localhost:5672/")` e `redis://localhost:6379/0`. Em produção, garantir sempre variáveis de ambiente; considerar remover defaults “guest” em doc ou comentar que são apenas para desenvolvimento. |
35
+ | **Document service** | Baixo | `DocumentServiceClient` não valida `base_url`. Garantir que `document_service_url` não seja controlada por usuário (evitar SSRF). Em produção usar HTTPS. |
36
+ | **Health / rotas** | Baixo | `Vert::Health::Routes.mount(router, path: nil)` usa `path` em `scope path`. O valor vem de `Vert.config.health_check_path` (default `/health`). Se a app permitir config dinâmico a partir de input, poderia haver path traversal; uso normal é seguro. |
37
+ | **Resposta 403** | Info | `render_forbidden` expõe `permission` (nome do método da policy) e `resource` (nome da classe). Pode ser desejável em APIs internas; em APIs públicas considerar resposta genérica para não revelar estrutura. |
38
+ | **Cache de permissões (Redis)** | Baixo | `invalidate_user_cache(user_id)` monta a chave `vert:permissions:#{user_id}:*`. Se `user_id` puder conter `*` ou `?`, o padrão Redis poderia invalidar mais chaves. Recomendação: usar apenas IDs válidos (UUID/integer) ou escapar/sanitizar. |
39
+ | **Consumers RabbitMQ** | Médio (contexto) | `ConsumerContext` define contexto (tenant_id, user_id, company_id) a partir dos headers da mensagem. Qualquer produtor da fila pode “personificar” um tenant. Garantir que apenas serviços confiáveis publiquem nessas filas e que a rede do broker seja controlada. |
40
+
41
+ ### 2.3 O que não foi encontrado
42
+
43
+ - Uso de `eval`, `exec`, `system`, backticks ou `Kernel#open` com input externo.
44
+ - `YAML.load` ou `Marshal.load` em dados de request ou mensagens.
45
+ - Exposição de stack trace ou detalhes internos em respostas de erro (apenas mensagens controladas).
46
+ - Credenciais ou tokens fixos no código.
47
+
48
+ ---
49
+
50
+ ## 3. Qualidade
51
+
52
+ ### 3.1 Estrutura e convenções
53
+
54
+ - `# frozen_string_literal: true` e estilo consistente.
55
+ - Separação clara: concerns, clients, RLS, outbox, health, authorization.
56
+ - Entry point único: `vert_core.rb` → `vert.rb`; Railtie condicional.
57
+
58
+ ### 3.2 Tratamento de erros
59
+
60
+ - `ConnectionHandler`: `rescue StandardError` com log e re-raise em `set_context`; em `reset_context` apenas log (evita mascarar falhas de reset).
61
+ - `DocumentServiceClient`: `execute_request` retorna hash `{ success:, error:, ... }`; não propaga exceção para o caller, adequado para cliente HTTP.
62
+ - `Publisher#publish`: `rescue StandardError` → `mark_as_failed!` e retorno `false`.
63
+ - Health checks: cada check em `check_all` em bloco próprio com `rescue` para não derrubar os demais.
64
+
65
+ ### 3.3 Configuração
66
+
67
+ - Flags explícitas (enable_rls, enable_outbox, etc.) com default seguro (maioria `false`; health `true`).
68
+ - Documentação no README e no template do initializer.
69
+
70
+ ### 3.4 Melhorias sugeridas
71
+
72
+ - **Configuração sensível:** Considerar um método `Vert.config.to_s` ou inspetor que oculte `rabbitmq_url` e `document_service_url` em logs (ex.: mostrar só host/scheme).
73
+ - **Versão do Ruby no CI:** Alinhar o workflow ao `required_ruby_version` (>= 3.2) para evitar publicar com Ruby incompatível.
74
+
75
+ ---
76
+
77
+ ## 4. Gemspec e publicação
78
+
79
+ - **Nome:** `vert-core` (require: `vert_core`); módulo: `Vert`. Consistente.
80
+ - **Licença:** MIT. Adequado.
81
+ - **Dependências:** activesupport/activerecord 7–9, bunny ~> 2.22, discard ~> 1.3, sidekiq 7–9. Ranges claros.
82
+ - **CI:** `.github/workflows/gem-push.yml` usa Ruby 2.6; o gemspec exige `>= 3.2.0`. **Correção necessária:** usar Ruby 3.2 (ou 3.3) no workflow.
83
+
84
+ ---
85
+
86
+ ## 5. Checklist pós-auditoria
87
+
88
+ - [ ] Atualizar workflow para Ruby 3.2+.
89
+ - [ ] Documentar na README que defaults de RabbitMQ/Redis são apenas para desenvolvimento.
90
+ - [ ] (Opcional) Sanitizar/validar `user_id` em chaves de cache no `PermissionResolver`.
91
+ - [ ] (Opcional) Resposta 403 mais genérica em ambientes públicos.
92
+ - [ ] Manter dependências atualizadas (`bundle audit` / Dependabot).
93
+
94
+ ---
95
+
96
+ ## 6. Conclusão
97
+
98
+ A gem **vert-core** está em bom estado para uso em produção do ponto de vista de segurança e qualidade. Não foram identificadas vulnerabilidades críticas ou altas. As recomendações são sobretudo de configuração (ENV em produção, confiança em produtores de mensagens), alinhamento do CI ao Ruby 3.2+ e pequenos ajustes opcionais de hardening e documentação.
@@ -51,7 +51,10 @@ module Vert
51
51
  end
52
52
 
53
53
  def invalidate_user_cache(user_id)
54
- pattern = "#{CACHE_PREFIX}:#{user_id}:*"
54
+ return if user_id.blank?
55
+ # Sanitize to avoid Redis KEYS pattern injection (e.g. * or ? in user_id)
56
+ safe_id = user_id.to_s.gsub(%r{[*?\[\]\{\}\\]}, "")
57
+ pattern = "#{CACHE_PREFIX}:#{safe_id}:*"
55
58
  redis_delete_pattern(pattern)
56
59
  end
57
60
 
@@ -50,6 +50,7 @@ module Vert
50
50
  @enable_company_scoped = false
51
51
  @enable_document_storeable = false
52
52
 
53
+ # Production: set RABBITMQ_URL, DOCUMENT_SERVICE_URL, REDIS_URL via ENV; do not rely on defaults.
53
54
  @rls_user = ENV.fetch("RLS_USER", "app_user")
54
55
  @rabbitmq_url = ENV.fetch("RABBITMQ_URL", "amqp://guest:guest@localhost:5672/")
55
56
  @exchange_name = ENV.fetch("RABBITMQ_EXCHANGE", "vert.events")
data/lib/vert/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vert
4
- VERSION = "1.0.1"
4
+ VERSION = "1.0.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vert-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vert Team
@@ -178,6 +178,7 @@ extra_rdoc_files: []
178
178
  files:
179
179
  - CHANGELOG.md
180
180
  - README.md
181
+ - SECURITY_AND_QUALITY_AUDIT.md
181
182
  - lib/vert.rb
182
183
  - lib/vert/authorization/controller_methods.rb
183
184
  - lib/vert/authorization/dynamic_policy.rb