TLDR: Nope, and if you think you need that, you're probably doing something wrong.
There is literally no possible way to prevent non-browser access to anything that is also exposed to browsers. As far as a server is concerned, a web browser is just a program that sends and receives HTTP (and related protocols) traffic. That's it. You can do that using curl
, you can do that using any of the many sorts of WebRequest
object available to different programming frameworks, you can do that by opening a simple TCP socket to the server and manually typing out the bytes to send (see the nc
/ncat
/netcat
program). Any information that a browser normally provides - cookies, the User-Agent header, browser-specific HTTPS and URL quirks, HTTP Authorization, TLS client certificates, JavaScript parsing, etc. - can all be spoofed by some other program. That absolutely includes all the CORS headers and behaviors.
What you can do is require authentication. If the consumer of your web service is authenticated, who cares whether they are using a normal web browser, a screen reader for blind people, a mobile application, PHP web server, a telnet
program on a Commodore 64, or tapping out the bits individually very quickly by semaphore?
In theory, cross-origin auth isn't that hard. You have to either send the Access-Control-Allow-Credentials: true
CORS response header (which permits HTTP Authorization headers and cookies) or the Access-Control-Allow-Headers: <HEADERNAME>
CORS response header (with a custom auth header). In either case, you also need to provide some way for a client to gain a valid authentication token (which could be via a web app, or a web service, or some other means; it could even be another CORS-enabled web service). Of course, you similarly have no way of preventing scripted access to the auth service, so anybody/anything with credentials can get a valid token and then use it.
What is your use case, here? Why are you trying to block scripted access? Why do you even expect this would work? I mean web browsers can run scripts, so there's nothing at all preventing a web browser from loading a page that contains JavaScript to access your web service, retrieve the results, and send them to a desktop or server application.
EDIT:
Ultimately is a REST API that enables CORS intrinsically insecure
Either you don't understand what "secure" means, or you don't understand what web servers do. Web servers parse incoming HTTP requests (HTTP being a text-based protocol typically sent on TCP port 80, or wrapped inside a SSL/TLS stream sent to TCP port 443) and, based on the contents of the HTTP request, send back an HTTP response. Web servers are "inherently insecure" in the sense that, if you expose sensitive information on one, anybody who can connect to it over the network and can send the right string of bytes can get back that data. Of course, that's how approximately every network server for every protocol in the world operates, so...
As a side note, this isn't a CORS problem. If you don't allow CORS at all, it will make absolutely no difference to the type of "attacker" you're envisioning. CORS is a way to open a hole in a critical part of the browser security model (called "same-origin policy"), but it is utterly irrelevant to things that are not browsers.