algorithm—it is probably some inadequacy in the larger system added by
a developer in the mistaken belief that
strong cryptography means strong security. Crypto is not soy sauce for security.
This attack is fairly elementary to
execute. It can be done with a tool no
more complicated than Firefox with
Firebug installed: add an extra parameter to the form, switch the submit
URL, and instantly gain control of any
account you wish. Of particular note
to open source software projects and
other scenarios where the attacker
can be assumed to have access to the
source code, this vulnerability is very
visible: the controller in charge of
authorization and access to the user
objects is a clear priority for attackers
because of the expected gains from
subverting it. A moderately skilled attacker could find this vulnerability
and create a script to weaponize it in a
matter of minutes.
How to avoid this scenario. This particular variation of the attack could be
avoided by checking authorization,
but that does not by itself prevent all
related attacks. An attacker can create an arbitrary number of accounts,
changing the owner _ id on each to
collide with a victim’s legitimate user
ID, and in doing so successfully delink
the victim’s data from his or her login.
This amounts to a denial-of-service attack, since the victim loses the utility
of the Diaspora service.
After authentication has been
fixed, write access to sensitive data
should be limited to the maximum
extent practical. A suitable first step
would be to disable mass assignment,
which should always be turned off in
a public-facing Rails app. The Rails
team presumably keeps mass assignment on by default because it saves
many lines of code and makes the
15-minute blog demo nicer, but it is
a security hole in virtually all applications.
Luckily, this is trivial to address:
Rails has a mechanism called attr _
accessible, which makes only the
listed model attributes available for
mass assignment. Allowing only safe
attributes to be mass-assigned (for example, data you would expect the end
users to be allowed to update, such
as their names rather than their keys)
prevents this class of attack. In addition, attr _ accessible documents
programmers’ assumptions about
security explicitly in their application
code: as a whitelist, it is a known point
of weakness in the model class, and it
will be examined thoroughly by any security review process.
This is extraordinarily desirable,
so it’s a good idea for developers to
make using attr _ accessible
compulsory. This is easy to do: simply
call ActiveRecord:: Base.attr _
accessible(nil) in an initializer,
and all Rails models will automatically have mass assignment disabled
until they have it explicitly enabled by
attr _ accessible. Note that this
may break the functionality of common Rails gems and plugins, because
they sometimes rely on the default.
This is one way in which security is a
problem of the community.
An additional mitigation method,
if your data store allows it, is to explicitly disallow writing to as much data as
is feasible. There is almost certainly
no legitimate reason for owner _ id
to be reassignable. ActiveRecord lets
you do this with attr _ readonly.
MongoMapper does not currently support this feature, which is one danger
of using bleeding-edge technologies
for production systems.
def self.search(query)
Person.all(‘$where’ =>
“function()
{ return this.diaspora _ han-dle.match(/^#{query}/i) ||
this.profile.first _ name.
match(/^#{query}/i) ||
this.profile.last _ name.
match(/^#{query}/i); }”)
#Permits code injection to
MongoDB.
end
mature. For example, the canonical
attack against SQL databases is SQL
injection: using the user-exposed interface of an application to craft arbitrary SQL code and execute it against
the database.
nosQL Doesn’t mean
no sQL Injection
The new NoSQL databases have a
few decades less experience getting
exploited than the old relational databases we know and love, which
means that countermeasures against
well-understood attacks are still im-
Impact. The previous code snippet
allows code injection into MongoDB,
effectively allowing an attacker full
read access to the database, including to serialized encryption keys.
Observe that because of the magic of
string interpolation, the attacker can
cause the string including the JavaScript to evaluate to virtually anything
the attacker desires. For example, the
attacker could inject a carefully constructed JavaScript string to cause the
first regular expression to terminate
without any results, then execute arbitrary code, then comment out the rest
of the JavaScript.
We can get one bit of data about
any particular person out of this find
call—whether the person is in the result set or not. Since we can construct
the result set at will, however, we can
make that a very significant bit. JavaScript can take a string and convert it