LRBlog

Logical Reality Design: Web Design and Software Development

Archive for the ‘Web Security’ Category

Thoughts on the Github Hack

March 5, 2012

Over the weekend, a young coder demonstrated a security vulnerability in github.com - one with wide-reaching implications. An early demonstration is at: https://github.com/rails/rails/issues/5239.

Our friend went on to make several updates to github as he experimented/demonstrated the vulnerabilities, got his account suspended, reinstated and set off a firestorm of criticism every which way.

I was ready to put it all into the "someone is wrong" pile, until I ran across this pull request on the Rails core: https://github.com/rails/rails/pull/4062.  That's some mid-90's Microsoft style arrogance right there, and on the off chance that anyone is having trouble seeing it, I figured I might add my breath to the maelstrom.

First of all: it was not right to hack github.  It's not okay to ignore the intent of security, no matter how weak the enforcement.  Much better to have pointed out the vulnerability to github, although for sure the fame wouldn't have been as bright (which is why I'm pointedly not referring to him by name in this post.)  Given github's track record, I think there's a pretty good chance they would have come clean, admitted the fault, as well as crediting its reporter.  But that's complete supposition.

That said, I don't think it's legitimate to consider Github a blameless victim.  The flaw in Rails that was exploited is well known, and well reported, and easy, if irritating, to fix.

The technical aside here is pretty simple.  In a file in config/initializers add:

ActiveRecord::Base.__send__(:attr_accessible, nil)

Then you need to white-list mass-assignable attributes in your models:

attr_accessible :name, :body, :whatever

And keep an eye on your logs for

WARNING: Can't mass-assign protected attributes: :blah

Which is a sign that you might need to add an entry for :blah into the respective model.

All pretty simple.  There are a couple of other notes, like "don't allow reference fields (e.g. :person_id) to be mass assigned" but that's the meat of it.  Put the initializer in your generator (that's much harder) and you never have to think about it again.

So, Github didn't put a simple, well-reported fix into their code.  Is that so bad?  I think so.  Github not only invited the developer community to trust them with the products of their labor, pretty much ousting SourceForge from that position in the process and firming up a development environment choice for open source work (i.e. "use git for version control"), it also invites developers to trust them with secrets.  Specifically, the secret contents of client repositories.  Heck, they get you to pay for the privilege.   So, in short, Github is taking money to keep secrets.  And by not covering a known security hole in a default Rails deploy, they were failing to uphold the trust of their paying customers.

I think Github was letting us down pretty badly.  I think an overzealous coder did a bad thing to bring that to light, but you can't argue that Github should be surprised or is blameless.  Two bad things, no one is blameless.

But the last straw for me was reading the Rails core teams' replies to a pull request to set the default for whitelisting attributes in Rails 4.0 to 'true.'  (After previous discussion concluded that making the change for 3.2 would be "too disruptive.")  That having to do attr_accessible for every model was "a lot of paperwork" - the final commend is @dhh's "I don't like this. -1"  Which is to say: we would rather put unsanitized data into the database than do the bare minimum of manual review.  And that's pretty lame.

 

A Security Insight

February 16, 2011

I may just be re-discovering an idea that's widely known, but I realized recently why cryptography is so important to computer security.  When there's no there there, the only physical constraint is time, and cryptography is a way to leverage that physical constraint into a security constraint.

Arguably, the fundamental problem of security (analogous to the fundamental problem of economics being scarcity) is constraining bad actors.

Good actors function in a society where their constraints are moral, ethical and legal.  We find that we can accomplish great things when we rely on these constraints, but the trade off is that we depend on them as universal constraints.  We can have a powerful dynamic economy, so long as no one commits fraud, or insider trading, etc.  Realistically, we can tolerate a certain amount of violation, but everyone needs to know the rules and at least make some attempt to play by them.

The weakness of these constraints is that they are volitional: we are only constrained by them by conscious acceptance.  As an upside, they're cheap to implement.  (Enforcement being a completely separate matter.)

Enter the bad actor.  Mallory (as he is sometimes known) recognizes that, if he's willing to disregard the damage done by violating the volitional constraints that everyone else agrees to, he can make huge gains for himself.

Recognizing that Mallory and his ilk will not accept volitional constraints, we remove the choice in the constrain - Mallory cannot help being a part of the physical universal and bound to laws of physics.  So, we enforce constraints by their application.  We take advantage of the fact that solid objects cannot co-locate (well before we understood why this would be so) by building walls and vaults and fences and keeps.  We use the fact that matter has continued existence to make receipts and licenses and ledgers.  We use the fact that matter cannot be created from nothing (and therefore cannot be perfectly duplicated) with signatures, seals, coinage, keys...

