Repository: mlflow/mlflow

Issue:
[BUG] Security Vulnerability
Please check it here https://huntr.com/bounties/e3d7a994-bfd6-4772-ac9b-9aee1aa16a5f/

Discussion:
github-actions[bot]: <!-- documentation preview -->


Documentation preview for 4af134e835e5636610e2f792c54a21e939ee04b8 will be available [here](https://output.circle-artifacts.com/output/job/af76e5a6-42c3-4588-930e-9fd616f25d7d/artifacts/0/docs/build/html/index.html) when [this CircleCI job](https://circleci.com/gh/mlflow/mlflow/87202) completes successfully.

<details>
<summary>More info</summary>

- Ignore this comment if this PR does not change the documentation.
- It takes a few minutes for the preview to be available.
- The preview is updated when a new commit is pushed to this PR.
- This comment was created by https://github.com/mlflow/mlflow/actions/runs/7692155696.

</details>


Patch:
diff --git a/docs/source/conf.py b/docs/source/conf.py
index d48256ab2..af66894ff 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -376,6 +376,7 @@ nitpick_ignore = [
     ("py:class", "pydantic.main.BaseModel"),
     ("py:class", "ConfigDict"),
     ("py:class", "FieldInfo"),
+    ("py:class", "ComputedFieldInfo"),
     ("py:class", "keras_core.src.callbacks.callback.Callback"),
 ]
 
diff --git a/docs/source/llms/langchain/guide/index.rst b/docs/source/llms/langchain/guide/index.rst
index 34a0f1321..4855e9be6 100644
--- a/docs/source/llms/langchain/guide/index.rst
+++ b/docs/source/llms/langchain/guide/index.rst
@@ -254,6 +254,89 @@ MLflow `langchain` flavor supports autologging of LangChain models, which provid
 - **Seamless Metrics Recording**: Autologging effortlessly captures metrics for evaluating generated texts, as well as key objects such as llms and agents employed during inference.
 - **Automated Input and Output Logging**: Autologging takes care of logging inputs and outputs of the LangChain model during inference. The recorded results are neatly organized into an inference_inputs_outputs.json file, providing a comprehensive overview of the model's inference history.
 
+.. note::
+    To use MLflow LangChain autologging, please upgrade langchain to **version 0.1.0** or higher.
+    Depending on your existing environment, you may need to manually install langchain_community>=0.0.16 in order to enable the automatic logging of artifacts and metrics. (this behavior will be modified in the future to be an optional import)
+    If autologging doesn't log artifacts as expected, please check the warning messages in `stdout` logs. 
+    For langchain_community==0.0.16, you will need to install the `textstat` and `spacy` libraries manually, as well as restarting any active interactive environment (i.e., a notebook environment). On Databricks, you can achieve this via executing `dbutils.library.restartPython()` to force the Python REPL to restart, allowing the newly installed libraries to be available.
+
+MLflow langchain autologging injects `MlflowCallbackHandler <https://github.com/langchain-ai/langchain/blob/master/libs/community/langchain_community/callbacks/mlflow_callback.py>`_ into the langchain model inference process to log
+metrics and artifacts automatically. We will only log the model if both `log_models` is set to `True` when calling :py:func:`mlflow.langchain.autolog` and the objects being invoked are within the supported model types: `Chain`, `AgentExecutor`, `BaseRetriever`, `RunnableSequence`, `RunnableParallel`, `RunnableBranch`, `SimpleChatModel`, `ChatPromptTemplate`,
+`RunnableLambda`, `RunnablePassthrough`. Additional model types will be supported in the future.
+
+.. note::
+    We patch `invoke` function for all supported langchain models, `__call__` function for Chains, AgentExecutors models, and `get_relevant_documents` function for BaseRetrievers, so only when those functions are called MLflow autologs metrics and artifacts.
+    If the model contains retrievers, we don't support autologging the model because it requires saving `loader_fn` and `persist_dir` in order to load the model. Please log the model manually if you want to log the model with retrievers.
+
+The following metrics and artifacts are logged by default (depending on the models involved):
+
+Artifacts:
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | Artifact name                                 | Explanation                                                               |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | table_action_records.html                     | Each action's details, including chains, tools, llms, agents, retrievers. |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | table_session_analysis.html                   | Details about prompt and output for each prompt step; token usages;       |
+  |                                               | text analysis metrics                                                     |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | chat_html.html                                | LLM input and output details                                              |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | llm_start_x_prompt_y.json                     | Includes prompt and kwargs passed during llm `generate` call              |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | llm_end_x_generation_y.json                   | Includes llm_output of the LLM result                                     |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | ent-<hash string of generation.text>.html     | Visualization of the generation text using spacy "en_core_web_sm" model   |
+  |                                               | with style ent (if spacy is installed and the model is downloaded)        | 
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | dep-<hash string of generation.text>.html     | Visualization of the generation text using spacy "en_core_web_sm" model   |
+  |                                               | with style dep (if spacy is installed and the model is downloaded)        |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | llm_new_tokens_x.json                         | Records new tokens added to the LLM during inference                      |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | chain_start_x.json                            | Records the inputs and chain related information during inference         |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | chain_end_x.json                              | Records the chain outputs                                                 |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | tool_start_x.json                             | Records the tool's name, descriptions information during inference        |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | tool_end_x.json                               | Records observation of the tool                                           |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | retriever_start_x.json                        | Records the retriever's information during inference                      |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | retriever_end_x.json                          | Records the retriever's result documents                                  |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | agent_finish_x.json                           | Records final return value of the ActionAgent, including output and log   |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | agent_action_x.json                           | Records the ActionAgent's action details                                  |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | on_text_x.json                                | Records the text during inference                                         |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | inference_inputs_outputs.json                 | Input and output details for each inference call (logged by default, can  |
+  |                                               | be turned off by setting `log_inputs_outputs=False` when turn on autolog) |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+
+Metrics:
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | Metric types                                  | Details                                                                   |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | Basic Metrics                                 | step, starts, ends, errors, text_ctr, chain_starts, chain_ends, llm_starts|
+  |                                               | llm_ends, llm_streams, tool_starts, tool_ends, agent_ends, retriever_ends |
+  |                                               | retriever_starts (they're the count number of each component invocation)  |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+  | Text Analysis Metrics                         | flesch_reading_ease, flesch_kincaid_grade, smog_index, coleman_liau_index |
+  |                                               | automated_readability_index, dale_chall_readability_score,                |
+  |                                               | difficult_words, linsear_write_formula, gunning_fog, fernandez_huerta,    |
+  |                                               | szigriszt_pazos, gutierrez_polini, crawford, gulpease_index, osman        |
+  |                                               | (they're the text analysis metrics of the generation text if `textstat`   |
+  |                                               | library is installed)                                                     |
+  +-----------------------------------------------+---------------------------------------------------------------------------+
+
+.. note::
+    Each inference call logs those artifacts into a separate directory named `artifacts-<session_id>-<idx>`, where `session_id` is randomly generated uuid, and `idx` is the index of the inference call.
+    `session_id` is also preserved in the `inference_inputs_outputs.json` file, so you can easily find the corresponding artifacts for each inference call.
+
+If you encounter any issues unexpected, please feel free to open an issue in `MLflow Github repo <https://github.com/mlflow/mlflow/issues>`_.
+
 An example of MLflow langchain autologging
 """"""""""""""""""""""""""""""""""""""""""
 
diff --git a/docs/source/python_api/mlflow.gateway.rst b/docs/source/python_api/mlflow.gateway.rst
index 10487e54a..174166659 100644
--- a/docs/source/python_api/mlflow.gateway.rst
+++ b/docs/source/python_api/mlflow.gateway.rst
@@ -12,3 +12,4 @@ mlflow.gateway
 .. automodule:: mlflow.gateway.config
     :members:
     :undoc-members:
+    :exclude-members: model_computed_fields
diff --git a/examples/langchain/chain_autolog.py b/examples/langchain/chain_autolog.py
index 1bc1c3892..100614d42 100644
--- a/examples/langchain/chain_autolog.py
+++ b/examples/langchain/chain_autolog.py
@@ -8,6 +8,11 @@ from langchain.schema.runnable import RunnableLambda
 
 import mlflow
 
+# Uncomment the following to use the full abilities of langchain autologgin
+# %pip install `langchain_community>=0.0.16`
+# These two libraries enable autologging to log text analysis related artifacts
+# %pip install textstat spacy
+
 assert "OPENAI_API_KEY" in os.environ, "Please set the OPENAI_API_KEY environment variable."
 
 # Enable mlflow langchain autologging
diff --git a/mlflow/store/artifact/local_artifact_repo.py b/mlflow/store/artifact/local_artifact_repo.py
index f7d78e90f..42a0dd989 100644
--- a/mlflow/store/artifact/local_artifact_repo.py
+++ b/mlflow/store/artifact/local_artifact_repo.py
@@ -9,6 +9,7 @@ from mlflow.utils.file_utils import (
     mkdir,
     relative_path_to_artifact_path,
 )
+from mlflow.utils.uri import validate_path_is_safe
 
 
 class LocalArtifactRepository(ArtifactRepository):
@@ -74,8 +75,9 @@ class LocalArtifactRepository(ArtifactRepository):
         """
         if dst_path:
             return super().download_artifacts(artifact_path, dst_path)
-        # NOTE: The artifact_path is expected to be in posix format.
+        # NOTE: The artifact_path is expected to be a relative path in posix format.
         # Posix paths work fine on windows but just in case we normalize it here.
+        artifact_path = validate_path_is_safe(artifact_path)
         local_artifact_path = os.path.join(self.artifact_dir, os.path.normpath(artifact_path))
         if not os.path.exists(local_artifact_path):
             raise OSError(f"No such file or directory: '{local_artifact_path}'")
@@ -100,8 +102,9 @@ class LocalArtifactRepository(ArtifactRepository):
             return []
 
     def _download_file(self, remote_file_path, local_path):
-        # NOTE: The remote_file_path is expected to be in posix format.
+        # NOTE: The remote_file_path is expected to be a relative path in posix format.
         # Posix paths work fine on windows but just in case we normalize it here.
+        remote_file_path = validate_path_is_safe(remote_file_path)
         remote_file_path = os.path.join(self.artifact_dir, os.path.normpath(remote_file_path))
         shutil.copy2(remote_file_path, local_path)
 


Test patch:
diff --git a/tests/store/artifact/test_local_artifact_repo.py b/tests/store/artifact/test_local_artifact_repo.py
index ed0c76938..0cea53977 100644
--- a/tests/store/artifact/test_local_artifact_repo.py
+++ b/tests/store/artifact/test_local_artifact_repo.py
@@ -200,3 +200,8 @@ def test_delete_artifacts(local_artifact_repo):
 
 def test_delete_artifacts_with_nonexistent_path_succeeds(local_artifact_repo):
     local_artifact_repo.delete_artifacts("nonexistent")
+
+
+def test_download_artifacts_invalid_remote_file_path(local_artifact_repo):
+    with pytest.raises(MlflowException, match="Invalid path"):
+        local_artifact_repo.download_artifacts("/absolute/path/to/file")
diff --git a/tests/utils/test_promptlab_utils.py b/tests/utils/test_promptlab_utils.py
index 326a9dea0..fc71bea53 100644
--- a/tests/utils/test_promptlab_utils.py
+++ b/tests/utils/test_promptlab_utils.py
@@ -104,4 +104,4 @@ def test_create_promptlab_run(store):
     # try to load the model
     import mlflow.pyfunc
 
-    mlflow.pyfunc.load_model(os.path.join(artifact_location, "model"))
+    mlflow.pyfunc.load_model(f"{artifact_location}/model")