1

I'm making use of the library GCDWebServer(https://github.com/swisspol/GCDWebServer) in a project of mine, that requires me to accept connections originating only from my application's process, for security reasons. I was hoping this is something that the iOS app sandbox would provide out of the box, but that doesn't appear to be the case. The sandbox appears to be enforced for UNIX domain sockets(AF_UNIX), by means of file-system permissions. But for TCP/IP sockets(AF_INET), used by GCDWebServer, there appears to be no sandboxing in place.

I was able to write two sample applications - a client and a server(signed with different developer certificates) and could have them communicate with each other, without any issues.

I was wondering if there was some way of enforcing the same on iOS, essentially spin up a HTTP server on a TCP socket but only accept connections from the same process. I can't make use of UNIX domain sockets, because the client which is going to request the content from the HTTP server is an AVPlayer and it wouldn't know how to connect to my application's UNIX domain socket.

HungryTux
  • 355
  • 3
  • 14
  • Perhaps you could elaborate on why you want to do that and maybe there's an alternative which is more suitable that could be recommended... – Zigglzworth Jun 27 '17 at 11:50
  • I thought as much. The idea is to pre-cache segments of a HLS(HTTP Live Streaming) video on the disk and have a local proxy server serve them if cached, or re-direct to the remote URL otherwise. So what we would be providing to an AVPlayer is a URL that looks like localhost:8080/MyVideo/playlist.m3u8. This is an optimization we're trying to make, to reduce video load times. Hope that explains the use-case. – HungryTux Jun 28 '17 at 02:52

2 Answers2

1

I'm about 99% certain that what you're asking for is impossible. I don't even think it is possible in OS X without writing a network kernel extension (and even then, it would be challenging).

By the time a network request reaches another process, it has passed through the networking stack and has lost any notion of what process originated the connection (unless this has improved fairly recently).

Realistically, the closest you can get is binding to a random port on the localhost interface and tearing it down as soon as your app gets put into the background.

Pedantically, if you managed to somehow convince Apple that you planned to build a VPN, it is theoretically possible to abuse the VPN API in such a way that would let you provide a private network that worked only within your app. It would not, however, ever be allowed in the app store.

But why would you ever want to do this? AVPlayer is more than capable of playing from a file URL.

dgatwood
  • 10,129
  • 1
  • 28
  • 49
  • I thought as much. The idea is to pre-cache segments of a HLS(HTTP Live Streaming) video on the disk and have a local proxy server serve them if cached, or re-direct to the remote URL otherwise. So what we would be providing to an AVPlayer is a URL that looks like http://localhost:8080/MyVideo/playlist.m3u8. This is an optimization we're trying to make, to reduce video load times. Hope that explains the use-case. – HungryTux Jun 28 '17 at 02:51
  • Also it appears that GCDWebServer already takes care of tearing down the webserver when the app is backgrounded. What I'm more concerned about is the use case where a malicious app uses one of the background capabilities on iOS to attempt connecting to the local proxy server started by my app. And if there's any vulnerabilities in the source code of the server(Eg: https://www.rapid7.com/db/modules/exploit/windows/http/sws_connection_bof), that allows for arbitrary code execution, then the other app gains control of my application's resources. – HungryTux Jun 28 '17 at 02:59
1

There are many ways you could do that: you can inspect the incoming request in GCDWebServer and decide if you want to respond to it or return an error.

You could add a secret header other apps wouldn't know about, sign the entire request with a secret key, etc...

Pol
  • 3,848
  • 1
  • 38
  • 55