But on a computer, none of those things are true.  There is only data (not even a separate 'code' as much as it's attempted), which is only a pattern, and it exists in the province of a machine designed to manipulate patterns.  The duplication and removal of a pattern is trivial, and to move it from one place to another not much more difficult.

The most remaining physical constraints (that I can think of) are time, connection, and the properties of the hardware the computer system runs on (e.g. power consumption, waste heat, MTBF of components.)  We use connection all the time: firewalls and airgaps, black and white machines, etc.  The trouble is that it is cumbersome to manage connection perfectly, and it tends to be poorly scoped to the action under constraint.  The properties of the hardware are difficult to leverage, since it is often feasible to circumvent them as a constraint - Mallory moves processing to his hardware and throws money at it.

But time, if properly exploited, can be a very effective constraint.  We all have the same amount of time, and cryptographic algorithms can leverage a few seconds of my weak machine's time into more time on a super computer than is likely to be left in the universe.

Something that's interesting about all this is that we haven't removed the volitional aspect from the constraints entirely - merely moved it around, to a smaller and more visible place maybe.  Castles are conquered with the aid of a traitor, accounting systems foiled by colluding participants, and users give their passwords away for chocolate.  As our security systems become more complex and removed from the things they protect, it becomes harder to associate the new volitional constraints they require with the moral, ethical or legal constraints that good actors voluntarily accept.

Bypassing mass assignment for update_attributes

March 14, 2009

I've been following this excellent post by M. Hartl and this post by E. Chapweske banishing mass assignment from one of my Rails applications due to launch soon.

I'm following Chapweske's approach of blocking mass assignment by default in all models, by putting this line in an initializer:

ActiveRecord::Base.send(:attr_accessible, nil)

This had the expected side effect of breaking several zillion tests, because tests frequently use things like Model.build() and Model.create!() to generate on-demand fixtures during testing. Hartl has a great bit of code that creates unsafe_build() and unsafe_create() methods in ActiveRecord. You can use these methods instead of build() and create() to function as expected in your tests.

This works great, except that I also use the mass-assignment method update_attributes! in my tests and specs frequently, particularly when I want to spec the effect a change on one model has on an associated models' methods. So, I expanded on Hartl's helper code a bit, to give myself the necessary methods. In case it helps anyone else:

/lib/initializers/unsafe_build_and_create.rb

class ActiveRecord::Base

# Build and create records unsafely, bypassing attr_accessible.
# These methods are especially useful in tests and in the console.

def self.unsafe_build(attrs)
record = new
record.unsafe_attributes = attrs
record
end

def self.unsafe_create(attrs)
record = unsafe_build(attrs)
record.save
record
end

def self.unsafe_create!(attrs)
unsafe_build(attrs).save!
end

def unsafe_update_attributes!(attrs)
self.unsafe_attributes = attrs
self.save!
end

def unsafe_update_attributes(attrs)
self.unsafe_attributes = attrs
self.save
end

def unsafe_attributes=(attrs)
attrs.each do |k, v|
send("#{k}=", v)
end
end
end

Likely web scam notice: webatrades.com

May 26, 2008

Looking for used cars on Craig's List, my girlfriend and I found what appears to be a classic web escrow auto scam: Web Auto Trades. An ad we responded to (a used Honda Accord at a surprisingly low price for the mileage) claimed to be using their service, which included a "five day guarantee" if you didn't like the car, and said we wouldn't have to meet the seller in person. These are all signs of a typical scam: buyer beware!

Other scam signs: though their snazzy flash-based website presents them as worldwide experts in escrow services, a google search for their domain name results in zero hits, and the domain has only been registered for five days and lists no telephone contacts:


Registrant:
Domain Privacy Group, Inc.
c/o webatrades.com,
5160 Yonge St. Suite 1800
Toronto, ON M2N 6L9
CA

Domain name: webatrades.com

Administrative Contact:
Domain Privacy Group, Inc. privacy-356772@domainprivacygroup.com
c/o webatrades.com,
5160 Yonge St. Suite 1800
Toronto, ON M2N 6L9
CA
Fax:

Technical Contact:
Domain Privacy Group, Inc. privacy-356772@domainprivacygroup.com
c/o webatrades.com,
5160 Yonge St. Suite 1800
Toronto, ON M2N 6L9
CA
Fax:

Registrar of Record: Netfirms Inc.
Record expires on 2009-05-21.
Record created on 2008-05-21.
Database last updated on 2008-05-28 12:54:04.

If you are finding this post because you googled their address after considering buying a car from someone using their service, I strongly consider you to avoid doing business with them, or at least to investigate the company much more thoroughly. Check with your state's attorney general's office to see if they've heard of them or have any complaints, and also consider checking with the BBB. Be very careful not to have your money taken by escrow scams, which this company gives every appearance of being.

Here's a screenshot of their front page, in case they pop up somewhere later under a different name.

This looks like an auto escrow scam.

Update: How to Avoid Escrow Fraud

Here are some useful links on escrow fraud, what it is, and how to avoid it: