Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Origin header is always sent from WebSocket client #9673

Closed
ursaj opened this issue Oct 15, 2019 · 12 comments · Fixed by #9692 or #12941
Closed

Origin header is always sent from WebSocket client #9673

ursaj opened this issue Oct 15, 2019 · 12 comments · Fixed by #9692 or #12941
Milestone

Comments

@ursaj
Copy link
Contributor

ursaj commented Oct 15, 2019

Expected behavior

No 'Origin' header sent by default.
A way to set custom 'Origin' header when it is needed.

Actual behavior

'Origin' header is set.
'Origin' header is auto-resolved into meaningless value. In my case - IP of the intermediate proxy between client and server sides.
Enforced 'Origin' header leads to cors check failure on server side and denial of service for legitim client.

Steps to reproduce

Open WebSocket connection with v13 handshaker

WebSocketClientHandshaker13.newHandshakeRequest:

if (!headers.contains(HttpHeaderNames.ORIGIN)) {
    headers.set(HttpHeaderNames.ORIGIN, websocketOriginValue(wsURL));
}

Netty version

4.1.39

Related issues: PR #9312 and PR #9435.

JVM version (e.g. java -version)

1.8.0_223-b27

OS version (e.g. uname -a)

@amizurov
Copy link
Sponsor Contributor

Hi, @ursaj. I agree that Origin and Sec-WebSocket-Origin is not required according the spec https://tools.ietf.org/html/rfc6455#section-1.3 Origin/Sec-WebSocket-Origin header field is sent by browser clients; for non-browser clients, this header field may be sent if it makes sense in the context of those clients. But i'm not sure can we just delete them. WDYT @normanmaurer @slandelle

@slandelle
Copy link
Contributor

I agree there's no way for an HTTP client to be able to infer Origin header and it can only be provided reliably by the user. IMHO, this is a bug, but fixing it would be a breaking change.
I say we should have an option to disable and deprecate sending Origin header for removal in Netty 5.

@ursaj
Copy link
Contributor Author

ursaj commented Oct 17, 2019

Actually it is already a breaking change between 4.1.31 and 4.1.39 - when 'Origin' header was forcibly injected. I'd spend quite a lot of effort to sort it out, when Singapore clients failed to connect to our backends during their upgrade. For me it was 4 a.m. on Sunday - quite an inconvenient time to solve such issues.

I'll better interpret it like a "temporary bug" and revert this behaviour to the one of 4.1.31.

@normanmaurer
Copy link
Member

@slandelle I agree with @ursaj ... we should fix it. @ursaj can you do a pr ?

normanmaurer pushed a commit that referenced this issue Nov 27, 2019
### Motivation:

Those who need 'Origin' or 'Sec-WebSocket-Origin' headers should provide them explicitly, like it is stated in WebSocket specs.

E.g. through custom headers:

    HttpHeaders customHeaders = new DefaultHttpHeaders()
        .add(HttpHeaderNames.ORIGIN, "http://localhost:8080");
    new WebSocketClientProtocolHandler(
        new URI("ws://localhost:1234/test"), WebSocketVersion.V13, subprotocol, 
        allowExtensions, customHeaders, maxFramePayloadLength, handshakeTimeoutMillis)


### Modification:

* Remove enforced origin headers.
* Update tests

### Result:

Fixes #9673: Origin header is always sent from WebSocket client
normanmaurer pushed a commit that referenced this issue Nov 27, 2019
Those who need 'Origin' or 'Sec-WebSocket-Origin' headers should provide them explicitly, like it is stated in WebSocket specs.

E.g. through custom headers:

    HttpHeaders customHeaders = new DefaultHttpHeaders()
        .add(HttpHeaderNames.ORIGIN, "http://localhost:8080");
    new WebSocketClientProtocolHandler(
        new URI("ws://localhost:1234/test"), WebSocketVersion.V13, subprotocol,
        allowExtensions, customHeaders, maxFramePayloadLength, handshakeTimeoutMillis)

* Remove enforced origin headers.
* Update tests

Fixes #9673: Origin header is always sent from WebSocket client
@normanmaurer normanmaurer added this to the 4.1.44.Final milestone Nov 27, 2019
@normanmaurer
Copy link
Member

normanmaurer commented Dec 18, 2019

Sorry but I have to revert this as this needs more thoughts.

@normanmaurer normanmaurer reopened this Dec 18, 2019
normanmaurer added a commit that referenced this issue Dec 18, 2019
…ent (#9692)"

This reverts commit f48d9fa as this needs more thoughts.
normanmaurer added a commit that referenced this issue Dec 18, 2019
…ent (#9692)"

This reverts commit f48d9fa as it needs more thoughts
@tmsimont
Copy link

Out of curiosity, what motivated the revert for this? I see "more thoughts" are cited but why? To me it seemed like the argument in this commit message was pretty compelling 19a4633

For context, I ran into this bug when performing a minor upgrade, too.

@tmsimont
Copy link

This feels more wrong the more I look into it.

The current state, in which the bug fix is reverted, sets the Origin header to the target webSocketURL

That is flat out wrong.

HTTP Origin
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin

The Origin request header indicates where a fetch originates from

webSocketURL

URL for web socket communications. e.g "ws://myhost.com/mypath".
Subsequent web socket frames will be sent to this URL.

It seems that the bug was introduced to hack in a fix for CORS requests. The hack was a breaking change that truly makes no sense. If a user wants to spoof the origin by setting it to the target URL, then there's an API in place to do this.

Why would you break the library by making this the default behavior?

@ursaj
Copy link
Contributor Author

ursaj commented Jul 17, 2020

I agree with @tmsimont .Reasoning like "this needs more thoughts" feels really disappointing. To such extend that I've just lost my passion to discuss or contribute anything.

Adding something or removing something to project is ok. Even if its buggy. But double standards in change management feel disrespectful to contributors.

Just a thought.

@normanmaurer
Copy link
Member

normanmaurer commented Jul 17, 2020 via email

@tmsimont
Copy link

Since everyone is busy allow me to review the history here...

It looks like this Origin header has had a rough history:

so to review...

  • Origin used to be missing from v13 handshaker and has a bumpy history in v0
  • Origin and Sec-WebSocket-Origin have always been set to the "Target" which is wrong...
  • Origin is now set incorrectly in v13, too, in addition to v0 but is not set in v7 nor v8
  • We can now at least set Origin into custom headers that won't be overridden which is nice
  • Users that depend on a value in Origin probably are not setting it explicitly and allowing the default behavior, which is backwards.

I'm totally lost as to why it was ever thought to be correct to set Origin = targetUrl

Can anyone explain that one?

ihanyong pushed a commit to ihanyong/netty that referenced this issue Jul 31, 2020
…t client (netty#9692)"

This reverts commit f48d9fa as it needs more thoughts
@vietj
Copy link
Contributor

vietj commented Oct 6, 2021

I believe there should be an option to disable sending the origin header by the handshaker.

Currently it is possible to work around this by subclassing handshaker classes and override the newHandshakeRequest request to clean up the request header.

@amizurov
Copy link
Sponsor Contributor

amizurov commented Oct 6, 2021

I think we can just remove ORIGIN and provide utility method HttpUtil.websocketOriginValue() for setting it via custom headers if it needed. The most of part was done in #9692. I believe we can close this problem for 4.1.* @normanmaurer WDYT ?

chrisvest pushed a commit that referenced this issue Apr 21, 2022
…2293)

Motivation:

In Netty 5 we only left the latest 13 version of websocket, so we can clean up the code a bit.

Modification:

- Remove `origin` header from handshake request, it can be set with `customHeaders`, see #9673
- Calculate expected value of `sec-websocket-accept` only when we received a response
- Remove unused code
- Add more tests for clientHandshaker13

Result:
Removed not used code and fixed wrong behaviour with origin header #9673.
normanmaurer added a commit that referenced this issue Nov 10, 2022
…est (#12941)

Motivation:

We have the old erroneous behavior of generating the `Origin| Sec-WebSocket-Origin` for client websocket handshake request (#9673). In Netty5 this fixed and auto-generation has been deleted at all, only if the client passed the `Origin` header via custom headers. The same we can do for Netty4 but it could potentially break some clients (unlikely), or introduce an additional parameter to disable or enable this behavior.

Modification:

Introduce new `generateOriginHeader` parameter in client config and generate the `Origin|Sec-WebSocket-Origin` header value only if it enabled. Add additional check for webSocketURI if it contains host or passed through `customHeaders` to prevent NPE in `newHandshakeRequest()`.

Result:

Fixes #9673 #12933 


Co-authored-by: Norman Maurer <norman_maurer@apple.com>
normanmaurer added a commit that referenced this issue Nov 10, 2022
…est (#12941)

Motivation:

We have the old erroneous behavior of generating the `Origin| Sec-WebSocket-Origin` for client websocket handshake request (#9673). In Netty5 this fixed and auto-generation has been deleted at all, only if the client passed the `Origin` header via custom headers. The same we can do for Netty4 but it could potentially break some clients (unlikely), or introduce an additional parameter to disable or enable this behavior.

Modification:

Introduce new `generateOriginHeader` parameter in client config and generate the `Origin|Sec-WebSocket-Origin` header value only if it enabled. Add additional check for webSocketURI if it contains host or passed through `customHeaders` to prevent NPE in `newHandshakeRequest()`.

Result:

Fixes #9673 #12933

Co-authored-by: Norman Maurer <norman_maurer@apple.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants