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

BotBuilder, as a library, should not pin 3rd party dependencies #1467

Closed
cognifloyd opened this issue Jan 14, 2021 · 12 comments · Fixed by #1561
Closed

BotBuilder, as a library, should not pin 3rd party dependencies #1467

cognifloyd opened this issue Jan 14, 2021 · 12 comments · Fixed by #1561
Assignees
Labels
backlog The issue is out of scope for the current iteration but it will be evaluated in a future release. Bot Services Required for internal Azure reporting. Do not delete. Do not change color. bug Indicates an unexpected problem or an unintended behavior. customer-replied-to Indicates that the team has replied to the issue reported by the customer. Do not delete. customer-reported Issue is created by anyone that is not a collaborator in the repository. needs-triage The issue has just been created and it has not been reviewed by the team.

Comments

@cognifloyd
Copy link

cognifloyd commented Jan 14, 2021

Version

4.11.0

Describe the bug

I'm trying to add BotBuilder to an app that already has ibm-watson as a dependency.
The conflict is due to botbuilder-core pinning a very old version of PyJWT.
ibm-watson needs ibm-cloud-sdk-core which needs PyJWT. ibm-cloud-sdk-core uses a range of versions, specifying PyJWT>=2.0.0a1,<3.0.0 in the last few versions, but for all older versions, it required PyJWT>=1.7.1.

BotBuilder is a library meant to be embedded in other applications, so pinning 3rd party deps is dangerous.
Looking through the dependencies in the various botbuilder libraries, it looks like several have dependencies that are pinned instead of specifying a range of valid versions. For the microsoft-provided deps, pinning makes perfect sense. For 3rd party deps, please do not pin the dep version (instead specify a range) and allow the application that is using the botbuilder framework to pin its own deps

To Reproduce

Steps to reproduce the behavior:

  1. pip install --upgrade pip (in a virtualenv) to use the new resolver that refuses to install conflicting dependencies
  2. pip install ibm-watson botbuilder-core==4.11.0
  3. pip backtracks for awhile until it gets to some very old versions of ibm-watson that it can't process and dies.
  4. even if pip could process the old versions, no version of the ibm lib ever supported version 1.5.3 of PyJWT that was released in 2018.

Expected behavior

For microsoft/azure libraries, go ahead and pin the deps. The botbuilder itself is versioned together, so pinning makes perfect sense.

If you want to pin the version 3rd party deps in requirements.txt, that also is fine so that you can say "This is the most tested/supported version". But please, in setup.py, specify a range of valid versions for 3rd party deps to ease integrating BotBuilder in existing applications.

Additional context

Here are the 3rd party dependency lines in setup.py that pin 3rd party deps in 4.11.0 (the deps are still pinned in main/4.12.0):

PyJWT, requests, cryptography

very common packages, likely to cause conflicts. Caused a conflict for me

"requests==2.23.0",
"cryptography==2.8.0",
"PyJWT==1.5.3",

aiohttp

very common package, likely to cause conflicts




Unpinning aiohttp in botbuilder-aialso requires bumping the required version of aioresponses to at least 0.7.1 to get this fix pnuckowski/aioresponses#174 (adds support for aiohttp 3.7+):

babel

common package, likely to cause conflicts

jsonpickle

less common package, so I'm not as concerned.


@cognifloyd cognifloyd added bug Indicates an unexpected problem or an unintended behavior. needs-triage The issue has just been created and it has not been reviewed by the team. labels Jan 14, 2021
@cognifloyd
Copy link
Author

Why is cryptography listed in the deps for botframework-connector? It is not imported anywhere by botframework-connector. And, these deps specify their own dependencies:

  • adal==1.2.1 requires cryptography>=1.1.0
  • msal==1.6.0 requires cryptography>=0.6,<4
  • PyJWT>=1.5.3,<2.0.0 requires cryptography>=1.4.0,<4.0.0 (newer versions bump the min, but not the max)
  • requests>=2.23.0,<3.0.0 requires cryptography>=1.3.4

I think cryptography should be removed from the requirements of botframework-connector.

