
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
including:
jsonb_set
(jsonb_nested_set
)Requirements:
Add this line to your application's Gemfile:
gem 'associate_jsonb'
And then execute:
$ bundle install
To set up your jsonb column, you can use the built in add_reference
/table.references
function. This will only add a new store column if it doesn't already exist
rails g migration add_foreign_key_store_to_my_table
class AddForeignKeyStoreToMyTable < ActiveRecord::Migration[6.0]
def change
add_reference :my_table, :user, store: :extra # => store created
add_reference :my_table, :label, store: :extra, null: false # => store already exists, NOT NULL check constraint added to `store->'label_id'`
# NOTE: you can also use a `change_table(:my_table) block`
end
end
and
class CreateMyTable < ActiveRecord::Migration[6.0]
def change
create_table(:my_table) do |t|
t.references :user, store: :extra
t.references :label, store: :extra, null: false
end
end
end
If you add the jsonb_foreign_key
function to your database, you can also create a foreign_key check constraint by using the same built-in :foreign_key
option used in normal reference definitions.
NOTE: true foreign key references are not possible with jsonb attributes. This will instead create a CHECK constraint that looks for the referenced column using an EXISTS
statement
rails g migration add_jsonb_foreign_key_function
class AddJsonbForeignKeyFunction < ActiveRecord::Migration[6.0]
def up
add_jsonb_foreign_key_function
end
end
class CreateMyTable < ActiveRecord::Migration[6.0]
def change
create_table(:my_table) do |t|
t.references :user, store: :extra, foreign_key: true, null: false
end
end
end
class CreateMyTable < ActiveRecord::Migration[6.0]
def change
create_table(:my_table) do |t|
t.references :person, store: :extra, foreign_key: { to_table: :users }, null: false
end
end
end
You can store all foreign keys of your model in one JSONB column, without having to create multiple columns:
class Profile < ActiveRecord::Base
# Setting additional :store option on :belongs_to association
# enables saving of foreign ids in :extra JSONB column
belongs_to :user, store: :extra
end
class SocialProfile < ActiveRecord::Base
belongs_to :user, store: :extra
end
class User < ActiveRecord::Base
# Parent model association needs to specify :foreign_store
# for associations with JSONB storage
has_one :profile, foreign_store: :extra
has_many :social_profiles, foreign_store: :extra
end
Due to the ease of getting out-of-sync, and the complexity needed to build it, HABTM relation functionality has not been implemented through JSONB
When enabled, only keys present in the updated hash and with values changed in memory will be updated.
To completely delete a key/value
pair from an enabled attribute, set the key's value to nil
.
e.g.
# given: instance#data == { "key_1"=>1,
# "key_2"=>2,
# "key_3"=> { "key_4"=>7,
# "key_5"=>8,
# "key_6"=>9 } }
instance.update({ key_1: "asdf", a: 1, key_2: nil, key_3: { key_5: nil }})
# instance#data => { "key_1"=>"asdf",
# "a"=>"asdf",
# "key_3"=> { "key_4"=>7,
# "key_6"=>9 } }
first, create the sql function
rails g migration add_jsonb_nested_set_function
class AddJsonbNestedSetFunction < ActiveRecord::Migration[6.0]
def up
add_jsonb_nested_set_function
end
end
then in an initializer, enable key based updates:
# config/initializers/associate_jsonb.rb
AssociateJsonb.enable_jsonb_set
Key based updates rely on inheritance for allowed attribute types. Any attributes that respond true to attr_type.is_a?(GivenClass)
for any enabled type classes will use jsonb_nested_set
To add classes to the enabled list, pass them as arguments to AssociateJsonb.add_hash_type(*klasses)
. Any arguments passed to AssociateJsonb.enable_jsonb_set
are forwarded to AssociateJsonb.add_hash_type
By default, calling AssociateJsonb.enable_jsonb_set(*klasses)
without arguments, and no classes previously added, adds ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Jsonb
to the allowed classes list
by default jsonb_nested_set
updates are disabled.
if you've enabled them and need to disable, use: AssociateJsonb.disable_jsonb_set
To remove a class from the allowed list while leaving nested set updates enabled, use AssociateJsonb.remove_hash_type(*klasses)
.
Any arguments passed to AssociateJsonb.disable_jsonb_set
are forwarded to AssociateJsonb.remove_hash_type
When jsonb_set updates are disabled, jsonb columns are replaced with the current document (i.e. default rails behavior)
You are also given the option to automatically clear nil/null values from the hash automatically when jsonb_set is disabled
in an initializer:
# config/initializers/associate_jsonb.rb
AssociateJsonb.jsonb_delete_nil = true
Rules for classes to which this applies are the same as for jsonb_nested_set
; add and remove classes through AssociateJsonb.(add|remove)_hash_type(*klasses)
To setup development environment, run:
$ bin/setup
To run specs:
$ bundle exec rspec
The gem is available as open source under the terms of the MIT License.
FAQs
Unknown package
We found that associate_jsonb demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.