<commit_before># ARSI - ActiveRecord SQL Inspector

[![Build Status](https://magnum.travis-ci.com/zendesk/arsi.svg?token=MsU5XFxeU3atFLQoVGDv&branch=master)](https://magnum.travis-ci.com/zendesk/arsi)

ARSI is a library to ensure that potentially dangerous sql statements are always scoped to an id column.

Currently ARSI will intercept ActiveRelation.update_all and ActiveRelation.delete_all method calls and verify that the SQL includes a scoping operator on an id column.

ID Columns:

- *_id
- id
- guid
- uuid
- uid

Operators:

- =
- <>
- IN
- IS

When a violation is found ARSI will trigger the `Arsi.violation_callback` callback and pass the current SQL and ActiveRelation object. The default callback will raise an `Arsi::UnscopedSQL` exception. You can override this callback in an initializer.

## Disabling ARSI

You can disable ARSI for a relation by using `without_arsi`

```ruby
User.where(active: false).without_arsi.delete_all # I know what I'm doing...

```

You can also disable ARSI via `ARSI.disable`

```ruby
class ApplicationController < ActionController::Base
  around_filter :configure_arsi
  def configure_arsi
    if use_arsi?
    	yield
    else
    	Arsi.disable { yield }
    end
  end
end
```


## Limitations

1. ARSI only supports MySQL
2. ARSI only supports Rails 3.2
2. ARSI is using regexs and is not parsing the SQL therefore false negatives are possible with specially crafted SQL statements.<commit_msg>simplify readme<commit_after># ARSI - ActiveRecord SQL Inspector

[![Build Status](https://magnum.travis-ci.com/zendesk/arsi.svg?token=MsU5XFxeU3atFLQoVGDv&branch=master)](https://magnum.travis-ci.com/zendesk/arsi)

Block sql statements that are not scoped by id in `.update_all` and `.delete_all`.

ID Columns:

- *_id
- id
- guid
- uuid
- uid

Operators:

- =
- <>
- IN
- IS

Triggers the `Arsi.violation_callback` with SQL and relation object.By default raise `Arsi::UnscopedSQL`.

## Disabling

via `.without_arsi`

```ruby
User.where(active: false).without_arsi.delete_all # I know what I'm doing...

```

via `ARSI.disable`

```ruby
class ApplicationController < ActionController::Base
  around_filter :without_arsi
  def without_arsi(&block)
    Arsi.disable(&block)
  end
end

Arsi.disable do
  User.update_all name: "Pete" # will be ignored
end
```


## Limitations

 - MySQL on Rails 3.2
 - uses regexs on SQL, false negatives with specially crafted SQL statements can occur
{'fraction_non_alphanumeric': 0.09435517099299547, 'fraction_numerical': 0.004532344458178822, 'mean_word_length': 4.176972281449894, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '580875', 'n_tokens_mistral': 815, 'n_tokens_neox': 792, 'n_words': 261}