snowflake-connector-python icon indicating copy to clipboard operation
snowflake-connector-python copied to clipboard

SNOW-342547: OSCP validation updates the OSCP cache when not needed

Open shahargl opened this issue 4 years ago • 3 comments

Please answer these questions before submitting your issue. Thanks!

  1. What version of Python are you using (python --version)? Python 3.7.3 (default, Apr 24 2020, 18:51:23)

  2. What operating system and processor architecture are you using (python -c 'import platform; print(platform.platform())')? Darwin-19.5.0-x86_64-i386-64bit

  3. What are the component versions in the environment (pip freeze)?

alembic==1.5.5
appnope==0.1.2
asn1crypto==1.4.0
atlassian-python-api==3.8.0
attrs==20.3.0
azure-common==1.1.26
azure-core==1.11.0
azure-storage-blob==12.7.1
backcall==0.2.0
boto3==1.17.15
botocore==1.20.15
cachetools==4.2.1
certifi==2020.12.5
cffi==1.14.5
chardet==3.0.4
click==7.1.2
clickclick==20.10.2
connexion==2.7.0
cryptography==3.2.1
curlify==2.2.1
decorator==4.4.2
Deprecated==1.2.12
Flask==1.1.1
Flask-Cors==3.0.10
Flask-Testing==0.8.0
google-api-core==1.22.0
google-api-python-client==1.9.3
google-auth==1.27.0
google-auth-httplib2==0.0.4
google-cloud-core==1.6.0
google-cloud-kms==1.4.0
google-cloud-pubsub==2.4.0
google-cloud-scheduler==2.1.0
google-cloud-secret-manager==1.0.0
google-cloud-storage==1.29.0
google-cloud-tasks==1.5.0
google-resumable-media==0.5.1
googleapis-common-protos==1.52.0
graphql-core==3.1.3
grpc-google-iam-v1==0.12.3
grpcio==1.35.0
gunicorn==20.0.4
httplib2==0.19.0
hypothesis==5.49.0
hypothesis-graphql==0.3.3
hypothesis-jsonschema==0.19.0
idna==2.8
importlib-metadata==1.7.0
inflection==0.5.1
iniconfig==1.1.1
ipython==7.21.0
ipython-genutils==0.2.0
isodate==0.6.0
itsdangerous==1.1.0
jedi==0.18.0
Jinja2==2.11.3
jmespath==0.10.0
jsonpatch==1.28
jsonpointer==2.0
jsonschema==3.2.0
junit-xml==1.9
jwcrypto==0.8
keyring==22.0.1
libcst==0.3.17
Mako==1.1.4
marisa-trie==0.7.5
MarkupSafe==1.1.1
msrest==0.6.21
multidict==5.1.0
mypy-extensions==0.4.3
ndg-httpsclient==0.5.1
oauthlib==3.1.0
openapi-schema-validator==0.1.2
openapi-spec-validator==0.3.0
oscrypto==1.2.1
packaging==20.9
parso==0.8.1
pexpect==4.8.0
pickleshare==0.7.5
pluggy==0.13.1
prompt-toolkit==3.0.17
proto-plus==1.13.0
protobuf==3.15.2
ptyprocess==0.7.0
pusher==3.0.0
py==1.10.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycparser==2.20
pycryptodomex==3.10.1
Pygments==2.8.1
PyJWT==2.0.1
PyNaCl==1.4.0
pyOpenSSL==19.1.0
pyparsing==2.4.7
pyrsistent==0.17.3
pytest==6.2.2
pytest-subtests==0.4.0
python-dateutil==2.6.0
python-dotenv==0.15.0
python-editor==1.0.4
python-json-logger==2.0.1
python-jwt==3.3.0
pytz==2020.5
PyYAML==5.4.1
requests==2.23.0
requests-oauthlib==1.3.0
rsa==4.7.2
s3transfer==0.3.4
schemathesis==3.1.0
six==1.15.0
snowflake-connector-python==2.3.10
snowflake-sqlalchemy==1.2.4
sortedcontainers==2.3.0
SQLAlchemy==1.3.23
SQLAlchemy-Utils==0.36.8
starlette==0.13.8
strict-rfc3339==0.7
swagger-ui-bundle==0.0.8
toml==0.10.2
traitlets==5.0.5
typing-extensions==3.7.4.3
typing-inspect==0.6.0
uritemplate==3.0.1
urllib3==1.25.11
wcwidth==0.2.5
Werkzeug==1.0.1
wrapt==1.12.1
yarl==1.6.3
zipp==3.4.0
  1. What did you do? When connecting to a snowflake host, snowflake's OSCP mechanism validates the certificates.

When a connection is being made, the OCSP validation mechanism triggered because the snowflake-connector wraps the default python SSL mechanism: image

The bug is that if the cache already exists, the oscp_snowflake updates the cache although there is nothing to update - the certificate is already cached and no state is being changed.

The stack trace is: image

And looking on read_ocsp_response_cache_file: image

It uses decode_ocsp_response_cache with the cache (json.load(f)) as the parameter.

The problem is that decode_ocsp_response_cache doesn't distinguish between a real response (which comes from a server) to a cached response (which comes from a file): image

And than

SnowflakeOCSP.OCSP_CACHE.update_or_delete_cache(
                    self, cert_id, b64decode(ocsp_response), ts)

is being triggered no matter the input source.

This is a huge problem for us because we use multi-threaded Flask server with SQLAlchemy, and these update_or_delete_cache creates A LOT of locks which, in some circumstances create a timeout.

In addition, I think it's a security issue because the certificate timestamp being update although no server verification ever made.

  1. What did you expect to see? The cache should be updated only if the certificates come from a server, via _download_ocsp_response_cache: image

  2. What did you see instead? The cache being updated based on... itself

  3. Can you set logging to DEBUG and collect the logs? There are a huge amount of logs in our ELK, which you can discuss with us (anecdotes.ai) and we'll demonstrate the issue.

shahargl avatar Apr 13 '21 12:04 shahargl

Maybe you can take a look @sfc-gh-stan?

shahargl avatar Apr 19 '21 11:04 shahargl

I have a better cache implementation written. I can pick this up soon!

sfc-gh-mkeller avatar Jun 11 '21 16:06 sfc-gh-mkeller

Any updates regarding this?

talboren avatar Apr 13 '22 07:04 talboren

To clean up and re-prioritize bugs and feature requests we are closing all issues older than 6 months as of March 1, 2023. If there are any issues or feature requests that you would like us to address, please re-create them. For urgent issues, opening a support case with this link Snowflake Community is the fastest way to get a response

github-actions[bot] avatar Mar 10 '23 02:03 github-actions[bot]