oracle / node-oracledb

Oracle Database driver for Node.js maintained by Oracle Corp.
http://oracle.github.io/node-oracledb/
Other
2.25k stars 1.07k forks source link

v6: Behavior Change in Oracle Client Library Loading on Windows without initOracleClient() #1620

Closed bchr02 closed 11 months ago

bchr02 commented 11 months ago
  1. What versions are you using? v6.2

  2. Is it an error or a hang or a crash? Unexpected behavior after updating to v6.2 from a prior version.

  3. What error(s) or behavior you are seeing?

In versions before oracledb v6, the library would automatically search the PATH for the Oracle Client library on Windows, even without explicitly invoking initOracleClient(). However, in v6.2 this behavior seems to have changed. Now, as per the official documentation, it is mandatory to call initOracleClient() to search the PATH.

This change was particularly noticeable in our setup, as we enforce encryption, and the THIN mode would not work. While I understand this might be the intended behavior in the latest version, it seems counterintuitive not to leverage available client libraries, especially if they are present in the system. I'd suggest reconsidering this behavior, so upgrading to v6 is more plug-and-play and so users don't unintendedly move to THIN mode without knowing.

  1. Include a runnable Node.js script that shows the problem.

n/a

amaanansari26 commented 11 months ago

I recently upgraded from 5.5.0 to 6.2.0 and experienced the same issue.

sharadraju commented 11 months ago

Hello, Thanks for using node-oracledb. initOracleClient is now mandatory to enable the Thick mode, not to set the search path for the Oracle Client libraries. You can simply call initOracleClient() without passing in any parameters and the library would still automatically be searched.

bchr02 commented 11 months ago

Hi @sharadraju thanks for the reply and clarification. What is the logic for requiring a call to initOracleClient() when all past versions did not require this and when THIN mode does not fully support all the features of THICK mode? Why not revert to THIN mode only when the Oracle Client Libraries are not found?

sharadraju commented 11 months ago

@bchr02 We had plenty of discussions about this model when we created python-oracledb Thin mode last year (and node-oracledb Thin mode this year). The model seems simplest and fits with our direction to make Thin the dominant and default mode. We were careful to allow initOracleClient to be called speculatively with different library paths, allowing apps to try various paths until a set of client libraries is successfully loaded. Although we have a long way to go with Thin mode, the earlier this kind of API change is done in a product lifetime, the lesser the overall pain is felt.

We would be happy to do a Zoom call and catch up with you, if you like.

bchr02 commented 11 months ago

I am definitely a supporter of Thin mode however until it has feature alignment (or at least the features that Oracle wants to support going forward), having it as the default doesn't make sense to me 1) especially when prior to v6 the default was to search for the Client Libraries, regardless of whether initOracleClient was called, 2) you could easily revert to Thin mode if no libraries were found, 3) and lastly you could have added a mechanism to explicitly opt into Thin mode. You are needlessly breaking people's implementations for no reason. With the strategy I mentioned this would allow people to migrate to Thin mode simply by explicitly opting in or just stopping to bundle the client libraries. And then once Thin mode has feature alignment you could make it the default.

cjbj commented 11 months ago

@bchr02 I prefer the clean separation of thin vs thick mode via an explicit call, and it makes sense for us to use the existing initOracleClient() method to do the extra work loading libraries. The best out-of-box experience for users is for the driver to use Thin mode by default, and for it to not silently load client libraries, since this may cause behavior changes and confusion if an app is distributed to multiple client environments. Any library or package that releases a new major release is bound to have some kind of change that might need application changes. For node-oracledb the addition of a single initOracleClient() call is all that is needed to keep using Thick mode.

abrar-khan007 commented 11 months ago

It seems that there is a behavior change in the Oracle Client library loading on Windows without explicitly calling initOracleClient() in version 6.2 of the library. Previously, the library would automatically search the PATH for the Oracle Client library, but now it is mandatory to call initOracleClient() to perform the search.

This change has caused issues for users who have upgraded to version 6.2, especially for those who enforce encryption and rely on the THICK mode. The THIN mode does not fully support all the features of THICK mode.

Explained that the intention behind this change is to make the THIN mode the default and dominant mode. Suggest calling initOracleClient() without passing any parameters to automatically search for the client libraries.

However, the other suggestion that it would make more sense to revert to THIN mode only when the Oracle Client Libraries are not found, and to provide an explicit mechanism to opt into THIN mode.

The preference for the clean separation of thin vs thick mode via an explicit call to initOracleClient(). Believe that the best out-of-box experience for users is to use Thin mode by default and to not silently load client libraries, as this may cause behavior changes and confusion in different client environments.

A single initOracleClient() call is sufficient to continue using Thick mode.

cjbj commented 11 months ago

I'm a bit confused here. Are these apps that are never going to be altered? If so, why was the app stack upgraded? But if they are being maintained, then why is the need to add one line calling initOracleClient() a problem?

I've fought hard to keep node-oracledb simple, and anything being suggested here goes against that.

bchr02 commented 11 months ago

why was the app stack upgraded?

As far as I know Oracle is not maintaining v5.5, so if we want to keep up with the latest security releases, we have to periodically upgrade.

why is the need to add one line calling initOracleClient() a problem?

It's not a problem.

I've fought hard to keep node-oracledb simple

It has not gone unnoticed and we greatly value everything that you and the team have done and are doing.

bchr02 commented 11 months ago

I've fought hard to keep node-oracledb simple, and anything being suggested here goes against that.

What I propose is adding something like oracledb.thinConnection(dbConfig); and documenting this as the DeFacto to use with mention that the alternative getConnection is still available and will first search for Client Libraries and if none are found only then default to thin mode. By doing this, node-oracledb will still remain simple, while at the same time create less friction to those supporting existing projects (and will potentially be less risky from a liability standpoint since thin mode doesn't support encryption😉).

anthony-tuininga commented 11 months ago

In a time when information security is of the upmost importance, why is the default mode one that does not yet support encryption?

This is not true. It is indeed true that Oracle specific encryption (NNE) is not supported, but thin mode does support TLS, an industry standard for encrypted connections. I realize that swapping to use TLS may not be feasible, or even possible in some instances, though.

But what if encryption was optional in a given environment to support an isolated use case or whatever the reason may be. Meanwhile a developer upgrades an application as part of their maintenance not realizing that thin mode does not support encryption. Would this not then start to send all the database traffic over the wire unencrypted?

If the server states that Oracle specific encryption is mandatory, an error will take place when attempting to connect to that database. If the server states that encryption is optional, then yes, an unencrypted connection will be established -- so if encryption is important, ensure that the server mandates it.

you are forcing users to add initOracleClient() and then eventually remove it once feature parity exists.

Is that truly such an onerous task? The vast majority of applications will never need to add it in the first place. Those making use of certain features (as documented here) will indeed need to add a call to initOracleClient() if they didn't already have one. They can remove it again later if the feature they required has been added to thin mode. I don't see this being too difficult or cumbersome.

you could add something like oracledb.estConnection(dbConfig); that would take the place of oracledb.getConnection(dbConfig); and work in thin mode and then document this as the default to use. This would allow for better backwards compatibility and less friction with those developers that have been using oracledb for years.

We could do that, but that would make the interface more complex! I realize that your use case is important to you, but we do have to consider other use cases, too! As mentioned, most use cases are well supported in thin mode, installation is considerably simpler and swapping to thick mode is not difficult if that proves necessary. This was all well documented in the release notes and the upgrade guide.

Your feedback is appreciated. It is definitely understood that this was a potential issue for some users. This is why it was introduced in a major version (6.0.0) and was highlighted as the first item in the release notes! At this point I don't think your suggestions would help, however, as many have already taken advantage of the new thin mode -- and would heartily object to your suggestions! It is unfortunate that you didn't notice this change during development and object to it then -- although even then I don't think it would have changed our minds. We considered this for a long time and believe this is the best approach long-term. The solution in your case is quite simple: simply add a call to oracledb.initOracleClient() prior to establishing your first connection -- a simple enough task, I think!

cjbj commented 11 months ago

As far as I know Oracle is not maintaining v5.5, so if we want to keep up with the latest security releases, we have to periodically upgrade.

We have always encouraged upgrading to new versions; and I don't recall a time we have had to put out a patch for an older version. However considering the jump to 6, if there is a major (e.g. security) issue with 5.5, and we were asked with a good business case (such as "I can't upgrade"), we would put out a patch. Note that in 5.5 (and 6's Thick mode) most of the heavy lifting is done by Oracle Client and this has regular RU releases.

Regarding NNE vs TLS, our security group is encouraging moving to TLS. As @anthony-tuininga noted, Thin mode supports TLS / mTLS just like Thick mode does.

bchr02 commented 11 months ago

For the applications internally we will most definitely look at migrating to One-Way TLS.

For the external application though it is dependent upon the customer's Oracle database so I cannot ask the customer to support a new protocol and I know for a fact some are still on Oracle 11g unfortunately.

At the end of the day, if you feel most of your customers are not using NNE, then I suppose this will not be a big issue.

Thanks for getting back to me @cjbj, @anthony-tuininga, @sharadraju.

sosoba commented 11 months ago

@cjbj @anthony-tuininga

Regarding NNE vs TLS, our security group is encouraging moving to TLS.

I think the problem is that these recommendations are not strongly emphasized. Once you use the official documentation: 18.1.4 Choosing Between Native Network Encryption and Transport Layer Security you will learn that NNE is actually a better choice.

I know it's easier said than done, but the company's information policy should be consistent.

jvisker commented 10 months ago

Yeah. I would really love to be able to point to an official document/policy that encourages one way over the other. That would potentially give more weight to switching to TLS over NNE instead of it just being because of developer preference.

bchr02 commented 10 months ago

The biggest pain point to moving to TLS is the need to manage certificate renewals and installation. It's too bad that Oracle doesn't offer some sort of TLS termination application that can be installed next to a Windows or Linux Server running Oracle database. The app could use Let's Encrypt SSL certificate provisioning via a DNS challenge (to an Oracle owned domain) to issue certificates and then install them in the Oracle wallet. This could be a service that you offer free of charge to your clients who have an active Oracle Support Subscription. Thoughts? ping: @cjbj @anthony-tuininga @sharadraju

sharadraju commented 8 months ago

The biggest pain point to moving to TLS is the need to manage certificate renewals and installation. It's too bad that Oracle doesn't offer some sort of TLS termination application that can be installed next to a Windows or Linux Server running Oracle database. The app could use Let's Encrypt SSL certificate provisioning via a DNS challenge (to an Oracle owned domain) to issue certificates and then install them in the Oracle wallet. This could be a service that you offer free of charge to your clients who have an active Oracle Support Subscription. Thoughts? ping: @cjbj @anthony-tuininga @sharadraju

Hi @bchr02 Happy New Year and apologies for getting back late on this. I have taken your suggestion to the higher management and will let you know of any updates on this.

bchr02 commented 8 months ago

Glad to hear that. Thank you.