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

Slack webclient communication through proxy fails to verify slack.com certificate even though rejectUnauthorized: false is used in webclient agent #2140

Open
romano-neosec opened this issue Jan 20, 2025 · 3 comments
Labels
needs info An issue that is claimed to be a bug and hasn't been reproduced, or otherwise needs more info pkg:web-api applies to `@slack/web-api`

Comments

@romano-neosec
Copy link

romano-neosec commented Jan 20, 2025

  1. I'm using below code for creating Slack web client on-demand in some typescript REST endpoint of some webservice. The client uses https agent for communicating with slack.com API via proxy (mitmproxy is used):
 private createProxyAwareSlackClient(token: any) {
    const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
    const slackClientOptions = { logLevel: LogLevel.DEBUG };

    if (proxyUrl) {
      slackClientOptions['agent'] =
        new URL(proxyUrl).protocol === 'http:' ? new HttpProxyAgent(proxyUrl, {rejectUnauthorized: false}) : new HttpsProxyAgent(proxyUrl, {rejectUnauthorized: false});
    }

    return new WebClient(token, slackClientOptions);
  }

  async firstHandshake(settings: any) {
    const slackWebClient = this.createProxyAwareSlackClient(undefined);
    let response: WebAPICallResult;
    try {
      response = await slackWebClient.oauth.v2.access({
        client_id: process.env.SLACK_CLIENT_ID,
        client_secret: process.env.SLACK_CLIENT_SECRET,
        code: settings.slack_code,
        redirect_uri: settings.redirect_uri
      });
    } catch (e) {
      logger.error(e);
      throw createError(500, 'Cannot get slack api key');
    }
  1. rejectUnauthorized: false is used while instantiating the agent to avoid validating of the slack.com certificate. Nevertheless, the certificate validation occurs and fails with below error in the client (rest endpoint source code):
[WARN]  web-api:WebClient:8 http request failed unable to verify the first certificate
[DEBUG]  web-api:WebClient:8 http request url: https://slack.com/api/oauth.v2.access
[DEBUG]  web-api:WebClient:8 http request body: {"client_id":"id","client_secret":"secret","code":"some_code","redirect_uri":"some_url"}
[DEBUG]  web-api:WebClient:8 http request headers: {}
[WARN]  web-api:WebClient:8 http request failed unable to verify the first certificate

and below error is seen in the mitmproxy logs:


[23:02:09.731][127.0.0.1:59940] client connect
[23:02:09.826][127.0.0.1:59940] server connect slack.com:443 (some_ip:443)
[23:02:09.911][127.0.0.1:59940] Client TLS handshake failed. The client disconnected during the handshake. If this happens consistently for slack.com, this may indicate that the client does not trust the proxy's certificate.
[23:02:09.913][127.0.0.1:59940] client disconnect
[23:02:09.914][127.0.0.1:59940] server disconnect slack.com:443 (some_ip:443)

It's important to note that:

HTTPS_PROXY env var is https://localhost:8080 (where mitmproxy listens)

How to skip slack.com certificate validation when slack webclient is accessing it via a proxy?

There's no issue and slack API is successfully accessed via the proxy without certificate validation if NODE_TLS_REJECT_UNAUTHORIZED=0 env var is present in the web service environment. However, it's a bad practice to disable certificate validation globally.

Packages:

Select all that apply:

  • [ x] @slack/web-api

Reproducible in:

The Slack SDK version

6.12.0

Node.js runtime version

v18.20.4

OS info

20.04.1-Ubuntu

Expected result:

slack.com certificate validation will be skipped.

Actual result:

[WARN] web-api:WebClient:8 http request failed unable to verify the first certificate

@WilliamBergamin
Copy link
Contributor

Hi @romano-neosec thanks for writing in 💯

From the source code it seems like the agent passed to the WebClient is immediately passed to the axios instance used by the WebClient 🤔

Is there a way for you to log the selected agent and the proxyUrl to make sure the correct ones are used?

Side note this might just be a typo, but your example is using new URL(proxyUrl).protocol === 'http:' the protocol value may need to be 'http'

@WilliamBergamin WilliamBergamin added needs info An issue that is claimed to be a bug and hasn't been reproduced, or otherwise needs more info pkg:web-api applies to `@slack/web-api` and removed untriaged labels Jan 20, 2025
@romano-neosec
Copy link
Author

romano-neosec commented Jan 22, 2025

@WilliamBergamin Thanks for your response.

I logged and debugged. The selected agent (HttpsProxyAgent) and the proxy url (https://localhost:8080) are correct.

Thanks for the side note. new URL(proxyUrl).protocol === 'http:' is actually the correct code.

http://example.com → protocol is 'http:'
https://example.com → protocol is 'https:'

@WilliamBergamin
Copy link
Contributor

  1. rejectUnauthorized: false is used while instantiating the agent to avoid validating of the slack.com certificate. Nevertheless, the certificate validation occurs and fails with below error in the client (rest endpoint source code)

Did some more digging it seems like this may be an issue in the HttpProxyAgent 🤔 This issue was opened and based on this comment it seems like you may need to implement the workaround to get rejectUnauthorized to work as expected

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs info An issue that is claimed to be a bug and hasn't been reproduced, or otherwise needs more info pkg:web-api applies to `@slack/web-api`
Projects
None yet
Development

No branches or pull requests

2 participants