Hacker News new | ask | show | jobs
by tgragnato 3388 days ago
An information leak is an information leak : we still fail to realise that it's something that's happening daily. There's no drama in it.

Criminals are taking advantage of opportunities like this every day, still no one cares too much about it (HN bubble & friends excluded).

Things like this may have a strong impact or not in the press/popularity circus, but in this particular case it seems they promptly monitored the situation (thanks to their competent staff).

What most surprises me is that their highly competent staff is thoughtlessly violating one of the security principles in sw : SECURITY BY ISOLATION .

No one (no matter how able you are) can write absolutely bug-free algorithms : even when dealing with formal verified software you can still attack the assumptions.

Security by correctness is a laudable effort, but computing customers data with a single process is not sane. I'm aware they're doing this for performance reasons, but a well implemented isolation layer would have prevented this (even while dealing with a bug like that).

Their architecture is vulnerable.

2 comments

> What most surprises me is that their highly competent staff is thoughtlessly violating one of the security principles in sw : SECURITY BY ISOLATION .

I don't think this is really true, but I'm open to hearing your thoughts on this. There was a bug in their HTML parser which caused unrelated memory to be dumped to the process. Their SSL termination servers were isolated elsewhere which is why SSL keys weren't dumped into public caches.

Where would you like them to draw the isolation boundary? Per function? Per rule? Per service? From what I understand, these processes were a part of a single service, but not every request was using each type of rule.

Even if they'd only had customers using their html parser isolated on separate servers, other customers would have been affected even if their HTML was perfectly valid according to the parser.

I think the implication is that the isolation should be per customer, each being allocated their own parsing process, isolated from the other customers.

That's roughly what we do, though we run an hosted version of an open source webapp, not a CDN. It's more expensive resource-wise (particularly RAM), but it has meant that we were immune to 90%+ of the security bugs discovered in the platform.

Sure, that's a valid question to ask. But imagine you have 1,000,000 customers. Now you have to calculate and manage scaling groups for 1,000,000 customers * number of services. The resourcing costs alone would be outlandish, not to mention trying to independently scale each customer. Perhaps container systems would make this easier, but do they have better memory isolation? Is it possible for a container process to overrun into another containers memory without an exploit in the container system?
A container is a process with some extra isolation (namespaces), they certainly can't overrun into each other without an exploit.

Why would the costs be outlandish? We offer that and we're fairly cheap. Since the cost is mostly fixed per customer, it should scale linearly.

As for scaling, they already have to do that, by pointing different requests at different servers depending on their load, etc.

Assuming for a minute that containers aren't in play, then the isolation model becomes that of a server/vm with the associated overhead of each. To make this easier we'll assume there's only a single service, even though we know this to be untrue.

If there are 1M customers that's a minimum of 1M servers. Some customers are obviously larger and would need more. There's also HA. Let's conservatively call it 2.5M servers.

At an absolute bare minimum we'd need to allocate 2.5M GB of ram and 2.5M vCPU. That's a huge amount of resources.

If you could reliably fit 10000 Small customers on a single server at 32gb ram and 8 cpus you can already start to see how many resources can be saved.

Without customer isolation you've got the entire cluster to handle load spikes and HA. With isolation you have to have scheduling monitoring each of the 1M clusters and scaling appropriately by anticipating demand.

Scaling a service is way easier than scaling customers within a service or many services.

Assuming for a minute that containers aren't in play, then the isolation model becomes that of a server/vm with the associated overhead of each.

Why? There's nothing magical about a container, it's literally just a cgroup of Linux processes. You don't have to use them to get the memory isolation we're talking about - uncontained processes get it too.

That's what we do: one process per client, uncontained, just running on a different system user.

But in any case, sure, use containers, I'm certainly not opposed to them.

There are many ways to ensure a system is fault-tolerant, scalable and still reasonably safe.

They certainly have the resources to solve this if only they want.

All I can say is that I am not willing to pay for something so fragile, but that is only my own opinion.

In the real world things may go differently: they exposed critical data back in 2012 too and they're still here ...