cognifloyd added a commit to cognifloyd/botbuilder-python that referenced this issue Jan 14, 2021
Allow apps that embed the BotBuilder Framework to use newer deps if they need it.

Looking at changelogs, these version ranges should be safe:
- PyJWT has backwards incompatible changes in 2.0.0. so `~=1.5.3` (ie `>=1.5.3,<2.0.0`)
- requests has no major changes between 2.23.0 and 2.25.1 (by reading the code changes).
  As requests has had breaking changes in minor releases before, cap it at `<2.6`

Drop cryptography, as this library does not use it directly.
These dependencies do use it, so let them specify their acceptable versions:
- `adal==1.2.1` requires `cryptography>=1.1.0`
- `msal==1.6.0` requires `cryptography>=0.6,<4`
- `PyJWT>=1.5.3,<2.0.0` requires `cryptography>=1.4.0,<4.0.0` (newer versions bump the min, but not the max)
- `requests>=2.23.0,<3.0.0` requires `cryptography>=1.3.4`

Bug: microsoft#1467
cognifloyd added a commit to cognifloyd/botbuilder-python that referenced this issue Jan 15, 2021
Allow apps that embed the BotBuilder Framework to use newer deps if they need it.

Looking at changelogs, these version ranges should be safe:
- PyJWT has backwards incompatible changes in 2.0.0. so `>=1.5.3,<2.0.0`
- requests has no major changes between 2.23.0 and 2.25.1 (by reading the code changes).
  As requests has had breaking changes in minor releases before, cap it at `<2.6`

Drop cryptography, as this library does not use it directly.
These dependencies do use it, so let them specify their acceptable versions:
- `adal==1.2.1` requires `cryptography>=1.1.0`
- `msal==1.6.0` requires `cryptography>=0.6,<4`
- `PyJWT>=1.5.3,<2.0.0` requires `cryptography>=1.4.0,<4.0.0` (newer versions bump the min, but not the max)
- `requests>=2.23.0,<3.0.0` requires `cryptography>=1.3.4`

Bug: microsoft#1467
cognifloyd added a commit to cognifloyd/botbuilder-python that referenced this issue Jan 15, 2021
Allow apps that embed the BotBuilder Framework to use newer deps if they need it.

Looking at changelog, current versions of aiohttp (3.7.*) should also be
fairly compatible with 3.6.*, so allow aiohttp>=3.6.2,<3.8.0

Bug: microsoft#1467
cognifloyd added a commit to cognifloyd/botbuilder-python that referenced this issue Jan 15, 2021
`jsonpickle` added python 3.8 support in 1.4, so allow `jsonpickle>=1.2,<1.5`

Bug: microsoft#1467
@ghost
Copy link

ghost commented Jan 15, 2021

You beat me to creating an issue about this. I am facing the same hurdle, my application uses latest pyjwt 2.0 whilst botframework uses the rather ancient 1.5.3.

@tracyboehrer tracyboehrer added Bot Services Required for internal Azure reporting. Do not delete. Do not change color. customer-reported Issue is created by anyone that is not a collaborator in the repository. labels Jan 15, 2021
@cognifloyd
Copy link
Author

cognifloyd commented Jan 15, 2021

@sferdi0 Can you check out where botframework-connector is using PyJWT to see what it would take to upgrade to 2.0? It is safe to upgrade to <2.0 without code changes (based on reading the changelog), but several things changed in 2.0.

@ghost
Copy link

ghost commented Jan 18, 2021

@cognifloyd I can't validate incoming messages for my Bot, e.g: my route is /api/messages and Microsoft sends me, for example, a conversationUpdate (when an user adds my app/bot to their Teams) - and this code tries to validate the incoming request using it's Authorization header:

In the new(er) PyJWT 2.0 that should be this instead:

token = jwt.decode(token, options={"verify_signature": False})

There are more places where JWT is used throughout the code but I don't think a migration would be complicated at all.

@cognifloyd
Copy link
Author

OK. I tested with the following dependency updates and all tests pass without any code changes.

requests, crptography, PyJWT

Note that this drops the explicit cryptography requirement, as botframework-connector does not use it directly.

-    "requests==2.23.0",
+    "requests>=2.23.0,<2.26",
-    "cryptography==3.2",
-    "PyJWT==1.5.3",
+    "PyJWT>=1.5.3,<2.0.0",

aiohttp

-    "aiohttp==3.6.2",
+    "aiohttp>=3.6.2,<3.8.0",

aioresponses

-aioresponses==0.6.3
+aioresponses>=0.7.1

jsonpickle

-    "jsonpickle==1.2",
+    "jsonpickle>=1.2,<1.5",

babel

I didn't test updating babel.

@cognifloyd
Copy link
Author

At a glance, bumping to PyJWT 2.0 will also require bumping msal and possibly others, as that also requires <2.0.

I would be okay with any updated PyJWT requirement (whether or not that includes v2.0) as long as it allows installing PyJWT>=1.7.1.

Please and thank you!

@cognifloyd
Copy link
Author

Also, if anyone else can submit a PR, that would be awesome. Sorry, I'm unable to contribute a PR myself, but I hope I've left enough breadcrumbs for others to get this updated.

@axelsrz
Copy link
Member

axelsrz commented Jan 20, 2021

Hello @cognifloyd thanks for bringing this up to our attention. We have decided in the past for a pinning strategy due to breaking changes by dependency updates appearing on our daily/PR builds.
With the arguments and situation presented in this thread we're considering to move to a "version range" policy, but we would have to draft a process for continuous development.

We will be updating this thread with any decisions taken in the following weeks, with solutions potentially similar to the one you proposed.

Let us know if you have further comments.

@axelsrz axelsrz added the customer-replied-to Indicates that the team has replied to the issue reported by the customer. Do not delete. label Jan 20, 2021
@srinaath srinaath added the backlog The issue is out of scope for the current iteration but it will be evaluated in a future release. label Feb 2, 2021
@compulim
Copy link

I think even though we move forward on the "version range" policy. After every release of the SDK, we should bump every dependencies to their latest version.

It's good for hygiene, progression on technical debts, and reducing chances of vulnerabilities.

@axelsrz could you bring this up in R13 planning?

@davidfishlock
Copy link

davidfishlock commented Mar 5, 2021

Is there any progress on this? I'm also running into this with the requests library.

If an exploit was to be found in requests then all applications using this SDK are required to remain vulnerable until botbuilder update their pinned dependency. Requests is currently pinned to a version from over a year ago.

All other SDKs that are used by applications that also declare this dependency are also being forced into specifiying a low range by this library.

If the policy is to continue pinning, then the dependencies must be tested and frequently updated as a priority. But I've not experienced an instance of requests making a breaking change without incrementing the major version, I don't really see a justification for pinning it to a minor.

@carlosscastro
Copy link
Member

Thanks for all the work and investigation, @cognifloyd and other contributors here, it's fantastic to receive such detailed feedback.

@cas--
Copy link

cas-- commented Apr 5, 2021

Why is cryptography listed in the deps for botframework-connector? It is not imported anywhere by botframework-connector. And, these deps specify their own dependencies:

* `adal==1.2.1` requires `cryptography>=1.1.0`

* `msal==1.6.0` requires `cryptography>=0.6,<4`

* `PyJWT>=1.5.3,<2.0.0` requires `cryptography>=1.4.0,<4.0.0` (newer versions bump the min, but not the max)

* `requests>=2.23.0,<3.0.0` requires `cryptography>=1.3.4`

I think cryptography should be removed from the requirements of botframework-connector.

I'm sure adal should also be removed as it is unused: #1620

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog The issue is out of scope for the current iteration but it will be evaluated in a future release. Bot Services Required for internal Azure reporting. Do not delete. Do not change color. bug Indicates an unexpected problem or an unintended behavior. customer-replied-to Indicates that the team has replied to the issue reported by the customer. Do not delete. customer-reported Issue is created by anyone that is not a collaborator in the repository. needs-triage The issue has just been created and it has not been reviewed by the team.
Projects
None yet
8 participants