Origin is always present on proxy for ionic serve

Short description of the problem:

We need to call an endpoint, which does control for CORS.
As described in many posts and howto’s, using proxy configuring it in ionic.config.json like this

"proxies": [{
      "path": "/cloud",
      "proxyUrl": "https://blabla.com"
  }]

should resolve the CORS issue

But it seems there is a bug, because it doesn’t work. We sniff with wireshark the headers which are passed after proxy to proxUrl and using ionic serve in the header there is always the origin header like this:
image
So there is http://localhost:8100 for origin but there should not be origin header.

What behavior are you expecting?

Proxy should NO pass origin header to resolve CORS issue

Post the output of ionic info below please
global packages:
@ionic/cli-utils : 1.0.0
Cordova CLI : 7.0.0
Ionic CLI : 3.0.0

local packages:
@ionic/app-scripts : 1.3.7
@ionic/cli-plugin-cordova : 1.0.0
@ionic/cli-plugin-ionic-angular : 1.0.0
Ionic Framework : ionic-angular 3.0.1

System:
Node : v6.10.2
OS : Linux 4.10
Xcode : not installed
ios-deploy : not installed
ios-sim : not installed

This is the issue I opened to the ionic-cli repo:

How is the origin header related to CORS issues?

If you do a for example a POST by an browser over http://localhost:8100 to a service located at https://blabla.com and on that server is CORS check, there is a CORS issue, because the browser adds the origin header to http://localhost:8100 and thats not allowed.
The CORS check checks if the origin host is the same as the servers host.

An proxy removes the origin from the header set by the browser, so there could not be an CORS issue.

Right?

From my understanding: Wrong.

The Service Proxy of Ionic CLI enables you to request URIs that are not on localhost (from where ionic serve … serves) which normally only is only possible if the server returns a Access-Control-Allow-Origin header. If served on localhost and requesting file from localhost - no CORS.

That’s right!
On mobile devices there is no CORS check because there is no Origin header present. But our problem is NOT running on devices, but the problem is with ionic serve or with emulate/run with livereload there is always the ORIGIN in the POST request. To omit this problem there is the Service Proxies as described in the cli readme

So in your opinion (this could probably the right one) there is always present the ORIGIN, but until now I ever saw the CORS check for oigin, as described (I think) also in this old blog post.

http://blog.ionic.io/handling-cors-issues-in-ionic/

I can simple simulate the BUG and CORS behavior with curl.

curl --data '{"Bla":"Bla"}' https://blabla.com/bla => no ORIGIN no CORS error
curl -H "Origin: http://localhost:8100" --data '{"Bla":"Bla"}' https://blabla.com/bla => ORIGIN HEADER and so CORS issue

Then I can simulate the same error by doing the call over the proxy, launched over ionic serve

curl --data '{"Bla":"Bla"}' http://localhost:8100/bla => no ORIGIN no CORS error also over proxy
curl -H "Origin: http://localhost:8100" --data '{"Bla":"Bla"}' http:/localhost:8100/bla => ORIGIN HEADER and so CORS issue also over PROXY

So If you think that’s not the truth, can you please help me? What I’m missing, what I’m doing wrong? Thx a lot!

CORS is a local problem. It makes your browser to not wanting to connect to a server that doesn’t return the correct headers.

If you do a curl re quest and get an error, that is coming from the remote server. CORS has nothing to do with it, but the server is implementing something that you don’t fulfill. What error do you get from curl?

Are you really sure?!?!?

First of all I got an CORS error, and there is no doubt about that. There is an 403 error combined with an CORS error.
And your are right it is the browser to not wanting to connect to a server that doesnt’t return the correct headers! But this problem is bypassed with the PROXY. And in your opinion how is this bypassed with the proxy?!?!?

As reading from the official old blog, you can read this:

There are two ways to solve the issue: The first, and easier, solution is to just allow all origins from your API endpoint. However, we can’t always control the endpoint we are accessing. What we need, then, is a request that does not specify an origin.

We can do this by using a proxy server. Let’s look how the Ionic CLI provides
an easily configurable proxy server.

So honestly I’m pretty sure about the issue and on an older ionic-cli version this was working well, the proxy should “filters” the origin, nothing special to do!

Or not? :slight_smile:

Could you, please, finally post the actual error you are getting? A CORS error is something your local browser gives you, not something returned by a server.

Okay, we are doing this post in the WebApp:

this.post('/cloud/login', JSON.stringify(body), headers)

This is the configuration of your ionic.config.json

{
  "name": "web-client-ionic",
  "app_id": "",
  "type": "ionic-angular",
  "proxies": [{
      "path": "/api",
      "proxyUrl": "http://192.168.8.1/api"
  },{
      "path": "/cloud",
      "proxyUrl": "https://smart.blablablabla.com"
  }]
}

there is configured a proxy for cloud and this is the error in the browser:

POST http://localhost:8100/cloud/login 403 (Forbidden) polyfills.js:3

In the browser there is now CORS exception because there is not present the Access-Control-Allow-Origin header, and thats okay, this is working well by the proxy. But logging server and also consulting the server mantainer they have a CORS problem because the origin is present in the request, which should not be. Isn’t this the right way to handle this?

Is there an exception or is it working well? Decide…

Where do you see this in the browser? I only see a server returning a 403 because of a header it is not expecting or handling well. This is a valid choice by the backend, but has nothing to do with real CORS.

And why in your opinion the official blog is writing this?
What we need, then, is a request that does not specify an origin.

To be honest I don’t care what a 2 year old blog post is saying or what you think it says.

You have a problem, I help you debugging it. You say contradictory stuff and I call you out on it. If there is a exception, let us see it. If it is working well in the browser (No CORS error message), then the problem is not a CORS problem but a different one.

It may well be that CLI v2 didn’t have this Origin header and that maybe v3 shouldn’t have it either, but right now we are still in the “What the f**k is happening” stage where I need to get honest information from you.

My English is for sure not the best one, and If I wrote something confused it’s about my bad English and for that I’m sorry.

I’m grateful for your help but I think we should remain friendly and constructive, sorry for my English if you prefer we can continue the discussion also in German.

I will repeat the things i think are happening IMO:

  1. In the browser using proxy there is no CORS error but only an simple 403 error, because there is no blocking Access-Control-Allow-Origin header, so the proxy is doing well this work
  2. The REST resource we have to call as others do, control for the origin in the request, if there is no ORIGIN it’s okay if there is an wrong ORIGIN it’s not okay, and IMO the old proxy did remove the ORIGIN, I don’t know on which version, perhaps with version 3.0 the ORIGIN is not removed anymore and this is a problem for our app, as it could be and probably it is, a problem for others then us.

IMO
thx

Ok, that was the most important information.

[quote=“mburger81, post:13, topic:90450”]
2) The REST resource we have to call as others do, control for the origin in the request, if there is no ORIGIN it’s okay if there is an wrong ORIGIN it’s not okay, and[/quote]

Do you know exactly what the backend is checking and why?
Pseudocode: if(origin != bla.com) { return 403 } ?

The problem exists on ionic serve, while testing, not when you run the app on a device, correct?

You should downgrade the Ionic CLI and check - just npm uninstall -g ionic and then npm install -g ionic@2.2.3 should be enough, no change on the project necessary. Same but without a version to get back to current version later after testing.

  1. I don’t know exactly how the backend does the check for this behavior, but I can ask for it. We already discussed this with their dev team, and they told us they wan’t change this because this would be a “standard”

  2. Yes the problem is only using ionic serve, we sniffed what is happening, and in the call from the ionic serve environment over the proxy there is the header "Origin: http://localhost:8001" present also for the proxy call. And from device without --livereload there is no Origin header. That’s the difference, because it is working in one situation and in the other not. I thought on a version before this was working well and the origin is removed from the proxy, as described in the (yes I know) old post, but …

  3. I tested it with ionic@2.2.3 and also with ionic@2.0.0, there is the same error, but I don’t sniffed the http requests so I don’t know if the origin is there or not, If you wan’t I could also sniff it. Who is handling the proxy, the ionic-cli or app-scripts? I think the first one, right?

That would be great, because most APIs obviously don’t do whatever they are doing and think of “standard” - so understanding what exactly is happening helps.

That would be great, version 2.2.3 will be enough. Then we know if v3 is doing something different than v2 did.

Hi, I tested it and also discussed it to the team.

  1. On ionic@2.2.3 there is the same behavior, the ORIGIN header is always present so there is also a 403 error. Perhaps I read years ago the blog post and I fought always that your proxy is doing the same as IMO others do.

  2. We talked to the service dev team, and they was repeating me the same as before and the same as we know about server security. The CORS control in the browser which is working well with the proxy is only for a local security and only a part of the security. But there is still the CORS check on the SERVER, so they don’t do something like that "if(origin != bla.com)" but they only configure the server to check for CORS, and so if the origin are not the same origin as configured or NO origin the server sends a 403.
    And honestly this is the same thing we used here over years in java REST services and others.

I think something like this:
https://enable-cors.org/server_apache.html
https://enable-cors.org/server_nginx.html
(I know this are example DISABLE CORS, but this should only the ability to block requests on server, not only for browser requests)

And this IMO is a standard CORS check on the server side you can only avoid not sending ORIGIN. Or you use some tunnels or something like that.

If it is so, perhaps we can ask for a FR?

Edit: The proxy-middleware you are using has the possibility to set configure something like changeOrigin and also there is something like that

function onProxyReq(proxyReq, req, res) {
    // add custom header to request 
    proxyReq.setHeader('x-added', 'foobar');
    // or log the req 
}

Where you can probably remove the header.

Edit 2:
Okay sorry you probably use this middleware https://github.com/gonzalocasas/node-proxy-middleware

Ok, so this is not a CLI v2, v3 issue. That is great.

Then they configure to check for Origin headers and only reply to calls from expected Origins - this has nothing to do with “CORS”. It’s for a similar problem, but on the other side of the pipe.

This is exactly NOT what you are describing.

Again, show me something where this is described. I wasn’t really able to find anything online with a bit of Googling.

Just a note: I am not working for Ionic and not working on the CLI, just a community moderator here.[quote=“mburger81, post:17, topic:90450”]
If it is so, perhaps we can ask for a FR?
[/quote]

I don’t know what a “FR” is, but you can go to GitHub - ionic-team/ionic-cli: The Ionic command-line interface and open an issue where you ask for the Origin header to be removed from requests coming from the Proxy the CLI can create. Your argument would be that your backend doesn’t work if an Origin-Header is present that doesn’t match the expected value.

I wrote in my post:

(I know this are example DISABLE CORS, but this should only the ability to block requests on server, not only for browser requests)

So IMO o wrote this is THE APPOSITE we have, this is the possibility to disable CORS check.

IMO this for example is EXACTLY the thing

I really don’t know how do you can say the ORIGIN check on server is not CORS, sorry

but thx you anyway

Best regards

Because all of these add the Access-Control-Allow-Origin header to the responses of the server in one way or another. This makes CORS issues in clients go away. That easy.