is it a security hole to verify an uploaded supposed-to-be-zip file as a zip with zip_open()?
That seems reasonable to me. I would probably place the file in a temporary directory first and then use zip_open on it in that location.

You may also be able to use OS level commands (which come with their own risks) to verify the integrity of the file without actually unzipping it.

Are you going to store the zip files as zip files after being uploaded? Doing so presents additional issues since zips can be used to contain lots of files that may or may not be appropriate. You may want to get a list of the contents of the file to automatically include in your field so people downloading them will know if the file contents are valid. You could also integrate with something like http://drupal.org/project/clamav to scan all the files that are uploaded.