Repository navigation
App installation failing with invalid browser on lambda, even with state set #366
Description
Activity
- addedquestionFurther information is requestedFurther information is requested
on Jun 6, 2021 Hi @Bhavya6187, thanks for asking the question!
The error indicates two possibilities:
- The installer didn't go through the OAuth flow from the install URL, which redirects users to Slack's authorize URL with state parameter
- The install URL didn't set cookie for the state value for some reason
In your case, the second one may be the reason as you observed the query string has valid
stateparameter.By default, the install URL has set-cookie response header like
set-cookie: slack-app-oauth-state=xxx-xxx-xxx-xxx-xxx; Secure; HttpOnly; Path=/; Max-Age=600. Check the browser developer tool to see how it's working with your app.A common cause of your situation is that the install URL does not start with
https://buthttp://. If so, the situation may arise as the set-cookie has theSecure;attribute. If that's not the case, check your AWS infra settings again.To learn how the part works, check the following source code:
- https://github.com/slackapi/bolt-python/blob/v1.6.1/slack_bolt/adapter/aws_lambda/lambda_s3_oauth_flow.py
- https://github.com/slackapi/bolt-python/blob/v1.6.1/slack_bolt/oauth/oauth_flow.py#L216-L227
- https://github.com/slackapi/python-slack-sdk/blob/v3.6.0/slack_sdk/oauth/state_utils/__init__.py#L38-L57
If you have some reason that you don't want to make the cookie validation functional, you can have your own
OAuthFlowthat inherits theLambdaS3OAuthFlowand overridesdef handle_callback(self, request: BoltRequest) -> BoltResponse:method to have only the parts necessary for you.Thanks for replying @seratch, these pointers were incredibly helpful. I did verify the https link in install url, and looked at the developer tools, and looks like the cookie values are set, but they are not matching. It is failing at this line - https://github.com/slackapi/python-slack-sdk/blob/v3.6.0/slack_sdk/oauth/state_utils/__init__.py#L55
When on /slack/install the value of cookie is -
slack-app-oauth-state=fb913dce-f7c7-49ad-8f4a-829a1b341e5fAfter the oauth flow the values are -
'state': '6ba9b705-99e1-4ab5-9b03-1eaa9de3b5db'
cookie - 'slack-app-oauth-state=fb913dce-f7c7-49ad-8f4a-829a1b341e5f'I can remove the cookie validation by extending LambdaS3OAuthFlow as a last resort, but was wondering what might be the reason behind mismatch of values here?
Hi @Bhavya6187, I'm not sure what the cause of your situation is yet.
I would recommend checking all the communications with a browser before the user redirection to
https://slack.com/oauth/v2/authorize?state={...}&client_id=111.222&scope={...}&user_scope={...}URL. Perhaps, thestateparameter in the redirection might not be different from the cookie value set by/slack/installpage response for some reason.@seratch Looks like the state value in the cookie and the state param in the redirect url generated are not the same. Looking at this line - https://github.com/slackapi/bolt-python/blob/main/slack_bolt/oauth/oauth_flow.py#L158 it looks like the state variable set in the cookie should be the same as the one in the url, but that does not look to be the case.
Any idea what might be missing here?
@Bhavya6187 As you see, the method is quite simple. As long as your app call the method only one time, your situation should not arise. Therefore, I'm guessing that your app may be repeating the state generation for some reason (e.g., redirecting users multiple times). I'm unable to tell anything further with given information.
To narrow the issue down, I would recommend deploying the example as-is first. Running the following script (after configuring required env variables) should work for you:
- https://github.com/slackapi/bolt-python/blob/v1.6.1/examples/aws_lambda/deploy_oauth.sh
- https://github.com/slackapi/bolt-python/blob/v1.6.1/examples/aws_lambda/aws_lambda_oauth_config.yaml#L27-L34
The example app handles everything (=
GET /slack/install,POST /slack/event, andGET /slack/oauth_redirect) with a single endpoint. The default path would behttps://{your public domain}/default/bolt_py_functionbut you can customize it by changing this part.Once you've confirmed the example works, identifying the issue that your app has can be easier.
@seratch You're right that is the issue. After "/slack/install", there is a second call being made to get 'favicon.ico', which ends up trigerring the path of /slack/install again, changing the cookie value. The routing happens at this line - https://github.com/slackapi/bolt-python/blob/v1.6.1/slack_bolt/adapter/aws_lambda/handler.py#L57
I was able to resolve it by adding
<link rel="icon" href="data:,">to the head section of the html here - https://github.com/slackapi/bolt-python/blob/v1.6.1/slack_bolt/oauth/internals.py#L76 which stops the browser from requesting it.Let me know if there's a more graceful solution than that. I'll close this issue in the meantime.
Thanks a lot for your pointers, they were really helpful.
Hi @Bhavya6187, thanks for sharing this and that makes sense!
I was able to resolve it by adding to the head section of the html here - https://github.com/slackapi/bolt-python/blob/v1.6.1/slack_bolt/oauth/internals.py#L76 which stops the browser from requesting it.
This looks good enough for avoiding the possible confusion. If you have time, would you mind sending a pull request to add the tag to the default template? I can work on it later, too.
(Filling out the following details about bugs will help us solve your issue sooner.)
The
slack_boltversionslack-bolt==1.6.1
slack-sdk==3.6.0
Python runtime version
Python 3.9.5
OS info
ProductName: macOS
ProductVersion: 11.4
BuildVersion: 20F71
Steps to reproduce:
I am following the lambda oauth example here and added some extra settings to help debug.
These are the url's I've made on API Gateway
Expected result:
Expected login to go through
Actual result:
Fails with output -
{'reason': 'invalid_browser', 'status_code': 400, 'error': None}
The problem in #248 seems to be related to state not set, however I can see both state and code set in this case. Am I missing something here?
Requirements
slack_sdk
slack-bolt
requests~=2.25.1