The issue is that CORS gates access only on the consent of the target server. It must return headers that opt into receiving requests from the website.
This proposal aims to tighten that, so that even if the website and the network device both actively want to communicate, the user's permission is also explicitly requested. Historically we assumed server & website agreement was sufficient, but Facebook's recent tricks where websites secretly talked to apps on your phone have broken that assumption - websites might be in cahoots with local network servers to work against your interests.
So the attack vector that I can imagine is that JS on the browser can issue a specially crafted request to a vulnerable printer or whatever that triggers arbitrary code execution on that other device. That code might be sufficient to cause the printer to carry out your evil task, including making an outbound connection to the attacker's server. Of course, the webpage would not be able to discover whether it was successful, but that may not be important.
It may send an OPTIONS request, or not.
It may block a request being sent (in response to OPTIONS) or block a response from being read.
It may restrict which headers can be set, or read.
It may downgrade the request you were sending silently, or consider your request valid but the response off limits.
It is a matrix of independent gates essentially.
Even the language we use is imprecise, CORS itself is not really doing any of this or blocking things. As others pointed out it’s the Single Origin Policy that is the strict one, and CORS is really an exception engine to allow us to punch through that security layer.
Maybe there is some side-channel timing that can be used to determine the existence of a device, but not so sure about actually crafting and delivering a malicious payload.
<img src="http://192.168.1.1/router?reboot=1">
triggers a local network GET request without any CORS involvement.None of us had to pass a security test to post here. There's no filter. That makes it pretty likely that HN's community is exactly as shitty as the rest of the internet's.
People need to stop treating this community like some club of enlightened elites. It's hilariously sad and self-congratulatory.
Though to be fair, a lot of web frameworks have methods to bind named inputs that allow either.
In the modern web its much less of an issue due to samesite cookies being default .
You cant do a DELETE from a form. You have to use ajax. If cross DELETE needs preflight.
To nitpick, CSRF is not the ability to use forms per se, but relying solely on the existence of a cookie to authorize actions with side effects.
While it clearly isn't a hard guarantee, in practice it does seem to generally work as these have been known issues without apparent massive exploits for decades. That CORS restrictions block probing (no response provided) does help makes this all significantly more difficult.
It's not just HTTP where this is a problem. There are enough http-ish protocols where protocol smuggling confusion is a risk. It's possible to send chimeric HTTP requests at devices which then interpret them as a protocol other than http.
The target application in this case was trying to validate incoming POST requests by checking that the incoming MIME type was "application/json". Normally, you can't make unauthorized XHR requests with this MIME type as CORS will send a preflight.
However, because of the way it was checking for this (checking if the Content-Type header contained the text "application/json"), It was relatively easy to construct a new Content-Type header that bypasses CORS:
Content-Type: multipart/form-data; boundary=application/json
It's worth bearing in mind in this case that the payload doesn't actually have to be form data - the application was expecting JSON, after all! As long as the web server doesn't do its own data validation (which it didn't in this case), we can just pass JSON as normal.
This was particularly bad because the application allowed arbitrary code execution via this endpoint! It was fixed, but in my opinion, something like that should never have been exposed to the network in the first place.
I've been that sloppy with dev servers too. Usually not listening on port 80 but that's hardly Ft Knox.
[0] https://github.com/bitcoin/bitcoin/blob/v29.0/src/httprpc.cp...
https://www.kb.cert.org/vuls/id/476267 is an article from 2001 on it.
The browser will restrict the headers and methods of requests that can be sent in no-cors mode. (silent censoring in the case of headers, more specifically)
Anything besides GET, HEAD, POST will result in an error in browser, and not be sent.
All headers will be dropped besides the CORS safelisted headers [0]
And Content-Type must be one of urlencoded, form-data, or text-plain. Attempting to use anything else will see the header replaced by text-plain.
[0] https://developer.mozilla.org/en-US/docs/Glossary/CORS-safel...
What framework allows you to setup a misconfigured parser out of the box?
I dont mean that as a challenge, but as a server framework maintainer Im genuinely curious. In express we would definitely allow people to opt into this, but you have to explicitly make the choice to go and configure body-parser.json to accept all content types via a noop function for type checking.
Meaning, its hard to get into this state!
Edit to add: there are myriad ways to misconfigure a webserver to make it insecure without realizing. But IMO that is the point of using a server framework! To make it less likely devs will footgun via sane defaults that prevent these scenarios unless someone really wants to make a different choice.
I don’t know the exact frameworks, but I consume a lot of random undocumented backend APIs (web scraper work) and 95% of the time they’re fine with JSON requests with Content-Type: text/plain.
Does no-cors allow a nefarious company to send a POST request to a local server, running in an app, containing whatever arbitrary data they’d like? Yes, it does. When you control the server side the inability to set custom headers etc doesn’t really matter.
I didnt mean it to come across that way. The spec does what the spec does, we should all be aware of it so we can make informed decisions.
Note: preflight is not required for any type of request that browser js was capable of making prior to CORS being introduced. (Except for local network)
So a simple GET or POST does not require OPTIONS, but if you set a header it might require OPTIONS (unless its a header you could set in the pre-cors world)
Also, form submission famously doesn't require CORS.
As far as I can tell, the only thing this proposal does that CORS does not already do is provide some level of enterprise configuration control to guard against the scenario where your users are using compromised internet sites that can ping around your internal network for agents running on compromised desktops. Maybe? I don't get it.
If somebody would fix the "no https for local connections" issue, then IoT websites could use authenticated logins to fix both problems. Non-https websites also have no access to browser crypto APIs so roll-your-own auth (the horror) isn't an option either. Fustrating!
Wondering whether I triggered CORS requests when I was struggling with IPv6 problems. Or maybe it triggers when I redirect index.html requests from IPv6 to IPv4 addresses. Or maybe I got caught by the earlier roll out of version one of this propposal? There was definitely a time while I was developing pipedal when none of my images displayed because my web server wasn't doing CORS. But. Whatever my excuse might be, I was wrong. :-/
https://security.stackexchange.com/questions/232345/ebay-web...
... Anyhow I think it doesn't matter because you can listen for the error/failure of most async requests. Cors errors are equivalent to network errors - the browser tells the js it got stays v code 0 with no further information - but the timing of that could lead to some sort of interference? Hard to say what that would be though. Maybe if you knew the target webserver was slow but would respond to certain requests, a slower failed local request could mean it actually reached a target device.
That said, why not just fire off simple http requests with your intended payload? Abusing the csrf vulnerabilities of local network devices seems far easier than trying to make something out of a timing attack here.
Significant components of the browser, such as Websockets have no such restrictions at all
they also had some kind of RPC websocket system for game developers, but that appears to have been abandoned: https://discord.com/developers/docs/topics/rpc
https://github.com/adc/ctf-midnightsun2022quals-writeups/tre...
False. CORS only gates non-simple requests (via options), simple requests are sent regardless of CORS config, there is no gating whatsoever.
Typically there are only 256 IP's, so a scan of them all is almost instant.
This isn't going to help for that. The locally installed app, and the website, can both, independently, open a connection to a 3rd party. There's probably enough fingerprinting available for the 3rd party to be able to match them.
C'mon. We all know that 99% of the time, Access-Control-Allow-Origin is set to * and not to the specific IP of the web service.
Also, CORS is not in the control of the user while the proposal is. And that's a huge difference.
Client: I consent
Server: I consent
User: I DON'T!
ISN'T THERE SOMEBODY YOU FORGOT TO ASK?
One of the solutions in the market was open source up to a point (Nowina NexU), but it seems it's gone from GitHub
For local network, you can imagine similar use cases — keep something inside the local network (eg. an API to an input device; imagine it being a scanner), but enable server-side function (eg. OCR) from their web page. With ZeroConf and DHCP domain name extensions, it can be a pretty seamless option for developers to consider.
It's just the default. So far, browsers haven't really given different IP ranges different security.
evil.com is allowed to make requests to bank.com . Similarly, evil.com is allowed to make requests to foo.com even if foo.com DNS resolves to 127.0.0.1 .
I remember having "zone" settings in Internet Explorer 20 years ago, and ISTR it did IP ranges as well as domains. Don't think it did anything about cross-zone security though.
I deal with a third-party hosted webapp that enables extra when a webserver hosted on localhost is present. The local webserver exposes an API allowing the application to interact more closely with the host OS (think locally-attached devices and servers on the local network). If the locally-installed webserver isn't present the hosted app hides the extra functionality.
Limiting browser access to the localhost subnet (127.0.0.1/8) would be fine to me, as a sysadmin, so long as I have the option to enable it for applications where it's desired.
What attack do you think doesn't have a solution? CSRF attacks? The solution is CSRF tokens, or checking the Origin header, same as how non-local-network sites protect against CSRF. DNS rebinding attacks? The solution is checking the Host header.
It's called ZTA, Zero Trust Architecture. Devices shouldn't assume the LAN is secure.
This is a problem impacting mass users, not just technical ones.
MacOS currently does this (per app, not per site) & most users just click yes without a second thought. Doing it per site might create a little more apprehension, but I imagine not much.
My parents who are non-technical click no by default to everything, sometimes they ask for my assistance when something doesn't work and often it's because they denied some permission that is essential for an app to work e.g. maybe they denied access to the microphone to an audio call app.
Unless we have statistics, I don't think we can make assumptions.
The moment a user gets this permissions request, as far as I can tell they will hit approve 100% of the time. We have one office where the staff have complained that it's impossible to look at astrology websites without committing to desktop popups selling McAfee. Which implies those staff, having been trained to hit "no", believe it's impossible to do.
(yes, we can disable with a GPO, which I heavily promote, but that org has political problems).
A random website someone linked me to wanting to access my local network is a very different case. I'm absolutely not giving network or location or camera or any other sort of access to websites except in very extreme circumstances.
Maybe this won't fool you, but it would trick 90% of internet users. (And even if it was 20% instead of 90%, that's still way too much.)
But I was just pointing out that, while I'll make good use of it, it still probably won't offer sufficient protection (from themselves) for most.
Besides that, approximately zero laypersons will have even the slightest clue what this permission means, the risks involved, or why they might want to prevent it. All they know is that the website they want is not working, and the website tells them to enable this or that permission. They will all blindly enable it every single time.
For example, it's pretty straightforward what camera, push notification, or location access means. Contact sharing is already a stretch ("to connect you with your friends, please grant...").
"Local network access"? Probably not.
They're just two different approaches with the same flaw: People with no clue how tech works cannot completely protect themselves from any possible attacker, while also having sophisticated networked features. Nobody has provided a decent alternative other than some kind of fully bubble-wrapped limited account using Group Policies, to ban all those perms from even being asked for.
Remember when they used to mock this as part of their marketing?
Microsoft deserved to be mocked for that implementation.
Creation of a shortcut on Windows is not necessarily innocuous. It was a common first vector to drop malware as users were accustomed to installing software that did the same thing. A Windows shortcut can hide an arbitrary pathname, arbitrary command-line arguments, a custom icon, and more; these can be modified at any time.
So whether it was a mistake for UAC to be overzealous or obstructionist, or Microsoft was already being mocked for poor security, perhaps they weren’t wrong to raise awareness about such maneuvers.
If you want to teach users to ignore security prompts, then completely pointless nagging is how you do it.
The "correct answer" to this is probably that there isn't a good answer here.
Security is a damn minefield and it's getting worse every day.
This is why Microsoft was so widely mocked for just how bad their initial implementation of UAC was.
https://discussions.apple.com/thread/254931245
iOS Shortcut danger
https://cyberpress.org/unveiling-risks-of-ios-shortcuts/
But anywho, cve.org lists 78 shortcut vulnerabilities across many platforms.
I know you'd like to believe the world we live in shouldn't require permissions for a user to create a shortcut and then access it, but that... Is actually the world we live in, and have been in for a very long time.
Security is hard and it's not getting any easier as system complexity increases.
If you don't believe me, ask your favorite LLM. I asked Gemini and got back what I expected to.
Yes, as a Chromecast user, please do give me a break from the prompts, macOS – or maybe just show them for Airplay with equal frequency and see how your users like that.
https://www.youtube.com/watch?v=wLgcb4jZwGM&list=PL1y1iaEtjS...
It's not clear to me from Google's proposal if it also restricts access to localhost, or just your local network - it'd be great if it were both, as we clearly can't rely on third parties to lock down their local servers sufficiently!
edit: localhost won't be restricted:
"Note that local -> local is not a local network request, as well as loopback -> anything. (See "cross-origin requests" below for a discussion on potentially expanding this definition in the future.)"
It will be restricted. This proposal isn't completely blocking all localhost and local IPs. Rather, it's preventing public sites from communicating with localhost and local IPs. E.g:
* If evil.com makes a request to a local address it'll get blocked.
* If evil.com makes a request to a localhost address it'll get blocked.
* If a local address makes a request to a localhost address it'll get blocked.
* If a local address makes a request to a local address, it'll be allowed.
* If a local address makes a request to evil.com it'll be allowed.
* If localhost makes a request to a localhost address it'll be allowed.
* If localhost makes a request to a local address, it'll be allowed.
* If localhost makes a request to evil.com it'll be allowed.