Join our Newsletter — 33% off our NHI Course
Home› Glossary› Cyber Security› Insecure Send
Cyber Security

Insecure Send

← Back to Glossary
By NHI Mgmt Group Updated September 29, 2026 Domain: Cyber Security

Insecure send is the unsafe use of Ruby's send or public_send methods with attacker-controlled method names or arguments. It is dangerous because reflection can be redirected to sensitive methods, including code execution paths, when input is not strictly validated against an allowlist.

What insecure send means in Ruby

Ruby’s send and public_send are metaprogramming tools that invoke methods by name at runtime. They become insecure when untrusted input can choose the method name or arguments, because the caller may unintentionally expose behaviour far beyond the intended code path.

The core issue is not reflection itself, but uncontrolled reflection. A safe design makes the allowed method surface explicit, while an insecure design lets user input steer execution into sensitive routines, error paths, or state-changing methods that were never meant to be reachable from that request.

How insecure send is exploited

Attackers look for inputs that are passed straight into dynamic dispatch. If the application builds a method name from request parameters, JSON fields, route values, or other attacker-controlled data, the resulting call can be redirected to private logic, destructive operations, or methods that reveal secrets or mutate objects in unsafe ways.

In Ruby, public_send is narrower than send because it respects method visibility, but that does not make it safe by itself. If an attacker can choose any public method, they may still reach sensitive business logic, trigger unintended side effects, or chain the call into a code path with dangerous arguments.

This pattern is especially risky when the method name is combined with loosely validated arguments, because the attack surface expands from method selection into parameter abuse. A small convenience feature can become a general-purpose dispatch primitive.

Why this pattern creates security exposure

Insecure send collapses the boundary between data and control. The application is treating input as a command selector, which means the input is no longer just influencing behavior, it is actively defining which behavior runs.

That creates a broad failure mode: unauthorized method invocation, privilege misuse inside the object model, and potential access to code paths that assume trusted callers. In a mature application, those paths may include object mutation, account changes, file operations, or framework hooks that were never intended to be externally reachable.

When reflection is used this way, the main danger is not one specific method, but the loss of control over the call graph. Once the call target is attacker-influenced, any reachable public or private method becomes part of the exposure surface.

How to recognise and constrain insecure send

The safest mental model is to treat any dynamic dispatch fed by external input as a design smell. If the method name is derived from a request, ask whether a fixed dispatch table, explicit branching, or a narrowly scoped allowlist would preserve the feature without exposing arbitrary invocation.

Validation must be structural, not cosmetic. Comparing a user-supplied string against a known set of permitted actions is materially different from filtering for characters or relying on naming conventions, because the risk comes from control flow, not syntax.

It also helps to review where the call sits in the object model. A seemingly harmless helper can become dangerous if it has access to stateful methods, persistence layers, or framework internals. In practice, the secure answer is usually to make the intended operations explicit rather than letting reflection select them indirectly.

Risk and Threat Considerations

Insecure send is high-risk because it turns attacker input into runtime method selection, which can expose code paths that perform privileged actions, leak internal state, or trigger unexpected execution. The danger increases when the called object has broad capabilities or when the method surface changes over time.

Failure mechanism: Untrusted input reaches send or public_send without a strict allowlist, so the attacker controls the invoked method or arguments and can steer execution into unintended behavior.

Impact: The result can be unauthorized action, logic abuse, sensitive data exposure, or code execution when the reachable method set includes dangerous primitives or chained calls.

Practitioner Guidance

Why practitioners should care: Dynamic dispatch is convenient, but in security-sensitive code it should be treated as an execution boundary. If the method name is user-influenced, the feature needs a deliberate trust decision, not just a validation check.

Common misunderstanding: Developers sometimes assume public_send is safe because it blocks private methods. It only narrows the surface, it does not stop an attacker from invoking unwanted public behavior when the method name remains uncontrolled.

Practitioner takeaway: Prefer explicit dispatch and tightly bounded allowlists, then reserve send for trusted internal flows where the full call target is already under application control.

Deepen Your Knowledge

Sign up to our weekly newsletter — get 33% off our NHI Foundation Level Course

    NHIMG Editorial Note
    Reviewed and updated by the NHIMG editorial team on September 29, 2026.
    NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org