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

Websocket Key Mismatch #483

Open
SteveSelva opened this issue Feb 6, 2024 · 2 comments
Open

Websocket Key Mismatch #483

SteveSelva opened this issue Feb 6, 2024 · 2 comments

Comments

@SteveSelva
Copy link

In Downstream, in HTTP1xCodec.cpp file, the websockAccept is generated from the websockAcceptKey sent from the Browser.

But in Upstream, an error message is thrown and the connection is terminated:

E20240206 16:59:09.517776 16080 HTTP1xCodec.cpp:1155] Mismatch in expected ws accept key: upstream: i3nI98Wx41+xdf2LZ91PdtmsuZ8= expected: 
E20240206 16:59:09.517776 16080 ProxyHandler.cpp:267] onServerError():what="Error parsing message: the on_headers_complete callback failed", direction=0, proxygenError=ParseHeader, codecStatusCode=-1, httpStatusCode=0

I think the expected Accept value for Websocket is not sent from Downstream to Upstream, so the expected value(proxygen::HTTP1xCodec::websockAcceptKey_) is empty in the error log message.

Proxygen.v2023.10.30
HTTP1xCodec.cpp LineNo.1147

  const std::string& upgrade = hdrs.getSingleOrEmpty(HTTP_HEADER_UPGRADE);
  if (kUpgradeToken.equals(upgrade, folly::AsciiCaseInsensitive())) {
    msg_->setIngressWebsocketUpgrade();
    if (transportDirection_ == TransportDirection::UPSTREAM) {
      // response.
      const std::string& accept =
          hdrs.getSingleOrEmpty(HTTP_HEADER_SEC_WEBSOCKET_ACCEPT);
      if (accept != websockAcceptKey_) {
        LOG(ERROR) << "Mismatch in expected ws accept key: "
                   << "upstream: " << accept
                   << " expected: " << websockAcceptKey_;
        return -1;
      }
    } else {
      // request.
      // If the websockAcceptKey is already set, we error out.
      // Currently, websockAcceptKey is never cleared, which means
      // that only one Websocket upgrade attempt can be made on the
      // connection. If that upgrade request is not successful for any
      // reason, the connection is no longer usable. At some point, we
      // may want to change this to clear the websockAcceptKey if
      // the request doesn't succeed keeping the connection usable.
      if (!websockAcceptKey_.empty()) {
        LOG(ERROR) << "ws accept key already set: '" << websockAcceptKey_
                   << "'";
        return -1;
      }
      auto key = hdrs.getSingleOrEmpty(HTTP_HEADER_SEC_WEBSOCKET_KEY);
      websockAcceptKey_ = generateWebsocketAccept(key);
    }
  }

How to fix this issue?

@SteveSelva
Copy link
Author

I am using Proxygen as a MITM proxy server. While establishing a WebSocket connection from downstream to upstream, this error occurred. Here, the websocketAcceptKey is stored in downstream from the WebSocket Request. While forwarding the WebSocket Request to upstream, it didn't copy the key and didn't generate the websocketAcceptKey, but its checking whether the websocketAcceptKey is matching the key received from the upstream, which results in this error.

Does Proxygen supports WebSocket over Proxy Communication or the implementation is wrong?

@SteveSelva
Copy link
Author

@afrind @jbeshay Can you help with this issue pls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant