Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
How does Facebook disable Developer Tools? (stackoverflow.com)
258 points by gedrap on Feb 12, 2014 | hide | past | favorite | 86 comments


I don't think Developer Tools are going to be able to allow overriding like this for long, or we're going to be seeing a lot of this on sites soon, just like the widespread right-click "disabling" of yesteryear.


I don't think it's as simple as that - there's a lot more damage you can do by copy-pasting arbitrary code obtained via a social engineering vector into the dev console, than right-clicking to save an asset.

I'd consider this a genuine security issue, and wouldn't be surprised if the dev console at least got moved behind a lot more 'here be dragons' warnings.

or hide it behind a turing-test-for-engineers ... 'solve the following code test to enable the dev console' ;)


Oh, I don't mean for the purposes of security, but sites thinking that they're protecting their content in some way by dropping in a future jquery plugin or whatever that disables the console, and suddenly the hackability and usability of the web becomes much less.

Another place where you see this sort of thing: banks that try to prevent password managers from filling in your credentials (also I've seen a few recently that try to prevent you from pasting in your password).

There is a tradeoff there too: like this Facebook trick helping save some users, bank tricks probably help some users from accidentally saving their bank credentials on some public or shared computer, but it makes it really annoying (or not possible short of opening devtools and setting the input box's value manually) for those of us that want a unique and more-or-less random password for each site we visit.


If you are using FF or Chrome you can just make your browser run a js script after loading a certain page.

It's neat for small changes as you don't have to write a whole extension just a simple script.


Web browsers had had the capability to execute javascript through the URL bar since as long as I can remember. Social engineers should be able to just bypass this by telling users to copy paste the following code, Control+L, type "javascript:" (chrome strips it when copy-pasting), Control+V, Enter.

    javascript:alert('hi ' + document.body.innerHTML);
If people can be tricked into executing code in the dev console, then why not this too?


Browsers have already started to remove/limit code execution capability from the address bar.

https://bugzilla.mozilla.org/show_bug.cgi?id=656433

https://code.google.com/p/chromium/issues/detail?id=82181


Wait does this mean bookmarklets will fail in those browsers from now on?


My bookmarklets run just fine, JS in the URL-bar doesn't.


But bookmarklets execute via the URL bar, that's all they are...


Do the bookmarklets execute in the context of the page?


Yes, they work just as they've always done.


That no longer works in newer Firefox (and I think Chrome?). You can turn that back on in about::settings though.

edit: Ooops, someone had already made a post to this effect. Sorry.


I tested it in Chrome before posting. Notably it removes the javascript: from the clipboard, but that's why I said to have the user type that part.


I think (Chrome & Firefox) you can use a content security policy to prevent JavaScript running from the address bar:

http://en.wikipedia.org/wiki/Content_Security_Policy


Something something security by obscurity something something.


This isn't anything to do with security by obscurity. This is like putting a cover over the launch missiles button.


I seems too easy to disable developer tools. What about a fork of chrome that prevent disabling this tools


There's an interesting link in the accepted answer about how the social engineering hack, that necessitated the disabling of Developer Tools in the first place, was executed in the first place: https://www.facebook.com/photo.php?v=956977232793


I'm sort of surprised that the developer tools have only recently become an attack vector (via social engineering). I'm not sure what can even really be done about it without seriously inconveniencing developers. Maybe making them disabled by default with an extra option to enable them would be enough to deter all but the most gullible of users?


> Maybe making them disabled by default with an extra option to enable them would be enough to deter all but the most gullible of users?

Safari does this


Why not a separate package altogether? That way the Chrome team can focus on Chrome, and the Developer Tools team can focus on producing a high-quality website debugger.


Because the "hackability" of the web is important. The ability to view source, play in the console, modify the dom, etc is amazing. Locking it down or providing a larger barrier to entry (eg, download this extra thing) provides dubious benefit and hides what makes the web great.

I speak from someone who teaches ruby and javascript. Javascript is in every browser and the console is a wonderful place to start. When I teach ruby (on Mac's) I have to start with, "well ok, now download xcode". It's really easy for someone to give up before getting everything working.


You can download the command line tools package from apple instead to get the compiler which is only a couple hundred megs instead of the 5 gig bloat that is xcode. Definitely saves a lot of hassle.


So downloading a 100KB extension for a browser which you use for downloading stuff all the time is a "huge barrier"? Wow, talk about a 1st world problem.

And "when I teach ruby", "well ok, now download xcode"... ok, Xcode is a 2.5GB download, but it is a one click download and install via App Store. And really? Xcode for Ruby? Are you really doing that?


Xcode is necessary because Apple distributes an operating system without a C compiler, and standard Ruby development requires a C compiler. Why Apple distributes an incomplete operating system by default, and why they distribute their development environment as one monolithic chunk as opposed to a set of packages, is anyone's guess.


Last I checked, Windows also doesn't ship with a C compiler by default. Even some Linux distros don't have it in the default install.


Windows is also an incomplete operating system as sold, as are those Linux distros. For a long time Windows was outright defective because there was no compiler available without paying hundreds of additional dollars to Microsoft, but they do have a free toolchain now.


OS X is an Open Brand UNIX 03 Registered Product since Leopard and given this it can be considered "complete." It isn't shipped with a compiler but your can install the cmdline tools (without all the XCode bundle) typing:

   xcode-select --install
on (Mavericks) Terminal.


standard Ruby development requires a C compiler

Mac OS X comes with Ruby already installed, and afaik you don't need a C compiler to learn standard ruby, you'd only need it for certain gems (which want to build native extensions).


OS X comes with an obsolete version of Ruby which almost nobody uses.

Standard Ruby development generally involves both a Ruby version manager (rvm, rbenv, etc.) and the ability to install gems with native extensions.


OS X comes with an obsolete version of Ruby which almost nobody uses.

The latest version of OS X comes with Ruby 2.0, which is hardly obsolete, and that or Ruby 1.8.7 (from earlier OS X) is totally fine for learning to use Ruby, which is how this thread started.

Claiming you need to start to learn by installing xCode or the tools is false - there is lots more to ruby than installing rvm, rails and sql gems etc. Beginners could go a long way without requiring non-native gems, and by the time they get to that stage, installing Ruby 2.0 should be a breeze, whatever route you choose.

Probably over 95% of mac users would never use the compiler, so I see why they left it out. Installing it is really very easy anyway, command line or with xcode.


Well i guess because 80% of mac users will never need a compiler.

Also instead of downloading the whole xcode you can download the xcode cli tools.


When you're teaching someone a subject that they expect to be challenging and aren't forced to learn, any extra barrier can dissuade them entirely. Think of the learning process like the conversion funnel for a web site.


I write JavaScript all day and the first step is to download XCode. I don't know if this is his reason, but installing XCode is the best way to get all the developer tools installed (clang, for example).


If scammers can get people to open the developer console and paste code, they can get them to install the "developer tools extension" and then open the console and paste code. Add all the warnings you want, the scammer will say "see what facebook doesn't want you to see!!!".

This has been called the "dancing monkeys problem". People can really be manipulated into doing anything in order to see the dancing monkeys (even if they couldn't be convinced to do those things for constructive purposes).

IMHO you just can't save people from themselves, might as well stop trying and making my life harder.


https://en.wikipedia.org/wiki/Dancing_pigs

Never seen it called "dancing monkeys" - got a cite?


I heard it as "dancing bunnies". I think more people will go for dancing bunnies, than pigs or monkeys -- bunnies are cuter! I wonder if scammers do A/B testing...


'Citation'. 'Cite' is the verb.


You'd think I was writing Wikipedia jargon after a Wikipedia URL or something.


We can put bareers here forever that will deter more and more developers and curious yet-to-be hackers from playing with the web, while scammers will just use simple social tricks to make gullible people jump through any obstacle we put.

Here, to be honest, I vote for natural selection. Fight the scammers, and let the gullible be scammed until the society develops an immune response. It happens all the times, and I think that at least a part of the solution for Internet scam is to accelerate immune response development as much as possible.


How isn't this a type of immune response?


The ongoing dumbing down of the Internet would be an autoimmune disease.


I would imagine that that would only be activated with a full deployment of FB, so developers wouldn't have to worry about it.


The accepted answer teases that this is not enough:

  Object.defineProperty(console, '_commandLineAPI',
   { get : function() { throw 'Nooo!' } })
But why isn't it enough?


I spent a while looking at it last night and came up with a solution, I'll walk you through it. For reference, here's the code:

    function escape(s) {
      // Bonus level!

      Object.defineProperty(console, 'foo', 
         { get : function() { throw 'nooo!' } });

      var code = 'with(window.console && console.foo || {}) {\n\t'+s+'\n}';
      console.log(code);

      try {
        console.log(eval(code));
      } catch (e) {
        console.log(e);
      }
    }
The idea is, you need to craft `s`, such that `s` can execute arbitrary code without throwing 'nooo!'. The interesting problem is, any access to `console.foo` with throw because the getter above is called. This includes the access inside the `with` statement. So the solution, if there is any, must somehow cause mutation of state before the `with` even executes.

Now, what brought me to the solution was this thought: "What in Javascript allows you to execute code before a given statement?" Upon framing it in this way, the solution became immediately clear: function declarations are automatically hoisted!

If you redefine `console` to be an object without the property 'foo', the `|| {}` part of the with predicate will instead be passed as the scope, and you have free reign to walk about the system.

So the solution is:

    alert(1) } function console(){} {
Which produces the statement:

    with(window.console && console.foo || {}) { 
      alert(1) } function console(){} {
    }


Ah, cool. That's a little shorter than the solution that I came up with:

  function window(){alert(1)}window()
To those of you going for the code golf record, you can save a character in STRML's solution by redefining window instead. Furthermore, the last two braces can be omitted and whitespace removed for a total of 27 characters.


Ah, very clever, thanks :)


Because it is possible to get around with just code: http://escape.alf.nu/20

(which I have done, under another username)


So how do you get around it? Or, I suppose more importantly, what else do you have to do to prevent people from getting around it?


It seems he's routing calls to print the code into console.log and eval-ing that string, which is quite interesting.


Eh? Who is "he"? What do you mean routing calls?


In the snippet posted by tshadwell. The code outputs a string into the console via console.log(), then executes the snippet from the console via eval(). Presumably to avoid to avoid Facebook's protections against console copy\paste execution.

Edit: I'm wrong. Need some sleep.


tshadwell did not post a code snippet he wrote. He posted a link to a site that demonstrates the sandbox that Facebook uses (I believe the Facebook engineer that wrote the Facebook implementation also owns escape.alf.nu). This code does not break out of the sandbox, it creates it.


I never claimed tshadwell wrote it, but you are correct, my skimming of the code was incorrect. It redirects the evaluated output of an escaped version of a string to the console.


This is an analysis of the code that facebook is trying to prevent from being pasted into the console

http://pastebin.com/0JXCVxXg


I thought it was obfuscated variable names, but it's a turkish word https://en.wiktionary.org/wiki/arkada%C5%9Flar (follower)


It means "friends". There are some functions named "get messages", "get friends", "get a random friend" and "post comment" too. Weird.


Not yeah I dont know why I thought this was about twitter so I only wrote follower (close semantics, and wiktionary listed both). So it's an i10n CRUD controller :)


How is this "browser vulnerability" different from a bookmarklet?


Or a browser extension.


How is this exploit not possible by just telling someone to paste javascript:alert(document.cookie) etc into their address bar?


Because pasting doesn't work. Most browsers (like Chrome, IE) just remove the javascript: prefix from your pasted text, and some browsers (like Firefox) don't allow you to execute standard javascript from the address bar.


I agree. Chrome doesn't allow you do paste it, you have to type it. I believe they disable it soon too.


See the link in the accepted answer. If you try to paste in "javascript: blahblahblah", Chrome is smart enough to remove the "javascript: " part. What the attackers do instead is to tell the victim to type "j", then ctrl+v the rest "avascript: blahblahblah". Just tried it in Chrome, it goes through.


Clever.


Have you tried doing that recently? Doesn't work on Firefox and Chrome, not for some time.


That is the original exploit mentioned in the accepted answer; however, Firefox and IE have disabled execution of javascript from the address bar, and I assume that Chrome is also moving to do the same thing.


And after that Hackers will start telling people do open their Concole in Developer Tools and paste the code there. I believe many people will do.


...which is exactly what this post is about..? That's the reason Facebook disables the DevTools console apparently.


But you rapidly reach a point beyond which most users can get to. Three steps: (1) open console, (2) copy, (3) paste is about the limit on what an average computer user can do these days.


Facebook is violating the user's right to their own software.


Facebook is protecting the vast majority of users and making developers click a checkbox to undo that protection. There are plenty of things to get outraged about, but I'd argue this isn't one of them.


http://Facebook.com/selfxss is all it really takes.


Wouldn't it be just as simple for an attacker to persuade a victim to paste a string starting with "javascript:" into the URL bar?


Both FireFox and Chrome have been preventing that since around 2011; the pasted url is stripped of the "javascript:" part. But now the malicious instructions tell users to press "j" before pasting the url (which is missing the "j" at the start), which prevents the browsers from detecting and stripping the protocol, thus allowing the script execution.


I think the burden lies on the browsers to warn average users of the danger of pasting javascript code. Perhaps a popup confirmation the first time you paste `javascript:...` in the address bar with a "Never ask again," and a warning that "Here be danger" when you open the dev console that you can dismiss.


Doesn't happen for me in Firefox - I can make alerts etc using the console.


This is a pretty good reason to never trust Chrome again.


I wouldn't trust any computer, then.

It's the same as taking a bunch of code you have no idea how works, and paste it into CMD, then wondering why you just deleted C:/


Exactly, how many developers can honestly say they've never copy pasted commands into the terminal without being 100% sure what they were doing?


Hesitantly, I will claim that I can say this because I cannot remember every pasting a command in I did not take the time to understand.


I would indeed not trust any OS that allows you to erase the root filesystem without at least asking for the superuser password :)


Funny that Windows does not even allow Administrator to do it. Ubuntu on other side asks only for user password (sudo)

:-)


>Ubuntu on other side asks only for user password

It's the user password of an admin user. What other password can it possibly ask for? a global su password?


So you're fine with Google allowing coders to change the function of the dev console? Interesting...


I hate the web

I hate the web




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: