Skip to content

The active model where method should act as a normal parameterized scope #116

Closed

Description

@catmando

Currently returns nil if used on a AR class, and throws a non-related error if used on a scope.

THIS WAS THE ORIGINAL CONCLUSION BUT ITS INCORRECT SEE DISCUSSION:

The reasons we won't implement where is that it could be used to insecurely determine counts on data.
For example Customers.where(top_secret_attribute: true).count could be executed from the JS console to find the count of customers with the top_secret_attribute.

where should be implemented as a scope.

We will need to add scope called __hyperstack_internal_where_scope

class ActiveRecord::Base 
  scope __hyperstack_internal_where_scope, 
    ->(attrs) { where(attrs) }, # server side we just call where
    filter: ->(attrs) { !attrs.detect { |k, v| self[k] != v } # client side optimization
  def self.where(attrs) 
    __hyperstack_internal_where_scope(attrs)
  end if RUBY_ENGINE == 'opal'
end

On the client side we can add the class level where method to ActiveRecord::Base and which simpy calls the `__hyperstack_internal_where_scope.

Activity

  1. modified the milestone: alpha1.4 on Jan 28, 2019
  2. Tim-Blokdijk commented on Jan 28, 2019

    @Tim-Blokdijk
    Contributor

    where is working within scopes, I presume this is not a security issue?

    Suggestion for an error message:
    Hypermodel does not support where outside of a scope for "security reasons". See [link to explanation] for details.
    Please use scopes, find, find_by and ActiveRecord relations to query your data.
    If you think you can write a secure where implementation, feel free to impress us.

  3. changed the title [-]The active model `where` method should consistently throw an error.[/-] [+]The active model `where` method should act as a normal parameterized scope[/+] on Feb 14, 2019
  4. catmando commented on Feb 16, 2019

    @catmando
    ContributorAuthor

    @Tim-Blokdijk yes you are right, and in fact, I am wrong in my overall conclusion. where can act like any other scope, and will simply follow the normal security rules. Thus if you do not open up the all scope then doing Customers.where(top_secret_attribute: true) will fail because no scope ever granted permission.

    In practical terms you could do this:

    class Customer < ApplicationRecord
      regulate_scope :all, ->() { acting_user.admin? }  # admins can get any data needed
    end

    now

    Customer.where(top_secret_attribute: true).count

    will only work if executed by an admin.

  5. added a commit that references this issue on Apr 2, 2021
    c016dbe
  6. catmando commented on Apr 5, 2021

    @catmando
    ContributorAuthor

    closed in 1.0.alpha1.7

  7. added 4 commits that reference this issue on Sep 2, 2026
    209be11
    43cbda3
    b01cda2
    b1446e7
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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions