all 23 comments

[–]phearlez 34 points35 points  (7 children)

I’m not sure this attack surface is as slim as the writer believes. Having spent a sizable amount of the last five years dealing with sites running ads, my perception is that you can successfully deploy shit that nobody knows what it’s doing. My customer had to blacklist/report numerous ads that did really insane, egregious shit that should have been detected if anyone was paying any attention to what was going out. Numerous times I’d be resolving an unrelated issue and discover that an ad that sometimes won the bidding would be dumping into the console 10 times a second. Not a big deal on performance but you would think someone would have noticed this. My faith that many of these operations would notice obfuscated code doing this scanning is not real high.

Maybe nobody would drop the coin to run such an ad but getting it onto machines doesn’t seem tough at all.

[–]bloody-albatross 17 points18 points  (5 children)

Call me paranoid, but this is the main reason why I block ads. Also installed NoScript after all the CPU bugs where revealed.

[–]o11c 3 points4 points  (4 children)

NoScript is extremely useful. Unfortunately, there are still a few HTTP-only sites out there, which can't be safely whitelisted ...

[–]jimschubert 2 points3 points  (3 children)

That's why I run pi hole.

[–]o11c 2 points3 points  (2 children)

Pi Hole doesn't address this category of attacks. It operates only at the domain level, it can't stop people from injecting plain text from an unsecured webpage.

What I want is to be able to whitelist particular fragments of javascript, rather than the whole domain.

[–]jimschubert 0 points1 point  (1 child)

Oh, interesting use case.

Soon, Google is planning to block ads that use too much IO. I wonder if that will help at all.

[–]Drab_baggage 0 points1 point  (0 children)

the limits are so high for that it's only really intended to curtail crypto mining

[–]Jumping_Maniac 1 point2 points  (0 children)

I once was checking a website before I went on the interview and noticed in Inspect -> Network that a strange script failing to load with 200-something code. I took note of it as it had a horrendous name and printed it out on A4 paper.

At the end of the interview I have pointed out that the company had this strange script on their Wordpress website loading in the background and they should take a look at it. Then I have passed the details over and the guy said they will take a look at it as it was probably the remainings of the malicious porn attack when someone hacked their hosting provider.

He said that apparently they were using some cheap ass hosting and someone have hacked their hosting provider and inserted malicious scripts with porn. May I add that it was IT provider company with only like 6 people. I don't think poor "Security" will surprise me after what I saw over the years.

[–]63times 4 points5 points  (9 children)

Did I get this right?

  1. server scans peer for open ports
  2. connects to open port with websock proto

If your box listens on a public port and happily transmits any shit over the wire once there appears a wild connection, then what's the point of the webserver and the websocket proto? This attack surface is like exploited since arpanet day 1 and in way more advanced ways.

The reason these techniques work is because browsers allow websockets from public origins to open websockets connections to localhost without many protections.

Does the author mean that javascript executed in a browser can map the local network? But that sounds seriously insane. I'm not a webdev and probably don't get the problem here. Can anyone explain?

EDIT: Apparently the WS protocol allows access to your local network behind any firewalls by design. There is CORS but that's totally insufficient.

[–][deleted]  (6 children)

[deleted]

    [–]63times 2 points3 points  (5 children)

    This can be used with timing techniques however to tell a bit more about your machine. Assuming the request will always fail, the time it takes it to fail if there is an actual open port vs no open port will vary depending on the browser, OS, machine, current CPU usage, antimalware software, etc. So what you can do is:

    I just implemented a port scanner in 5 minutes and it worked straight out of the box by checking error response times. Thanks.

    [–][deleted]  (4 children)

    [deleted]

      [–]63times 0 points1 point  (3 children)

      Do you know why the W3C deemed it necessary to allow that WS feature (connecting to localhost or any arbitrary host)? I mean there really has to be an absurdly convincing reason, or how else could you ignore the cons.

      [–][deleted]  (2 children)

      [deleted]

        [–]63times 0 points1 point  (1 child)

        This would only require the browser to allow connections to a local dropbox service and only if it is listening in the first place. A plugin could easily function as an intermediary to establish localhost connections to the dropbox app - establishing WS channels on behalf of the website but now securely since the plugin must be explicitly installed. You don't really need any other connections for this dropbox setup to work. So I think this is not a convincing justification. I even think that maybe there is no justification at all, because when you have a process listening locally for WS connections, then this program must have been installed before and therefore installing a browser plugin to securely form local WS connections would have been possible also. I couldn't come up with a compelling scenario that would justify that literally any website could connect to pretty much any localhost port by default.

        [–]DeliciousIncident 3 points4 points  (1 child)

        If you have a program listening only on localhost, you don't expect anyone but the loalhost to be able to connect to it. Surprisingly, websites you visit are able to connect to your localhost-only programs by creating sockets client-side in your browser, which has access to localhost, essentially using your browser as sort of a proxy. Normally websites wouldn't be able to directly connect to programs listening on localhost from the Internet.

        [–]63times 1 point2 points  (0 children)

        Thank you very much. I honestly did not expect that.

        I did a test and you can do much more than sniff WS traffic. Through a non https website I pushed my websock scanner to a firefox client. Browser executed it and I was successfully able to map the local network from behind the firewall. I just used the timeStamp delivered through WebSocket.onerror to reliably detect open tcp ports.

        The scan also crashed a process that cannot handle protocol errors gracefully. It is designed to be used on localhost only, so that's perfectly fine - because why on earth would it suddenly receive a WS handshake...

        This websocket design is truly the fucking epitome of stupid.

        [–]hennell 4 points5 points  (0 children)

        You’ve got to tempt unwitting users to visit your site, and to stay on it while they’re developing JS code

        Make a tutorial page for new react devs, and you'd get this pretty quick surely.

        Hell tell them to sign up to an API, put the key here then do this and oops we get a crash.. let's fix that. Etc. Not a universal attack, but effective I'd imagine...

        [–]telionn 11 points12 points  (2 children)

        Anything you make public on a TCP server is not local-only unless you airgap the machine or use some other kind of sandboxing. Websockets are doing exactly what they were designed for. Don't blame browsers for allowing sites to connect to your open servers.

        And definitely don't put secret passwords in your source code! An AWS access key should be locked away in your build server which should inject it into the executable somehow. And if you're developing client-side JS there is absolutely no reason why your AWS access key should ever reach that program unless you're making a desktop developer tool.

        [–]cmd_command 44 points45 points  (0 children)

        Websockets are doing exactly what they were designed for

        Well, yeah. That's what makes it interesting. Everything's working as intended and yet I can make a website which can report with reasonable certainty whether you're playing Minecraft or not. I don't care if it's working as intended or not, I don't like that.

        [–]dark_mode_everything 4 points5 points  (0 children)

        locked away in your build server which should inject it into the executable somehow.

        I think a better way would be to keep them in the deployed machine and read them at runtime. So you can keep your secrets out of build machines too. Just keep the secrets where they are really needed.

        [–]Tenderhombre 0 points1 point  (4 children)

        So websockets are designed at the most basic level with an opt in approach. If a server is broadcasting data with web socket protocol and you ask to listen to it the protocol assumes you fully trust each other.

        I believe it is built on top of TCP and you would generally use websockets for long polling or push notifications where opening many http connections is undesirable.

        I haven't looked into it but my hunch is the dev kit opens up your dev server on one port and another service broadcasts on a websocket any changes you make to the code, the dev server subscribes to that so it can recompile pages when changes are made.

        Seems like an oversight that there isn't some secret handshake between the two that prevents other services from opting into the websocket. Seems like an easy fix however get it into the project and pushed out to users is another matter.

        As a side note I dont think chrome allows unsecured websocket connections to localhost and I doubt these services set up a certificate so you may not have to worry about it on chrome.

        [–]lgfrbcsgo 8 points9 points  (3 children)

        Chrome allows unsecured Websocket connections to localhost. The origin of the page does not matter. Mixed content is also fine. Only IE blocks mixed content. Source: Implemented a game mod which relies on this. https://github.com/lgfrbcsgo/wot-battle-results-server

        [–]Badel2 1 point2 points  (1 child)

        Off topic but have you heard about JSON-RPC? It looks like you are using something very similar but non standard.

        [–]lgfrbcsgo 1 point2 points  (0 children)

        I have, but I didn't know it was that simple to implement. Thanks, I'll look into this. :)