{"id":9352,"date":"2019-09-27T14:19:27","date_gmt":"2019-09-27T17:19:27","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=9352"},"modified":"2019-09-27T17:07:36","modified_gmt":"2019-09-27T20:07:36","slug":"incorrect-access-control-in-simple-form-cve-2019-16676","status":"publish","type":"post","link":"http:\/\/blog.plataformatec.com.br\/2019\/09\/incorrect-access-control-in-simple-form-cve-2019-16676\/","title":{"rendered":"Incorrect Access Control in Simple Form (CVE-2019-16676)"},"content":{"rendered":"\n
Simple Form version The issue applies only to forms that are built using user-supplied input. For example, the following form that builds a label based on user input:<\/p>\n\n\n In this case, the If you build your forms with backend-provided information only, your application is not affected by this issue.<\/p>\n\n\n\n By knowing that this breach exists, an attacker could invoke any method on the form object. This means that they could do any of the following:<\/p>\n\n\n\n The issue is caused by Simple Form\u2019s automatically discover of input types feature. When a form input is provided without the This works for a bunch of input types but it doesn\u2019t for file inputs. In the case of file inputs, they can have a lot of different names – In order to discover file inputs, Simple Form was calling The default value of the Simple Form was changed to check in a different way whether some attribute might be suitable for a file input. It now checks for the presence of methods directly, without calling The officially supported Gems are:<\/p>\n\n\n\n Although this new code is harder to maintain, we think it\u2019s worth the tradeoff with more security. See the\u00a0commit<\/a>\u00a0with the solution for more information.<\/p>\n\n\n\n Note:<\/strong> This solution does not support multiple file upload inputs, as this is very application-specific. To render file input for multiple file upload, use the You might have noticed that we released this fix in a major version ( If you had changed the In the meantime, you can explicitly say which type the input is:<\/p>\n\n\n If you can\u2019t upgrade for any reason but want to be protected from the security breach, you can also explicitly pass the input type – using 5.0<\/code> was released today with a fix for a security issue that could allow an attacker to execute methods on form objects. The issue is explained in details below.<\/p>\n\n\n\n
Description<\/h2>\n\n\n\n
<%=<\/span> simple_form_for<\/span> @user<\/span> do<\/span> |form<\/span>| %><\/span>\n <%=<\/span> form.label<\/span> @user_supplied_string<\/span> %><\/span>\n ...\n<%<\/span> end<\/span> %><\/span>\n<\/code><\/div>Code language:<\/span> HTML, XML<\/span> (<\/span>xml<\/span>)<\/span><\/small><\/pre>\n\n\n
@user_supplied_string<\/code> would be invoked as a method call in the
@user<\/code> object (unless the string contains any of the following:
password<\/code>,
time_zone<\/code>,
country<\/code>,
email<\/code>,
phone<\/code> or
url<\/code>).<\/p>\n\n\n\n
Possible implications<\/h2>\n\n\n\n
#destroy<\/code>)<\/li>
Cause<\/h2>\n\n\n\n
as<\/code> option, the library tries to discover which type that input is. This is done with a regular expression for the most common types. Something like this:<\/p>\n\n\n
case<\/span> attribute_name.to_s\nwhen \/(?:\\b|\\W|_)password(?:\\b|\\W|_)\/ then :password\nwhen \/(?:\\b|\\W|_)time_zone(?:\\b|\\W|_)\/ then :time_zone\nwhen \/(?:\\b|\\W|_)country(?:\\b|\\W|_)\/ then :country\nwhen \/(?:\\b|\\W|_)email(?:\\b|\\W|_)\/ then :email\nwhen \/(?:\\b|\\W|_)phone(?:\\b|\\W|_)\/ then :tel\nwhen \/(?:\\b|\\W|_)url(?:\\b|\\W|_)\/ then :url\n<\/code><\/div>Code language:<\/span> JavaScript<\/span> (<\/span>javascript<\/span>)<\/span><\/small><\/pre>\n\n\n
avatar<\/code>,
attachment<\/code>,
profile_image<\/code> and so on.<\/p>\n\n\n\n
#send<\/code> on the object passing
attribute_name<\/code> as the parameter. That would result in an object, which would then later be checked against a list of file methods, to decide whether that attribute should be a file input or not:<\/p>\n\n\n
def file_method?(attribute_name)\n file = @object.send(attribute_name) if @object.respond_to?(attribute_name)\n file && SimpleForm.file_methods.any? { |m| file.respond_to?(m) }\nend\n<\/code><\/div><\/pre>\n\n\n
SimpleForm.file_methods<\/code> config was:
[:mounted_as, :file?, :public_filename, :attached?]<\/code> which are basically methods present in some popular file upload Gems.<\/p>\n\n\n\n
Solution<\/h2>\n\n\n\n
#send<\/code>. For example, the check for ActiveStorage looks like this:<\/p>\n\n\n
@object<\/span>.respond_to?(\"#{attribute_name<\/span>}_attachment<\/span>\")\n<\/code><\/div>Code language:<\/span> CSS<\/span> (<\/span>css<\/span>)<\/span><\/small><\/pre>\n\n\n
as<\/code> option.<\/p>\n\n\n\n
How to upgrade<\/h2>\n\n\n\n
5.0<\/code>). This was done because to fix the issue, we had to fully deprecate the
SimpleForm.file_methods<\/code> configuration. There are no other breaking changes in this release, so it should be easy to upgrade.<\/p>\n\n\n\n
SimpleForm.file_methods<\/code> configuration to include other methods, please check whether they are from one of the supported Gems. If they are, you should be fine without them. If they are from another upload library, please open an issue<\/a> asking for support and we\u2019ll take a look into it.<\/p>\n\n\n\n
<%=<\/span> form.input<\/span> :avatar<\/span>, as:<\/span> :file<\/span> %><\/span>\n<\/code><\/div>Code language:<\/span> HTML, XML<\/span> (<\/span>xml<\/span>)<\/span><\/small><\/pre>\n\n\n
Can\u2019t upgrade?<\/h3>\n\n\n\n
as<\/code> – to your user-based forms. That would make Simple Form return early and not execute the user input on the object.<\/p>\n\n\n\n
Acknowledgments<\/h2>\n\n\n\n