Skip to content

Feature/v2 security#6

Merged
Perafan18 merged 4 commits intomasterfrom
feature/v2-security
Nov 10, 2025
Merged

Feature/v2 security#6
Perafan18 merged 4 commits intomasterfrom
feature/v2-security

Conversation

@Perafan18
Copy link
Owner

@Perafan18 Perafan18 commented Nov 10, 2025

Summary by CodeRabbit

Notas de Versión

  • New Features

    • Limitación de tasa en endpoints de cadena para mejorar estabilidad y proteger contra abusos.
    • Validación estricta de datos de bloque con errores claros al enviar payloads inválidos.
  • Documentation

    • Nuevo documento de directrices de desarrollo: setup, ejecución local, pruebas y depuración.
  • Chores

    • Añadidas dependencias para validación y protección por tasa; ajustes de linting para facilitar el desarrollo.

Perafan18 and others added 2 commits November 9, 2025 00:28
Security improvements:
- Add input validation using dry-validation
- Add rate limiting using rack-attack
- Validate all POST request payloads
- Rate limits: 60 req/min general, 10 chains/min, 30 blocks/min
- Return proper 400 errors for invalid inputs
- Return 429 errors when rate limits exceeded

Implementation details:
- Created BlockDataContract for data validation
- Configure rack-attack with sensible rate limits
- Disabled rate limiting in test environment
- All validation errors return structured JSON responses

This enhances security and prevents abuse while maintaining usability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Nov 10, 2025

Warning

Rate limit exceeded

@Perafan18 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 10 minutes and 29 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 49cef26 and c443127.

📒 Files selected for processing (2)
  • main.rb (3 hunks)
  • src/validators.rb (1 hunks)

Walkthrough

Se añaden directrices de desarrollo, dependencias (dry-validation, rack-attack), configuración de Rack::Attack con varias reglas de throttling, validadores Dry::Validation para datos de bloque y la integración del middleware y validación en los endpoints de bloque (excluyendo entornos de test).

Changes

Cohort / File(s) Resumen
Guía de desarrollo
.junie/guidelines.md
Nuevo documento que detalla configuración de Ruby (3.2.2), stack (Sinatra, Mongoid, MongoDB), variables de entorno, uso de Docker, flujo de trabajo, estrategia de tests (RSpec) y normas de RuboCop.
Gestión de dependencias
Gemfile
Añadidas gemas dry-validation (> 1.10) y rack-attack (> 6.7); resto de dependencias mantenidas.
Limitación de velocidad (Rack::Attack)
config/rack_attack.rb
Nueva configuración con throttles: global IP (60 req/min), POST /chain (10 req/min) y POST /chain/.../block (30 req/min); respuesta personalizada 429 JSON.
Integración en la app / Endpoints
main.rb
Carga de config/rack_attack.rb y activación de use Rack::Attack salvo en ENV['ENVIRONMENT']=='test'; uso de BlockDataContract para validar payloads en POST /chain/:id/block y POST /chain/:id/block/:block_id/valid, devolviendo 400 con errores si fallan.
Validadores
src/validators.rb
Nuevo BlockDataContract < Dry::Validation::Contract que exige :data como cadena no vacía.
Configuración de lint
.rubocop.yml
Ajuste en Metrics/BlockLength para permitir método namespace en lista de AllowedMethods/Exclude.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Cliente
    participant RackAttack as Rack::Attack
    participant App as Sinatra App
    participant Validator as BlockDataContract
    participant Service as ChainService

    Client->>RackAttack: HTTP POST /chain/:id/block (payload)
    alt Throttle exceeded
        RackAttack-->>Client: 429 JSON (throttled)
    else Allowed
        RackAttack->>App: forward request
        App->>Validator: validar params
        alt Validation fails
            Validator-->>App: errores de validación
            App-->>Client: 400 JSON (errores)
        else Validation ok
            Validator-->>App: datos validados
            App->>Service: añadir bloque (datos validados)
            Service-->>App: resultado
            App-->>Client: 201/200 JSON (resultado)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderado) | ⏱️ ~20 minutos

