Skip to content

Matcher coverage: Falcon + async-grpc Ruby services (no web framework gate fires) #87

Description

@mkamranii

The pattern

DeepSec's Ruby matchers (`rb-rails-controller`, `rb-sinatra-route`, `rb-grape-endpoint`, `rb-hanami-action`, `rb-roda-route`) are all gated on a request/response web framework being detected. Modern async-Ruby services that use Falcon as the server with async-grpc (or plain gRPC) for RPC don't trigger any of those gates, so no Ruby matchers activate and the LLM never gets candidates to investigate.

Concretely, on a Falcon/async-grpc service (~80 Ruby files), DeepSec produced:

```
[deepsec:scan] docker, github-actions, ruby
[deepsec:scan] ruby N files 0 hits 0.00%
⚠ Low matcher coverage for ruby (very low)
deepsec may not have built-in matchers for your ruby stack.
```

The only findings on the scan came from generic matchers (`github-workflow-security`, `dockerfile-from-mutable-tag`). The actual Ruby business logic was never investigated.

Example shapes worth catching

1. gRPC service entry points (the equivalent of a Rails controller action for these apps):

```ruby

lib/example_service.rb

class ExampleService < ::ExampleGen::Service
def lookup(request, call)
# ← request is attacker-controlled, call.metadata holds auth headers
# Equivalent role to a Rails controller action — but no gate fires today
BackendClient.new(request.payload).run
end
end
```

2. async-websocket handlers:

```ruby

lib/stream_handler.rb

Async::WebSocket::Adapters::Rack.open(env) do |connection|
while message = connection.read
# ← attacker-controlled message; no auth gate here unless app adds one
handle_message(message.buffer)
end
end
```

3. JWT verification in gRPC interceptors — analogous to `before_action :authenticate_user!` in Rails, but DeepSec doesn't know to expect it.

CWE / category

Mostly framework / entry-point coverage rather than a single CWE. The downstream sinks DeepSec already knows about (CWE-89 SQLi, CWE-918 SSRF, CWE-78 OS command, CWE-79 XSS-in-API-responses, CWE-287 missing auth) all apply — they're just unreachable today because no candidates exist for the LLM to start from.

Closest CWE for the missing-auth shape: CWE-306 (Missing Authentication for Critical Function) — gRPC services exposing privileged operations without a per-method interceptor check.

Languages / frameworks

  • Language: Ruby
  • Server: Falcon (async, multi-tenant web server; HTTP/2 + WebSocket native)
  • RPC: async-grpc or plain `grpc` gem
  • Common companions: `async`, `async-websocket`, `zeitwerk`, `jwt`

Detection sentinels that distinguish Falcon/async-grpc apps from Rails:

  • `Gemfile` contains `gem "falcon"` or `gem "async-grpc"` or `gem "grpc"` without `gem "rails"`
  • `config.ru` present at repo root with no `config/routes.rb` or `bin/rails`
  • `proto/` directory with `.proto` files (gRPC service definitions)
  • Service classes inheriting from generated `*Service::Service` parent classes (the `_services_pb.rb` files `grpc_tools_ruby_protoc` emits)

Generic vs org-specific

Generic — this is a widely-used Ruby async-IO stack from the `socketry` ecosystem, not org-specific. Anyone running a Ruby gRPC microservice today is likely on Falcon + async-grpc and would benefit. The patterns are stable across projects because they all extend the same auto-generated gRPC base classes.

Closest existing analogue is `js-fastify-route` / `js-hono-route` — framework-gated entry-point matchers that activate only when the framework is detected.

Have you tried writing it yourself?

Not yet — wanted to confirm appetite for upstream coverage first. `docs/supported-tech.md` lists `sinatra`, `grape`, `hanami`, `roda` as "Roadmap" but Falcon / async-grpc aren't on that list. If you'd take a PR, happy to draft a detector + matcher + prompt-highlight block (Rails plus the four roadmap frameworks all follow the same shape, so it's a small, well-scoped add).

Suggested matcher slugs:

  • `rb-grpc-service` — gated on `tech: ["grpc-ruby"]`, file pattern `lib/**/service.rb`, regex on `class \w+ < \S+(?:Service|Service::Service)\b`
  • `rb-async-websocket-handler` — gated on `tech: ["async-websocket"]`, regex on `Async::WebSocket::Adapters::Rack\.open`
  • `rb-falcon-rack-app` — gated on `tech: ["falcon"]`, weak entry-point candidate for the `config.ru` rack app boundary

Prompt highlights would mirror the Rails ones: confirm a per-RPC auth interceptor exists, confirm request fields aren't passed unsanitized to subprocess/SQL/HTTP sinks, confirm error responses don't leak stack traces.


Happy to send a PR if there's interest.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions