We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Yaml loader should be replaced by safe_loader or other more secure loader
To load yaml files from unknown source, we should avoid using yaml's loader.  A better way is to use either safe_loader or other mechanism.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nvflare/lighter/provision.py`
Content:
```
1 # Copyright (c) 2021-2022, NVIDIA CORPORATION.  All rights reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 from __future__ import absolute_import
16 
17 import argparse
18 import os
19 import pathlib
20 import shutil
21 import sys
22 import webbrowser
23 
24 import yaml
25 
26 from nvflare.fuel.utils.class_utils import instantiate_class
27 from nvflare.lighter.spec import Participant, Project, Provisioner
28 
29 
30 def main():
31     parser = argparse.ArgumentParser()
32     parser.add_argument("-p", "--project_file", type=str, default="project.yml", help="file to describe FL project")
33     parser.add_argument("-w", "--workspace", type=str, default="workspace", help="directory used by provision")
34     parser.add_argument("-c", "--custom_folder", type=str, default=".", help="additional folder to load python codes")
35     parser.add_argument(
36         "-u",
37         "--ui_tool",
38         action="store_true",
39         help="Run provisioning UI tool to generate project.yml file",
40     )
41 
42     args = parser.parse_args()
43 
44     file_path = pathlib.Path(__file__).parent.absolute()
45     current_path = os.getcwd()
46     custom_folder_path = os.path.join(current_path, args.custom_folder)
47     sys.path.append(custom_folder_path)
48     print("Path list (sys.path) for python codes loading: {}".format(sys.path))
49 
50     # main project file
51     project_file = args.project_file
52     current_project_yml = os.path.join(current_path, "project.yml")
53     if len(sys.argv) == 1 and not os.path.exists(current_project_yml):
54         answer = input(
55             f"No project.yml found in current folder.  Is it OK to generate one at {current_project_yml} for you? (y/N) "
56         )
57         if answer.strip().upper() == "Y":
58             shutil.copyfile(os.path.join(file_path, "project.yml"), current_project_yml)
59             print(f"{current_project_yml} was created.  Please edit it to fit your FL configuration.")
60         exit(0)
61 
62     if args.ui_tool:
63         ui_helper_path = os.path.join(file_path, "provision_helper.html")
64         ui_helper_url = f"file://{ui_helper_path}"
65         webbrowser.open_new_tab(ui_helper_url)
66         print(
67             "\n******\n"
68             "Now launching provisioning UI tool.\n"
69             "After generating project.yml in the browser and saving it to your local folder,\n"
70             "please re-run provision with -p option, pointing to the generated project.yml, to generate all packages.\n******\n"
71         )
72         exit(0)
73 
74     workspace = args.workspace
75     workspace_full_path = os.path.join(current_path, workspace)
76 
77     project_full_path = os.path.join(current_path, project_file)
78     print(f"Project yaml file: {project_full_path}.")
79 
80     project_dict = yaml.load(open(project_full_path, "r"), Loader=yaml.Loader)
81     api_version = project_dict.get("api_version")
82     if api_version not in [3]:
83         raise ValueError(f"API version expected 3 but found {api_version}")
84 
85     project_name = project_dict.get("name")
86     project_description = project_dict.get("description", "")
87     participants = list()
88     for p in project_dict.get("participants"):
89         participants.append(Participant(**p))
90     project = Project(name=project_name, description=project_description, participants=participants)
91 
92     builders = list()
93     for b in project_dict.get("builders"):
94         path = b.get("path")
95         args = b.get("args")
96         builders.append(instantiate_class(path, args))
97 
98     provisioner = Provisioner(workspace_full_path, builders)
99 
100     provisioner.provision(project)
101 
102 
103 if __name__ == "__main__":
104     main()
105
```

Path: `nvflare/lighter/utils.py`
Content:
```
1 # Copyright (c) 2021-2022, NVIDIA CORPORATION.  All rights reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 import os
16 import random
17 from base64 import b64encode
18 
19 import yaml
20 from cryptography.hazmat.primitives import hashes
21 from cryptography.hazmat.primitives.asymmetric import padding
22 
23 
24 def generate_password():
25     s = "abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"
26     passlen = 16
27     p = "".join(random.sample(s, passlen))
28     return p
29 
30 
31 def sign_all(content_folder, signing_pri_key):
32     signatures = dict()
33     for f in os.listdir(content_folder):
34         path = os.path.join(content_folder, f)
35         if os.path.isfile(path):
36             signature = signing_pri_key.sign(
37                 data=open(path, "rb").read(),
38                 padding=padding.PSS(
39                     mgf=padding.MGF1(hashes.SHA256()),
40                     salt_length=padding.PSS.MAX_LENGTH,
41                 ),
42                 algorithm=hashes.SHA256(),
43             )
44             signatures[f] = b64encode(signature).decode("utf-8")
45     return signatures
46 
47 
48 def load_yaml(file_name):
49     return yaml.load(open(file_name, "r"), Loader=yaml.Loader)
50 
51 
52 def sh_replace(src, mapping_dict):
53     result = src
54     for k, v in mapping_dict.items():
55         result = result.replace("{~~" + k + "~~}", str(v))
56     return result
57
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/nvflare/lighter/provision.py b/nvflare/lighter/provision.py
--- a/nvflare/lighter/provision.py
+++ b/nvflare/lighter/provision.py
@@ -21,10 +21,9 @@
 import sys
 import webbrowser
 
-import yaml
-
 from nvflare.fuel.utils.class_utils import instantiate_class
 from nvflare.lighter.spec import Participant, Project, Provisioner
+from nvflare.lighter.utils import load_yaml
 
 
 def main():
@@ -77,7 +76,7 @@
     project_full_path = os.path.join(current_path, project_file)
     print(f"Project yaml file: {project_full_path}.")
 
-    project_dict = yaml.load(open(project_full_path, "r"), Loader=yaml.Loader)
+    project_dict = load_yaml(project_full_path)
     api_version = project_dict.get("api_version")
     if api_version not in [3]:
         raise ValueError(f"API version expected 3 but found {api_version}")
diff --git a/nvflare/lighter/utils.py b/nvflare/lighter/utils.py
--- a/nvflare/lighter/utils.py
+++ b/nvflare/lighter/utils.py
@@ -46,7 +46,7 @@
 
 
 def load_yaml(file_name):
-    return yaml.load(open(file_name, "r"), Loader=yaml.Loader)
+    return yaml.safe_load(open(file_name, "r"))
 
 
 def sh_replace(src, mapping_dict):

{"golden_diff": "diff --git a/nvflare/lighter/provision.py b/nvflare/lighter/provision.py\n--- a/nvflare/lighter/provision.py\n+++ b/nvflare/lighter/provision.py\n@@ -21,10 +21,9 @@\n import sys\n import webbrowser\n \n-import yaml\n-\n from nvflare.fuel.utils.class_utils import instantiate_class\n from nvflare.lighter.spec import Participant, Project, Provisioner\n+from nvflare.lighter.utils import load_yaml\n \n \n def main():\n@@ -77,7 +76,7 @@\n     project_full_path = os.path.join(current_path, project_file)\n     print(f\"Project yaml file: {project_full_path}.\")\n \n-    project_dict = yaml.load(open(project_full_path, \"r\"), Loader=yaml.Loader)\n+    project_dict = load_yaml(project_full_path)\n     api_version = project_dict.get(\"api_version\")\n     if api_version not in [3]:\n         raise ValueError(f\"API version expected 3 but found {api_version}\")\ndiff --git a/nvflare/lighter/utils.py b/nvflare/lighter/utils.py\n--- a/nvflare/lighter/utils.py\n+++ b/nvflare/lighter/utils.py\n@@ -46,7 +46,7 @@\n \n \n def load_yaml(file_name):\n-    return yaml.load(open(file_name, \"r\"), Loader=yaml.Loader)\n+    return yaml.safe_load(open(file_name, \"r\"))\n \n \n def sh_replace(src, mapping_dict):\n", "issue": "Yaml loader should be replaced by safe_loader or other more secure loader\nTo load yaml files from unknown source, we should avoid using yaml's loader.  A better way is to use either safe_loader or other mechanism.\n", "before_files": [{"content": "# Copyright (c) 2021-2022, NVIDIA CORPORATION.  All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import\n\nimport argparse\nimport os\nimport pathlib\nimport shutil\nimport sys\nimport webbrowser\n\nimport yaml\n\nfrom nvflare.fuel.utils.class_utils import instantiate_class\nfrom nvflare.lighter.spec import Participant, Project, Provisioner\n\n\ndef main():\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"-p\", \"--project_file\", type=str, default=\"project.yml\", help=\"file to describe FL project\")\n    parser.add_argument(\"-w\", \"--workspace\", type=str, default=\"workspace\", help=\"directory used by provision\")\n    parser.add_argument(\"-c\", \"--custom_folder\", type=str, default=\".\", help=\"additional folder to load python codes\")\n    parser.add_argument(\n        \"-u\",\n        \"--ui_tool\",\n        action=\"store_true\",\n        help=\"Run provisioning UI tool to generate project.yml file\",\n    )\n\n    args = parser.parse_args()\n\n    file_path = pathlib.Path(__file__).parent.absolute()\n    current_path = os.getcwd()\n    custom_folder_path = os.path.join(current_path, args.custom_folder)\n    sys.path.append(custom_folder_path)\n    print(\"Path list (sys.path) for python codes loading: {}\".format(sys.path))\n\n    # main project file\n    project_file = args.project_file\n    current_project_yml = os.path.join(current_path, \"project.yml\")\n    if len(sys.argv) == 1 and not os.path.exists(current_project_yml):\n        answer = input(\n            f\"No project.yml found in current folder.  Is it OK to generate one at {current_project_yml} for you? (y/N) \"\n        )\n        if answer.strip().upper() == \"Y\":\n            shutil.copyfile(os.path.join(file_path, \"project.yml\"), current_project_yml)\n            print(f\"{current_project_yml} was created.  Please edit it to fit your FL configuration.\")\n        exit(0)\n\n    if args.ui_tool:\n        ui_helper_path = os.path.join(file_path, \"provision_helper.html\")\n        ui_helper_url = f\"file://{ui_helper_path}\"\n        webbrowser.open_new_tab(ui_helper_url)\n        print(\n            \"\\n******\\n\"\n            \"Now launching provisioning UI tool.\\n\"\n            \"After generating project.yml in the browser and saving it to your local folder,\\n\"\n            \"please re-run provision with -p option, pointing to the generated project.yml, to generate all packages.\\n******\\n\"\n        )\n        exit(0)\n\n    workspace = args.workspace\n    workspace_full_path = os.path.join(current_path, workspace)\n\n    project_full_path = os.path.join(current_path, project_file)\n    print(f\"Project yaml file: {project_full_path}.\")\n\n    project_dict = yaml.load(open(project_full_path, \"r\"), Loader=yaml.Loader)\n    api_version = project_dict.get(\"api_version\")\n    if api_version not in [3]:\n        raise ValueError(f\"API version expected 3 but found {api_version}\")\n\n    project_name = project_dict.get(\"name\")\n    project_description = project_dict.get(\"description\", \"\")\n    participants = list()\n    for p in project_dict.get(\"participants\"):\n        participants.append(Participant(**p))\n    project = Project(name=project_name, description=project_description, participants=participants)\n\n    builders = list()\n    for b in project_dict.get(\"builders\"):\n        path = b.get(\"path\")\n        args = b.get(\"args\")\n        builders.append(instantiate_class(path, args))\n\n    provisioner = Provisioner(workspace_full_path, builders)\n\n    provisioner.provision(project)\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "nvflare/lighter/provision.py"}, {"content": "# Copyright (c) 2021-2022, NVIDIA CORPORATION.  All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport os\nimport random\nfrom base64 import b64encode\n\nimport yaml\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives.asymmetric import padding\n\n\ndef generate_password():\n    s = \"abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n    passlen = 16\n    p = \"\".join(random.sample(s, passlen))\n    return p\n\n\ndef sign_all(content_folder, signing_pri_key):\n    signatures = dict()\n    for f in os.listdir(content_folder):\n        path = os.path.join(content_folder, f)\n        if os.path.isfile(path):\n            signature = signing_pri_key.sign(\n                data=open(path, \"rb\").read(),\n                padding=padding.PSS(\n                    mgf=padding.MGF1(hashes.SHA256()),\n                    salt_length=padding.PSS.MAX_LENGTH,\n                ),\n                algorithm=hashes.SHA256(),\n            )\n            signatures[f] = b64encode(signature).decode(\"utf-8\")\n    return signatures\n\n\ndef load_yaml(file_name):\n    return yaml.load(open(file_name, \"r\"), Loader=yaml.Loader)\n\n\ndef sh_replace(src, mapping_dict):\n    result = src\n    for k, v in mapping_dict.items():\n        result = result.replace(\"{~~\" + k + \"~~}\", str(v))\n    return result\n", "path": "nvflare/lighter/utils.py"}], "after_files": [{"content": "# Copyright (c) 2021-2022, NVIDIA CORPORATION.  All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom __future__ import absolute_import\n\nimport argparse\nimport os\nimport pathlib\nimport shutil\nimport sys\nimport webbrowser\n\nfrom nvflare.fuel.utils.class_utils import instantiate_class\nfrom nvflare.lighter.spec import Participant, Project, Provisioner\nfrom nvflare.lighter.utils import load_yaml\n\n\ndef main():\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"-p\", \"--project_file\", type=str, default=\"project.yml\", help=\"file to describe FL project\")\n    parser.add_argument(\"-w\", \"--workspace\", type=str, default=\"workspace\", help=\"directory used by provision\")\n    parser.add_argument(\"-c\", \"--custom_folder\", type=str, default=\".\", help=\"additional folder to load python codes\")\n    parser.add_argument(\n        \"-u\",\n        \"--ui_tool\",\n        action=\"store_true\",\n        help=\"Run provisioning UI tool to generate project.yml file\",\n    )\n\n    args = parser.parse_args()\n\n    file_path = pathlib.Path(__file__).parent.absolute()\n    current_path = os.getcwd()\n    custom_folder_path = os.path.join(current_path, args.custom_folder)\n    sys.path.append(custom_folder_path)\n    print(\"Path list (sys.path) for python codes loading: {}\".format(sys.path))\n\n    # main project file\n    project_file = args.project_file\n    current_project_yml = os.path.join(current_path, \"project.yml\")\n    if len(sys.argv) == 1 and not os.path.exists(current_project_yml):\n        answer = input(\n            f\"No project.yml found in current folder.  Is it OK to generate one at {current_project_yml} for you? (y/N) \"\n        )\n        if answer.strip().upper() == \"Y\":\n            shutil.copyfile(os.path.join(file_path, \"project.yml\"), current_project_yml)\n            print(f\"{current_project_yml} was created.  Please edit it to fit your FL configuration.\")\n        exit(0)\n\n    if args.ui_tool:\n        ui_helper_path = os.path.join(file_path, \"provision_helper.html\")\n        ui_helper_url = f\"file://{ui_helper_path}\"\n        webbrowser.open_new_tab(ui_helper_url)\n        print(\n            \"\\n******\\n\"\n            \"Now launching provisioning UI tool.\\n\"\n            \"After generating project.yml in the browser and saving it to your local folder,\\n\"\n            \"please re-run provision with -p option, pointing to the generated project.yml, to generate all packages.\\n******\\n\"\n        )\n        exit(0)\n\n    workspace = args.workspace\n    workspace_full_path = os.path.join(current_path, workspace)\n\n    project_full_path = os.path.join(current_path, project_file)\n    print(f\"Project yaml file: {project_full_path}.\")\n\n    project_dict = load_yaml(project_full_path)\n    api_version = project_dict.get(\"api_version\")\n    if api_version not in [3]:\n        raise ValueError(f\"API version expected 3 but found {api_version}\")\n\n    project_name = project_dict.get(\"name\")\n    project_description = project_dict.get(\"description\", \"\")\n    participants = list()\n    for p in project_dict.get(\"participants\"):\n        participants.append(Participant(**p))\n    project = Project(name=project_name, description=project_description, participants=participants)\n\n    builders = list()\n    for b in project_dict.get(\"builders\"):\n        path = b.get(\"path\")\n        args = b.get(\"args\")\n        builders.append(instantiate_class(path, args))\n\n    provisioner = Provisioner(workspace_full_path, builders)\n\n    provisioner.provision(project)\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "nvflare/lighter/provision.py"}, {"content": "# Copyright (c) 2021-2022, NVIDIA CORPORATION.  All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport os\nimport random\nfrom base64 import b64encode\n\nimport yaml\nfrom cryptography.hazmat.primitives import hashes\nfrom cryptography.hazmat.primitives.asymmetric import padding\n\n\ndef generate_password():\n    s = \"abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n    passlen = 16\n    p = \"\".join(random.sample(s, passlen))\n    return p\n\n\ndef sign_all(content_folder, signing_pri_key):\n    signatures = dict()\n    for f in os.listdir(content_folder):\n        path = os.path.join(content_folder, f)\n        if os.path.isfile(path):\n            signature = signing_pri_key.sign(\n                data=open(path, \"rb\").read(),\n                padding=padding.PSS(\n                    mgf=padding.MGF1(hashes.SHA256()),\n                    salt_length=padding.PSS.MAX_LENGTH,\n                ),\n                algorithm=hashes.SHA256(),\n            )\n            signatures[f] = b64encode(signature).decode(\"utf-8\")\n    return signatures\n\n\ndef load_yaml(file_name):\n    return yaml.safe_load(open(file_name, \"r\"))\n\n\ndef sh_replace(src, mapping_dict):\n    result = src\n    for k, v in mapping_dict.items():\n        result = result.replace(\"{~~\" + k + \"~~}\", str(v))\n    return result\n", "path": "nvflare/lighter/utils.py"}]}