title: Nested attributes rejection proc bypass in Active Record
description: "There is a vulnerability in how the nested attributes feature in Active
Record \nhandles updates in combination with destroy flags when destroying records
is \ndisabled. This vulnerability has been assigned the CVE identifier CVE-2015-7577.
\n\nVersions Affected: 3.1.0 and newer \nNot affected: 3.0.x and older \nFixed
Versions: 5.0.0.beta1.1, 188.8.131.52, 184.108.40.206, 220.127.116.11 \n\nImpact \n------ \nWhen
using the nested attributes feature in Active Record you can prevent the \ndestruction
of associated records by passing the `allow_destroy: false` option \nto the `accepts_nested_attributes_for`
method. However due to a change in the \ncommit [a9b4b5d] the `_destroy` flag
prevents the `:reject_if` proc from \nbeing called because it assumes that the record
will be destroyed anyway. \n\nHowever this isn't true if `:allow_destroy` is false
so this leads to changes \nthat would have been rejected being applied to the record.
Attackers could use \nthis do things like set attributes to invalid values and to
clear all of the \nattributes amongst other things. The severity will be dependent
on how the \napplication has used this feature. \n\nAll users running an affected
release should either upgrade or use one of \nthe workarounds immediately. \n\nReleases
\n-------- \nThe FIXED releases are available at the normal locations. \n\nWorkarounds
\n----------- \nIf you can't upgrade, please use the following monkey patch in an
initializer \nthat is loaded before your application: \n\n``` \n$ cat config/initializers/nested_attributes_bypass_fix.rb
\nmodule ActiveRecord \n module NestedAttributes \n private \n\n def reject_new_record?(association_name,
attributes) \n will_be_destroyed?(association_name, attributes) || call_reject_if(association_name,
attributes) \n end \n\n def call_reject_if(association_name, attributes) \n
\ return false if will_be_destroyed?(association_name, attributes) \n\n case
callback = self.nested_attributes_options[association_name][:reject_if] \n when
Symbol \n method(callback).arity == 0 ? send(callback) : send(callback, attributes)
\n when Proc \n callback.call(attributes) \n end \n end \n\n
\ def will_be_destroyed?(association_name, attributes) \n allow_destroy?(association_name)
&& has_destroy_flag?(attributes) \n end \n\n def allow_destroy?(association_name)
\n self.nested_attributes_options[association_name][:allow_destroy] \n end
\n end \nend \n``` \n\nPatches \n------- \nTo aid users who aren't able to upgrade
immediately we have provided patches for \nthe two supported release series. They
are in git-am format and consist of a \nsingle changeset. \n\n* 3-2-nested-attributes-reject-if-bypass.patch
- Patch for 3.2 series \n* 4-1-nested-attributes-reject-if-bypass.patch - Patch
for 4.1 series \n* 4-2-nested-attributes-reject-if-bypass.patch - Patch for 4.2
series \n* 5-0-nested-attributes-reject-if-bypass.patch - Patch for 5.0 series \n\nPlease
note that only the 4.1.x and 4.2.x series are supported at present. Users \nof earlier
unsupported releases are advised to upgrade as soon as possible as we \ncannot guarantee
the continued availability of security fixes for unsupported \nreleases. \n\nCredits
\n------- \nThank you to Justin Coyne for reporting the problem and working with
us to fix it. \n\n: https://github.com/rails/rails/commit/a9b4b5da7c216e4464eeb9dbd0a39ea258d64325
- "~> 3.0.0"
- "< 3.0.0"
- "~> 5.0.0.beta1.1"
- "~> 4.2.5, >= 18.104.22.168"
- "~> 4.1.14, >= 22.214.171.124"
- "~> 126.96.36.199"