wiki icon indicating copy to clipboard operation
wiki copied to clipboard

Add POC for connection pool attacks.

Open NDevTK opened this issue 2 years ago • 22 comments

https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/

It seems powerful since it allows for timing attacks even when theirs CSRF protection. And theirs limits that only affect one host allowing for better precision and tracking such as

  • https://source.chromium.org/chromium/chromium/src/+/master:net/socket/client_socket_pool_manager.cc;l=43
  • https://source.chromium.org/chromium/chromium/src/+/main:net/spdy/spdy_session.h;l=79 (maybe)

It would even be possible to exclude resources just by caching them.

NDevTK avatar Aug 04 '21 12:08 NDevTK

Yeah awesome idea, I tried to develop a PoC a few times and it's not easy.

// First tab
for(let i=0; i<128; i++) fetch(`https://x${i}.server.xom/stall`, {mode:'no-cors'})
// Second tab
for(let i=0; i<128; i++) fetch(`https://x${128+i}.server.xom/stall`, {mode:'no-cors'})

This seemed to work more or less.

terjanq avatar Aug 04 '21 19:08 terjanq

Hey!

The original Connection Pool Exhaustion report contains a POC: https://bugs.chromium.org/p/chromium/issues/attachmentText?aid=339460

I used it multiple times in the past and it worked very well with few modifications but I am not sure if it needs to be adapted to circumvent newer browser mitigations. Chrome shipped a partitioned cache, but I am not sure if socket pools were part of that initial effort. In any case hope this helps you.

manuelvsousa avatar Aug 04 '21 21:08 manuelvsousa

@manuelvsousa the report uses yahoo mail may also work for other services allowing XS-Search seems bad. From what I understand about it you can do timing attacks even if its a separate request in a different window with CSRF protection. Caching is not needed.

NDevTK avatar Aug 04 '21 22:08 NDevTK

@terjanq do you think it would be possible to create a traffic monitor in javascript? That shows the time, duration and maybe host of each network request in a table.

NDevTK avatar Aug 04 '21 23:08 NDevTK

