CtrlK
BlogDocsLog inGet started
Tessl Logo

igmarin/hanakai-yaku

Curated library of atomic AI agent skills for Hanami, dry-rb, and ROM Ruby development. Covers actions, slices, repositories, relations, changesets, providers, DI, operations, TDD, CLI, views, routing, and validation. Shared Ruby process skills have moved to ruby-core-skills. Uses Markdown + Front-matter architecture.

92

1.33x
Quality

94%

Does it follow best practices?

Impact

92%

1.33x

Average score across 35 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

SKILL.mdskills/review-security/

name:
review-security
license:
MIT
description:
Use when conducting a security audit, vulnerability check, or code review on Hanami 2.x applications. Validates parameter handling, detects CSRF misconfigurations, audits authentication integration points, flags SQL injection and XSS risks, enforces input sanitization, and identifies secrets management and session configuration issues.
metadata:
{"ecosystem_sources":["hanami/hanami"],"tags":["security","review","csrf","authentication","vulnerabilities"],"version":"1.0.0"}

review-security

Use this skill when reviewing Hanami 2.x code for security concerns.

Core principle: Security is layered. Validate at the boundary, authenticate explicitly, and never trust input.


Review Workflow

Follow this sequence when performing a security review:

  1. Validate params — Check every Action for a params block. Grep: grep -rn 'request.params' app/actions/ | grep -v 'params do'
  2. Verify CSRF config — Confirm config.actions.csrf_protection = true in config/app.rb for HTML apps.
  3. Audit auth checks — Confirm every sensitive Action has an explicit before :authenticate! or equivalent. Grep: grep -rn 'def handle' app/actions/ and cross-check with grep -rn 'authenticate'
  4. Check authorization — Confirm role/permission checks exist in Actions or service objects beyond mere authentication.
  5. Scan for secrets in code — Grep: grep -rn 'secret\|password\|api_key\|token' app/ config/ --include='*.rb' | grep -v 'settings\|ENV'
  6. Check logging — Grep: grep -rn 'logger' app/ | grep 'password\|token\|secret'
  7. Check SQL safety — Grep: grep -rn 'where("' app/ to find potential string interpolation in queries.
  8. Check template output — Grep: grep -rn 'raw ' app/ to find unescaped output.
  9. Review session config — Confirm config.sessions has a secret from settings, not hardcoded.
  10. Review error messages — Confirm auth failures return generic messages (no user enumeration).

Quick Reference Checklist

ConcernRed Flag
Param validationrequest.params used directly in business logic
CSRF protectionMissing csrf_protection = true for HTML endpoints
AuthenticationAuth assumed by convention, not explicit check
AuthorizationOnly authn, no authz
Error messagesMessages like "User not found" or "Password incorrect"
Loggingparams[:password] or tokens in log calls
SecretsHardcoded strings for keys/secrets in source files
SQL injectionString interpolation in where("...")
XSSraw or html_safe on user input
Session managementNo secret, no expiration, or hardcoded secret

Core Rules

  1. Validate all params via the Params DSL:

    # GOOD
    params do
      required(:email).value(:string, format?: /\A.+@.+\z/)
      required(:password).value(:string, min_size?: 8)
    end
    
    # BAD — mass assignment risk
    user_repo.create(request.params)
  2. Enable CSRF protection for HTML endpoints:

    # config/app.rb
    config.actions.csrf_protection = true
  3. Authenticate in Actions using injected services:

    include Deps["authentication"]
    before :authenticate!
    
    def authenticate!(request, response)
      halt 401 unless authentication.valid?(request)
    end
  4. Never log sensitive data:

    # GOOD
    logger.info("Login attempt: #{params[:email]}")
    
    # BAD
    logger.info("Login: #{params[:email]}, password: #{params[:password]}")
  5. Store secrets in settings, never in code:

    # config/settings.rb
    setting :session_secret, constructor: Types::String
    # .env
    SESSION_SECRET=your-secret-here
  6. Prevent SQL injection using ROM's query interface:

    # GOOD
    users.where(email: params[:email]).one
    
    # BAD
    users.where("email = '#{params[:email]}'")
  7. Escape output in templates to prevent XSS:

    <!-- GOOD -->
    <p><%= user.bio %></p>
    
    <!-- BAD -->
    <p><%= raw user.bio %></p>
  8. Use secure session configuration:

    config.sessions = :cookie, {
      key: "my_app.session",
      secret: settings.session_secret,
      expire_after: 60 * 60 * 24 * 7
    }
  9. Return generic error messages for auth failures:

    # GOOD
    halt 401, { error: "Invalid credentials" }.to_json
    
    # BAD — reveals account existence
    halt 401, { error: "User not found" }.to_json

Integration

Related SkillWhen to chain
validate-paramsAll params must be validated before use.
handle-errorsError responses must not leak sensitive information.
settingsSecrets and configuration must use Settings, not hardcoded values.
code-reviewSecurity review is part of every code review.
setup-authenticationFor implementing auth strategies.
security-review-process (from ruby-core-skills)OWASP checklist, Ruby-level security concerns.

Rails → Hanami

RailsHanami 2.x
protect_from_forgeryconfig.actions.csrf_protection = true
before_action :authenticate_user!Explicit before :authenticate! in each Action
strong_parametersParams DSL with type coercion and constraints
Rails.application.credentialsSettings with environment variables
html_safe / rawERB auto-escapes; avoid raw on user input
config.session_storeconfig.sessions = :cookie, { ... } in config/app.rb

skills

review-security

README.md

tile.json