lit_require_frozen.rb

lib/sequel/extensions/lit_require_frozen.rb

The lit_require_frozen extension disallows the use of unfrozen strings as literal strings in database and dataset methods. If you try to use an unfrozen string as a literal string for a dataset using this extension, an exception will be raised.

While this works for all Ruby versions, it is designed for use on Ruby 3+ where all files are using the frozen-string-literal magic comment. In this case, uninterpolated literal strings are frozen, but interpolated strings are not frozen. This allows you to catch potentially dangerous code:

# Probably safe, no exception raised
DB["SELECT * FROM t WHERE c > :v", v: user_provided_string)

# Potentially unsafe, raises Sequel::LitRequireFrozen::Error
DB["SELECT * FROM t WHERE c > '#{user_provided_string}'"]

The assumption made is that a frozen string is unlikely to contain unsafe input, while an unfrozen string has potentially been interpolated and may contain unsafe input.

This disallows the the following cases:

  • Sequel::LiteralString instances that are unfrozen and are not based on a frozen string

  • Sequel::SQL::PlaceholderLiteralString instances when the placeholder string is not frozen

  • Unfrozen strings passed to Database#<< or [] or Dataset#with_sql

To use this extension, load it into the database:

DB.extension :lit_require_frozen

It can also be loaded into individual datasets:

ds = DB[:t].extension(:lit_require_frozen)

Assuming you have good test coverage, it is recommended to only load this extension when testing.

Related module: Sequel::LitRequireFrozen