URLConnection and the dreaded NSURLErrorDomain

I made a simple test application with this command…

Connection.Send("GET", "https://72.142.79.106:9630/api/")

it returns the following error…

The operation couldn’t be completed. (NSURLErrorDomain error -1012.)

I’ve provided nothing but the url but I should be getting back a 403 error at least.

I’ve imported the following info.plist file but it doesn’t seem to help.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSExceptionDomains</key>
		<dict>
			<key>72.142.79.106</key>
			<dict>
				<key>NSIncludesSubdomains</key>
				<true/>
				<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
				<true/>
			</dict>
		</dict>
	</dict>
</dict>
</plist>

Attempting to access the url via curl provides the following insight…

% curl https://72.142.79.106:9630/api/                                        
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
% 

Using curl -k provides an encrypted response.

On the other hand, I have a PHP script that uses curl_exec() and can access this server without issue. Similar to the -k option, it simply sets the following curl options…

		curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER, False);
		curl_setopt($curlHandle, CURLOPT_SSL_VERIFYHOST, 0);

Is there any way to do this with URLConnection in Xojo?

Ssl doesn’t do ip addresses. So try with a domain name or try without ssl.

I created an A record on the client’s domain that points to the same IP address used above and after confirming propagation with a dig command, I tried again.

Using the curl command, I get the same response but with URLConnection, now I get a slightly different error…

An SSL error has occurred and a secure connection to the server cannot be made.

Adding this line before the Send() does nothing.

Connection.AllowCertificateValidation = False

Using HTTPSecureSocket seems to solve the issue but is less desirable due to its deprecated status.

Var https As New HTTPSecureSocket
https.Get("https://72.142.79.106:9630/api/", 10)

Still… we’re just trying to do a one-time data extraction and it’s an old server so maybe old code is the answer.

Still wondering why this didn’t work.

If you can reproduce it failing in a sample project, file a ticket.

I was actually doubting myself and whether or not I understood what it was supposed to do. If is the equivalent to CURLOPT_SSL_VERIFYPEER = False then yes, I will file a ticket.

Feedback case created… <https://xojo.com/issue/62583>

My feedback case was marked as “By Design” and closed. However, I’m still not entirely clear on why or what the AllowCertificateVerification property is supposed to do.

Greg O’Lone
November 14, 2020 - 2:50pm UTC
So setting CURLOPT_SSL_VERIFYPEER to false or by using HTTPSecureSocket with certificate validation turned off, you run the risk of a man-in-the-middle attack where an attacker spoofs a good known website using a less secure site to harvest secure data. Your basically saying “I know the certificate that was returned doesn’t match the URL I typed, but just connect anyway”
URLConnection uses a system-level socket and it, by default, makes sure that the certificate matches the domain that you typed. It does not surprise me that the use of an IP address triggers this error.
Have you tried using the domain name that’s assigned to that certificate with the port number instead?

Greg O’Lone
November 14, 2020 - 2:53pm UTC
uh yeah. This is a self-signed certificate. You shouldn’t be using this on the open internet anyway.
Notice the note:
“server.local” certificates do not meet pinning requirements
That’s the issue.

Greg O’Lone
November 14, 2020 - 2:54pm UTC
This case has been closed because the behavior described is not a bug.

So, from what I can gather here, setting AllowCertificateVerification to False is a bad idea. You shouldn’t do it so the software, by design, will not allow it.

There are two problems with this response.

  1. Security issues raised could be mitigated with the use of a VPN or virtually eliminated if the solution was only used on localhost or on a private network. While encouraging best practises through strategically set defaults isn’t a bad idea, it shouldn’t be the role of the IDE to enforce security.

  2. Why offer an option if you’re going to ignore it? Either I’m using this feature incorrectly or it doesn’t work in which case, it should be fixed or removed.

And this brings me to the reason why I’m posting this here rather than responding to the feedback case… I simply may not understand what this feature does and under what circumstance it should be used.

How are we to use Xojo to connect to older servers that don’t meet the modern security requirements? Setting this to False seemed to me to be the answer but it didn’t work.

Note: In my case, we only need to run this software once on localhost to extract data from a legacy system. So, this is one of those rare cases in which security is not a concern.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.