HIGH cross site request forgerygrapebearer tokens

Cross Site Request Forgery in Grape with Bearer Tokens

Cross Site Request Forgery in Grape with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Cross Site Request Forgery (CSRF) is an attack that tricks a victim into executing unwanted actions on a web application in which they are authenticated. When APIs use Bearer Tokens for authentication, developers may assume that because tokens are required, requests are automatically protected against CSRF. This assumption is incorrect in certain deployment and client contexts.

Grape is a REST-like API micro-framework for Ruby, often used with Rack. APIs built with Grape commonly accept Bearer Tokens via the Authorization header. While sending credentials in headers helps avoid some traditional cookie-based CSRF issues, the vulnerability can still arise when requests are made from browsers in specific scenarios:

  • Authenticated browsers automatically include cookies and HTTP authentication credentials for same-site requests. If your Grape API is called from browser JavaScript (e.g., via fetch or XMLHttpRequest) and relies only on Bearer Tokens in headers, an attacker can craft a form or image request that triggers state-changing methods (POST, PUT, DELETE). Browsers will include session-related cookies if present, and if the Grape app also accepts cookie-based sessions or if the token is stored in a way the browser can auto-send (rare but possible), the request may be executed unintentionally.
  • CSRF risk increases when the API serves responses to browser-origin requests (e.g., JavaScript clients) and lacks explicit anti-CSRF mechanisms. Even with Bearer Tokens, if the token is stored in localStorage and exposed via XSS, the attacker can read it and forge requests with the correct Authorization header; however, a forged request from a third-party site won’t automatically include the token unless the client-side code explicitly adds it. The danger arises when the API does not validate the Origin header or use SameSite cookie attributes for any auxiliary cookies.
  • Non-browser clients (like mobile apps or curl) are not susceptible to CSRF because they do not automatically attach credentials across origins. However, browser-based clients consuming a Grape API must be treated with caution. Attack vectors such as malicious sites embedding forms or scripts that call your API endpoints can succeed if defenses are weak.

In practice, a Grape endpoint that accepts Bearer Tokens but does not implement CSRF-specific protections can be exploited in a browser context when cross-origin requests are allowed via CORS misconfigurations or when legacy cookie-based authentication is also supported. For example, a DELETE /accounts/1 endpoint protected by a Bearer Token can be invoked via a simple form submission if the browser’s credential storage behavior inadvertently permits it, or if the token is inadvertently exposed to the browser environment.

Bearer Tokens-Specific Remediation in Grape — concrete code fixes

To mitigate CSRF for Grape APIs using Bearer Tokens, focus on strict request validation and browser-specific protections. Below are concrete, actionable fixes with code examples.

1. Enforce Origin and Referer Validation

Explicitly check the Origin and Referer headers for known, trusted origins. Reject requests with missing or unexpected values.

# In your Grape API class or a before block
before do
  allowed_origins = ['https://app.yourdomain.com', 'https://dashboard.yourdomain.com']
  origin = request.env['HTTP_ORIGIN']
  referer = request.env['HTTP_REFERER']
  unless allowed_origins.include?(origin) || allowed_origins.include?(referer)
    error!('Forbidden', 403)
  end
end

2. Use SameSite Cookie Attributes for Any Session Cookies

If your Grape app sets cookies (e.g., for a web frontend), ensure SameSite is set to Lax or Strict. This prevents browsers from sending cookies in cross-site requests.

# Example when setting a cookie in a Rack-compatible response
set_cookie 'session_id', {
  value: 'abc123',
  httponly: true,
  secure: true,
  same_site: :lax
}

3. Require Anti-CSRF Tokens for State-Changing Methods

For browser-origin requests, require a custom header (e.g., X-CSRF-Token) that cannot be set cross-origin due to CORS restrictions. This pattern is effective when your frontend reads a token and includes it in headers.

# Grape endpoint expecting CSRF token for destructive methods
class MyAPI < Grape::API
  before do
    if %w[POST PUT DELETE PATCH].include?(request.request_method)
      provided_token = request.env['HTTP_X_CSRF_TOKEN']
      expected_token = env['rack.session']&.[]('csrf_token')
      unless provided_token&;casecmp(expected_token)
        error!('Invalid CSRF token', 422)
      end
    end
  end

  desc 'Delete an account', csrf_protected: true
  params do
    requires :account_id, type: Integer
  end
  delete '/accounts/:account_id' do
    # deletion logic
  end
end

4. Configure CORS Strictly

Limit which origins can interact with your API. Avoid wildcard origins when state-changing operations are involved.

# Using a Rack CORS middleware initializer (config/initializers/cors.rb)
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'https://app.yourdomain.com'
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :delete],
      expose: ['X-CSRF-Token'],
      max_age: 86400
  end
end

5. Avoid Relying Solely on Bearer Tokens in Browser Contexts

Do not store Bearer Tokens in localStorage if your API is called from browsers, as XSS can lead to token theft. Prefer short-lived tokens stored in memory or secure, HttpOnly cookies where appropriate. For SPAs, use the Authorization header with tokens obtained via secure flows and ensure strict CORS rules.

By combining these measures—origin validation, SameSite cookies, CSRF tokens for mutating requests, and strict CORS—you significantly reduce the CSRF risk for Grape APIs using Bearer Tokens, even when accessed from browser-based clients.

Frequently Asked Questions

Can a Bearer Token in the Authorization header prevent CSRF?
No. Bearer Tokens in headers prevent some credential leakage, but they do not stop a browser from automatically including cookies or other ambient credentials. Without explicit origin validation or anti-CSRF tokens, browser-origin requests can still trigger unwanted actions.
Is it enough to check the presence of the Authorization header?
Not for CSRF protection. An attacker can craft a request that includes the Authorization header if the token is exposed via XSS or insecure storage. You must also validate Origin/Referer and use anti-CSRF tokens for state-changing methods.