Puntos para revisar con atención:

  • Reglas y condiciones de throttling en config/rack_attack.rb (rutas, límites y matching de paths).
  • Integración y uso de BlockDataContract en main.rb (asegurar que se usan los datos validados y se manejan errores correctamente).
  • Exclusión del middleware en entorno test y su impacto en pruebas de integración.
  • Compatibilidad de nuevas gemas (dry-validation, rack-attack) con las versiones actuales del proyecto.

Poem

🐰 En la forja del código salto y salto,
límites y datos ahora guardo alto.
Rack vigila, Dry valida el pan,
bloques seguros en este gran clan.
¡Brinco feliz, la forja canta en su saltar! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive El título 'Feature/v2 security' es demasiado genérico y vago. Aunque menciona 'security', no especifica claramente cuáles son las medidas de seguridad implementadas (rate limiting, validación de datos, etc.). Proporciona un título más descriptivo que especifique las medidas de seguridad principales, por ejemplo: 'Add rate limiting and input validation for security' o 'Implement Rack::Attack rate limiting and block data validation'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
main.rb (1)

69-71: Añadir manejo de errores para JSON inválido.

El método parse_json_body lanzará una excepción si el cuerpo de la petición no es JSON válido, pero no hay un rescue que capture este error y devuelva una respuesta 400 apropiada al cliente.

Aplica este diff para manejar errores de parsing JSON:

 helpers do
   def parse_json_body
     JSON.parse(request.body.read)
+  rescue JSON::ParserError
+    halt 400, { error: 'Invalid JSON format' }.to_json
   end
🧹 Nitpick comments (1)
config/rack_attack.rb (1)

20-26: Respuesta personalizada apropiada para errores de rate limit.

La respuesta 429 con formato JSON y mensaje claro proporciona buena experiencia al cliente API.

RuboCop sugiere añadir una coma al final del array en línea 24 para consistencia de estilo:

         429,
         { 'Content-Type' => 'application/json' },
-        [{ error: 'Rate limit exceeded. Please try again later.' }.to_json]
+        [{ error: 'Rate limit exceeded. Please try again later.' }.to_json],
       ]
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f69abf and eadf86a.

⛔ Files ignored due to path filters (1)
  • Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • .junie/guidelines.md (1 hunks)
  • Gemfile (1 hunks)
  • config/rack_attack.rb (1 hunks)
  • main.rb (2 hunks)
  • src/validators.rb (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
main.rb (3)
src/validators.rb (1)
  • params (6-10)
src/blockchain.rb (1)
  • add_block (20-24)
src/block.rb (1)
  • valid_data? (44-46)
🪛 RuboCop (1.81.7)
config/rack_attack.rb

[convention] 24-24: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)

🔇 Additional comments (9)
Gemfile (1)

6-21: La organización en grupos temáticos mejora la legibilidad.

La agrupación de dependencias por funcionalidad (Web framework, Database, Configuration, Validation, Testing) hace que el archivo sea más mantenible. Las versiones especificadas son apropiadas para las nuevas funcionalidades de seguridad y validación introducidas en este PR.

main.rb (5)

7-10: Las dependencias necesarias están correctamente incluidas.

La integración de Rack::Attack y el módulo de validación se realiza de manera ordenada, cargando tanto la gema como su configuración específica del proyecto.


14-15: Buena práctica: deshabilitar rate limiting en tests.

La activación condicional de Rack::Attack evita que los tests fallen por límites de tasa, manteniendo la seguridad en producción.


22-22: Configuración apropiada del Content-Type para endpoints JSON.

Establecer content_type :json asegura que las respuestas se identifiquen correctamente como JSON.

Also applies to: 29-29, 47-47


31-37: La validación de entrada mejora la seguridad y robustez.

La integración de BlockDataContract valida los datos antes de procesarlos, retornando errores 400 apropiados cuando falla. El uso de validation[:data] garantiza que solo datos validados lleguen a la lógica de negocio.


49-59: Validación consistente aplicada en el endpoint de verificación.

Se aplica el mismo patrón de validación que en el endpoint de creación de bloques, asegurando coherencia en el manejo de errores.

.junie/guidelines.md (1)

1-158: Documentación exhaustiva que facilita la incorporación de desarrolladores.

El documento proporciona instrucciones claras para configuración, desarrollo, testing y debugging. Las referencias a los cambios introducidos en este PR (Rack::Attack, validación con dry-validation) ayudan a los desarrolladores a entender el contexto completo del proyecto.

