So I made a phonegap app which uses socket.io to do stuff.
I have the following Content-Security-Policy (CSP)
<meta http-equiv="Content-Security-Policy" content="
default-src * data: blob: ws: wss:;
style-src * 'unsafe-inline';
script-src * 'unsafe-inline' 'unsafe-eval';
connect-src * ws: wss:;">
When I start the app on safari / iOS I get the following error:
Refused to connect to ws://10.0.1.63:3000/socket.io/?EIO=3&transport=websocket&sid=xTaMJwP3rVy3UnIBAAAi
because it appears in neither the connect-src directive nor the default-src directive of the Content Security Policy.
AND:
SecurityError (DOM Exception 18): The operation is insecure.
The same app with the same CSP works just fine on Chrome / Android but not on Safari / iOS.
I think this has something to do with:
a refined content security policy (WebKit)
Resources that seem to come up a lot:
Why is it saying "Refused to connect to "URL starting with ws:" because it appears in neither the connect-src directive nor the default-src directive of the Content-Security-Policy even though it is mentioned in both?
Okay, safari / iOS is more strict than chrome / Android when it comes to this, all fine, but it still needs to enable me to allow the connection through. This is really frustrating for an app developer! Solutions?
EDIT: Made a bug report on bugs.webkit.org: https://bugs.webkit.org/show_bug.cgi?id=165754
Okay so this is kind of dumb, but OK, i'll keep this answer so future people can see it and don't have to deal with this problem
What I did wrong was:
I had the following head:
<head>
<meta charset="utf-8" />
<!--<meta http-equiv="Content-Security-Policy"
content="default-src *; style-src 'self' http://* 'unsafe-inline'; script-src 'self' http://* 'unsafe-inline' 'unsafe-eval'" />-->
<meta http-equiv="Content-Security-Policy" content="
default-src * data: blob: ws: wss: gap://ready file://*;
style-src * 'unsafe-inline';
script-src * 'unsafe-inline' 'unsafe-eval';
connect-src * ws: wss:;">
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width" />
<meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline'; style-src 'self' 'unsafe-inline'; media-src"/>
<link rel="stylesheet" type="text/css" href="css/reset.css" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<title>Kerst app!</title>
</head>
And I didn't notice that I had the "Content-Security-Policy" meta tag twice
I know right? The duplicate caused iOS to just take the latest one which was more strict. Removed the duplicate, worked the first time around.
And finally the corect Code
<head>
<meta charset="utf-8" />
<!--<meta http-equiv="Content-Security-Policy"
content="default-src *; style-src 'self' http://* 'unsafe-inline'; script-src 'self' http://* 'unsafe-inline' 'unsafe-eval'" />-->
<meta http-equiv="Content-Security-Policy" content="
default-src * data: blob: ws: wss: gap://ready file://*;
style-src * 'unsafe-inline';
script-src * 'unsafe-inline' 'unsafe-eval';
connect-src * ws: wss:;">
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width" />
<link rel="stylesheet" type="text/css" href="css/reset.css" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<title>Kerst app!</title>
</head>