May 09

Overzealous input validation

Apple's iCal has an interesting bug in its data validation code. If you attempt to subscribe to a calendar on an HTTPS server it will timeout for awhile and give an "invalid hostname" error. The first time I encountered this I assumed that it didn't have SSL support and was simply using an overly-broad error message. Later I noticed that you could publish to an SSL-protected WebDAV server and decided to try a little harder on those https calendars.

If you attempted to enter an https:// URL, it will be stored as http://https://, explaining that "invalid hostname". This is an example of a common source of annoying behaviour: over-zealous input valid. URLs are fairly complex - there are many protocols, some system dependent, optional usernames and passwords, multiple host formats, etc. Building a parser in a language without decent library functions is non-trivial and many programmers punt the problem of building a parser which can handle all of the options allowed in even a moderately complex standard in favor of simple hardcoded string operations - like prepending "http://" if the string doesn't already start with it.

This approach breaks valid URLs and the worst part is that it's completely unnecessary since the programmer already has access to a complete validating URL handler in the form of the underlying network library (CoreFoundation or DAVAccess according to otool -L) which already has to be capable reporting an error if a given URL couldn't be retrieved - whether the error is from a malformed URL or a dead server is irrelevant. In other words, a programmer at Apple actually spent time writing code which makes iCal less capable than it would have been had he done nothing at all, in which case you would also be able to publish to FTP, Windows or AppleShare servers and you'd automatically gain support for things like SFTP if the appropriate extensions were installed or built into later versions of the operating system.

Fortunately, this bug is only in the user interface: if you edit ~/Library/Preferences/com.apple.iCal.sources.plist there's a field containing the source URL and simply changing 'http:' to 'https:' will get everything working (verified with tcpdump). The only downside is that you'll lose the ability to edit the subscription settings within iCal unless you change the URL back to http:.

(If you're using a self-signed CA key, MacOSXHints has instructions for adding your key to the system CA store)