Since network bandwidth is limited it would be hard for a browser to prevent this attack not even sure what a website can do to prevent it. Even by denying search from url it still allows for tracking. mitm attacks probably have the same issue :(

NDevTK avatar Aug 04 '21 23:08 NDevTK

@manuelvsousa the report uses yahoo mail may also work for other services allowing XS-Search seems bad. From what I understand about it you can do timing attacks even if its a separate request in a different window with CSRF protection. Caching is not needed.

Sorry, I did not want to imply you would need caching for this, I mentioned partitioned caches because their bundle also include http socket partition which is what you need to consider for this attack. AFAIK Chrome did not ship this (nor implemented), but Firefox for example already offers an implementation (issue1, issue2) on by default.

manuelvsousa avatar Aug 05 '21 09:08 manuelvsousa

@manuelvsousa if it was done using the "top-level document's origin" that could still be abused with window.open() Anyway the network will always make this attack possible. Being able to do XS-Search attacks without any practical way to defend it for a website seems bad.

NDevTK avatar Aug 05 '21 17:08 NDevTK

Yeah, you are correct as it's in theory possible, but as we learned in the past years it's a difficult task to have clear deterministic protections against XS-Leaks, which means that sometimes we need to look at the trade-off of applying certain mitigations and evaluate their impact in protecting specific XS-Leaks (i.e, the level of how much we reduce the chance of success).

I would say that for this specific case it would be quite a heavy challenge to pull off a timing attack with socket exhaustion in a browser with socket pool partitioning which automatically forces you to use window.open, because you would have to open ~255 tabs, maintain stability at various levels (ram, cpu, network), fight other websites for resources and well, make sure the victim doesn't notice it :) And all of this to obtain only one timing measurement, which itself does not tell much to an attacker :)

Being able to do XS-Search attacks without any practical way to defend it for a website seems bad.

I could not agree more and that is why we (the web) must think and adopt new new protections and when possible offload their integration from developers who really don't have to deal with issues like these :)

I think we could work on a POC for this, even if the ultimate goal is to show case what happens in browsers which do not partition their socket pools. If you are up for it and need assistance, feel free to ping this issue for assistance and I will try to help you.

Reconsidering the defenses for timing attacks (which includes this one), maybe it's worth dedicating some time to reevaluate what it's possible to achieve considering a browser with socket partitioning, Same-Site=Lax by default, COOP (and maybe a default policy), Isolation Policies in websites, etc

manuelvsousa avatar Aug 05 '21 18:08 manuelvsousa

@manuelvsousa yeah if the only limit was socket exhaustion it would require a popunder bug. However the network connection has limited bandwidth that can also be exploited. As said in the first comment it seems theirs also a stream limit of 100 and a connections per host limit of 6. Not sure why ~255 windows cant be reused for a different attack. COOP does improve it a lot but just one search could still provide information depending on the target.

I think it would be good to create a working POC thats generic like what I said in https://github.com/xsleaks/wiki/issues/115#issuecomment-893048721 or simplified if thats to hard to get working.

NDevTK avatar Aug 05 '21 18:08 NDevTK

I wanted to keep some connections open annoyed that glitch.com uses http/2 :/

NDevTK avatar Aug 05 '21 21:08 NDevTK

Found https://deelay.me/100000/ for a delayed reply with no HTTP/2 used.

NDevTK avatar Aug 06 '21 01:08 NDevTK

@terjanq do you think it would be possible to create a traffic monitor in javascript? That shows the time, duration and maybe host of each network request in a table.

I am not sure I understand what you mean. If it's about browser extensions then yeah, it should be possible (and there should be already tools in place)

terjanq avatar Aug 06 '21 11:08 terjanq

@terjanq every tab shares the same network so it maybe possible to detect when a request is made, Because a fetch will be slower when theirs less usable bandwidth. With enough reliably it can also be used to track the duration of requests. Since http/2 has connection reuse it maybe slower to make a fetch to a website that has no existing connection.

NDevTK avatar Aug 06 '21 16:08 NDevTK

You are suggesting that from two different origins two requests can end up in the same http/2 stream? That would be wild. I don't know if that's possible but if it was then indeed some new ideas would be possible.

terjanq avatar Aug 06 '21 16:08 terjanq

@terjanq chrome devtools network tab has a connection id feature. https://stackoverflow.com/a/43520092 it seems a connection gets shared when using fetch("https://<HOST>/?c="+Math.random(), {mode: "no-cors", credentials: "include"});

NDevTK avatar Aug 06 '21 19:08 NDevTK

There does seem to be a delay for the first connection but dont know a way to force disconnect the connection, So you have to wait for the browser to close it. Maybe other timing attacks can be done with the connection.

NDevTK avatar Aug 07 '21 01:08 NDevTK

Update :D When fetching https://www.google.com from https://example.com You can force close the connection by doing for(let i=0; i<4000; i++) fetch('https://example.com', {mode: "no-cors"}); and waiting for the net::ERR_INSUFFICIENT_RESOURCES then TypeError: Failed to fetch errors. (Lack of testing)

NDevTK avatar Aug 07 '21 01:08 NDevTK

  • So I guess its possible to do a timing attack for http/2 by checking for no significant difference between a request with and without credentials: "include" that has an existing connection and if there is abort the request. however its a bit annoying since DoSing the cache might not always work.

  • If there is a stream limit https://source.chromium.org/chromium/chromium/src/+/main:net/spdy/spdy_session.h;l=79 then It might be better to abuse that.

NDevTK avatar Aug 08 '21 22:08 NDevTK

Made a function for testing the delay.

async function checkDelay(domain, times) {
var TODO = [];
let start = performance.now();
for(let i=0; i<times; i++) {
TODO.push(fetch('https://'+domain+'/?v='+i+Math.random(), {mode: 'no-cors'}));
};
await Promise.all(TODO);
let time = performance.now() - start;
return time;
}

NDevTK avatar Aug 10 '21 21:08 NDevTK

I should relay get back to this, being able to do timings attacks with DNS maybe interesting.

NDevTK avatar Sep 09 '21 23:09 NDevTK

@terjanq do you think it would be possible to create a traffic monitor in javascript? That shows the time, duration and maybe host of each network request in a table.

I think that should be doable with the connection pool attack. The only problem I think might arise is in this situation: The attacker's site A exhausts all the connections. Now it does a request to victim's site B right after releasing one of his occupied connections. Now he ques another request to time the time until the request to site B is done. Now, site B is loaded and the browser ques let say 5 requests for further resources to be loaded. I don't know if you will be able to measure the time of every one of those requests. I don't see how you could inject your connections between those requests to make the timing attack work.

@terjanq every tab shares the same network so it maybe possible to detect when a request is made, Because a fetch will be slower when theirs less usable bandwidth. With enough reliably it can also be used to track the duration of requests. Since http/2 has connection reuse it may be slower to make a fetch to a website that has no existing connection.

In theory, this should be possible. But if you want to apply this in a real scenario I think there are just too many factors you can't control. For example the traffic usage of different applications on the host system (this might be everything from steam updates to watching Netflix, where the network usage isn't stable at one specific kb/s value )

BitnomadLive avatar Oct 10 '21 09:10 BitnomadLive

@BitnomadLive

In theory, this should be possible. But if you want to apply this in a real scenario I think there are just too many factors you can't control. For example the traffic usage of different applications on the host system (this might be everything from steam updates to watching Netflix, where the network usage isn't stable at one specific kb/s value )

The benefit of abusing HTTP/2 would be that it requires for the same host to use the same connection. If that connection has its own limits it can be abused otherwise just being able to detect the connection has been established, Means a request was made to that host. issue being how to force close the connection.

I also made https://devicemonitor.glitch.me/ it may be possible to detect when a request was made using it.

NDevTK avatar Oct 10 '21 17:10 NDevTK

Closing as merged although any improvements would be good :)

NDevTK avatar Nov 06 '22 18:11 NDevTK