Linux namespaces/containers create a memory page table completely separate from the host's so barring vulnerabilities in the container implementation that allow mapping host physical memory to guest virtual, isolation is strictly enforced by the memory controller in the hardware. Without an exploit, the worst case scenario is leaking shared library read-only sections across containers (since the physical memory might be shared for a smaller container footprint, although i don't know if LXC supports that yet).
> Linux namespaces/containers create a memory page table completely separate from the host's

Each _process_ has its own memory page table. Containers are built out of processes, so they inherit this attribute.

Namespaces have nothing to do with it.

Sorry, I should have elaborated: with namespaces, each container instance gets its own process table with separate non-shareable pages (without KSM or other dedup feature) and then each container process gets its own page tables, like they normally do. The point is that there's an extra level of isolation beyond just processes, although there is still the kernel attack surface.
> each being allocated their own parsing process

That just punts the vulnerable code elsewhere. A kernel bug could leak memory across processes. And the kernel is also written in C, so you aren't getting protection from a "better" language either.

That's assuming that the likelihood of such a bug in the kernel code is the same as a bug in an HTML parser. And also that this bug would go unnoticed for months. The fact that both are written in C doesn't make them equal.
absolutely true
Thing is, with the single model process, a kernel bug could also leak memory between customers. And in fact, it's much more likely, since for it they're all in the same security context. So it's not punting the code, it's reducing the attack surface.
> And in fact, it's much more likely, since for it they're all in the same security context.

I disagree. I think it's much less likely, because the kernel doesn't usually get involved in the process' memory once it is allocated.

Sure, it maps the virtual memory about to physical memory as needed, but bugs there is likely to cause severe corruption resulting in an immediate crash. The kernel doesn't go low level enough for it to be likely to result in messing with a process such that the single process continues to work but also leaks across the process-internal customer boundary that the kernel cannot see. That would require a level of surgical precision I don't think is likely in a bug.

To be clear, I'm not saying that you shouldn't use per-customer processes. The kernel has more eyes and is less likely to be vulnerable in this way. Just that from an analytical perspective, you are really just moving the problem elsewhere, rather than solving it.

I read their post "incident report" too . Isolation is claimed, but if I understand correctly, HTTP handling is shared between customers. Am I wrong ?

Suppose you're a "bad actor", knowing this is a shared service, wouldn't you look for 0 days in it ? A carefully crafted exploit has the potential to leak specific content from unaware customers again.

The attack surface is nginx (http://nginx.org/en/security_advisories.html) plus each component of each loaded module ...

It would be saner to apply isolation to each element of the cartesian product between customers and services.

The performance (and cost) impact can be mitigated by scheduling resources over a pool of disposable virtual machines (obviously in xen and with iommu protection), but I bet they can develop even better solutions.

Even if there were a set of VMs per customer (and all the scaling per customer overhead that goes along with that), a carefully crafted exploit would still reveal details for that customer. Then it'd be a matter of enumerating all of the customers you were interested in exploiting, which would make it easier to get data for a specific target.

The operational overhead of VM/Container isolation for the cartesian product of customer + service sounds like it'd be extremely prohibitive. It's certainly a tradeoff, but to claim it's saner is missing all of the other costs associated with such a system.

Yeah it makes a targeted attack easier. But it prevents attacks across different customers. Tradeoffs ...

Maintaining a running pool of VMs per service in a sufficient number to serve the load of requests grouped by customer, and assigning the VM to a specific customer only at needs is different than running permanently a pool of (n).customers x (m).services VMs.

This is why an efficient scheduler and the usage of disposable VMs is a need. Still depending on the load and the variety of the traffic it may not be feasible, you are absolutely right !

Another approach to ensure isolation is the usage of a MAC framework. As I wrote "I bet they can develop even better solutions" ;)

The point is that if they had isolated their customers only those customers using that particular feature would have been affected. Now potentially all customers have been affected.
It's not much to go on, but it seems they are looking into better isolation going forward: https://disqus.com/home/discussion/cloudflare/incident_repor...
We'll be sure to write up details of things we have changed. It's ongoing.