src/validators.rb (1)

5-10: Validación básica apropiada para datos de bloque.

El contrato valida que el campo data sea una cadena no vacía, lo cual es adecuado para la naturaleza flexible de los datos blockchain. La validación de formato más específica (si es necesaria) puede añadirse posteriormente.

config/rack_attack.rb (1)

6-17: Se confirma el vacío de cobertura en el endpoint /chain/:id/block/:block_id/valid.

El patrón regex ^/chain/.+/block$ en línea 16 no captura el endpoint POST /chain/:id/block/:block_id/valid (que termina en /valid en lugar de /block). Actualmente, este endpoint solo aplica el throttle global de 60 req/min, no el límite específico de 30 req/min definido para creación de bloques.

Verifica si este endpoint requiere el mismo límite de tasa que /chain/:id/block o si el comportamiento actual es intencional.

Resolved conflicts and integrated all features:
- Rack::Attack rate limiting integrated with API v1
- dry-validation for input validation on all endpoints
- PoW validation (difficulty) integrated with security validation
- All endpoints under /api/v1 namespace with security middleware
- Updated .rubocop.yml to allow namespace blocks
- All tests passing (17 examples, 0 failures)
- RuboCop clean (10 files, no offenses)
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
main.rb (1)

106-108: Falta manejo de errores para JSON malformado.

El método parse_json_body no maneja excepciones de JSON::ParserError. Si un cliente envía JSON malformado, esto resultará en un error 500 con una página HTML en lugar de una respuesta JSON apropiada, lo cual es inconsistente con la API y podría exponer información sensible en trazas de error.

Aplica este diff para agregar manejo de errores:

 def parse_json_body
   JSON.parse(request.body.read)
+rescue JSON::ParserError
+  halt 400, { error: 'Invalid JSON' }.to_json
 end
🧹 Nitpick comments (1)
main.rb (1)

110-115: Considera mejorar el manejo de errores para consistencia con la API.

El método find_block_chain usa raise para errores de "Chain not found", lo cual resultará en respuestas de error 500 con HTML en lugar de respuestas JSON con código 404. Aunque este código no fue modificado en este PR, considera usar halt 404, { error: 'Chain not found' }.to_json para mantener consistencia con las respuestas de validación agregadas.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eadf86a and 49cef26.

⛔ Files ignored due to path filters (1)
  • Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • .rubocop.yml (1 hunks)
  • Gemfile (1 hunks)
  • main.rb (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Gemfile
🧰 Additional context used
🧬 Code graph analysis (1)
main.rb (3)
src/validators.rb (1)
  • params (6-10)
src/blockchain.rb (1)
  • add_block (22-34)
src/block.rb (1)
  • valid_data? (50-52)
🔇 Additional comments (4)
.rubocop.yml (1)

37-38: ¡Se ve bien!

La exclusión de namespace en Metrics/BlockLength es apropiada para bloques de rutas de Sinatra, que típicamente contienen múltiples definiciones de endpoints y pueden exceder los límites de longitud.

main.rb (3)

8-11: ¡Buena integración de dependencias de seguridad!

La carga de Rack::Attack y los validadores está bien estructurada para soportar las nuevas funcionalidades de seguridad.


15-16: ¡Configuración correcta del middleware!

La carga condicional de Rack::Attack excluyendo el entorno de test es la práctica recomendada para evitar interferencias en las pruebas.


62-64: Validación implementada correctamente.

La validación con BlockDataContract está bien implementada en este endpoint, retornando un 400 con errores de validación cuando falla.

Moved difficulty validation from validate_difficulty helper to BlockDataContract
for consistency. This addresses CodeRabbit's feedback about inconsistent validation
approaches.

Changes:
- Extended BlockDataContract to validate optional difficulty field
- Added validation rules: must be positive integer between 1 and 10
- Updated POST /chain/:id/block to use validated difficulty from contract
- Removed standalone validate_difficulty helper method
- Maintained default difficulty value of 2 when not provided

All tests passing (17 examples, 0 failures)
RuboCop clean (10 files, no offenses)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@Perafan18 Perafan18 merged commit 188644d into master Nov 10, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant