Skip to content

Commit 0f87d06

Browse files
authored
Fix CalculatorTool ACE vulnerability (#301)
* Fix calculator ACE vulnerability * Add result type check * Fix comments * Add type ignore error code * Fix flake8 and mypy conflicts * Fix flake8 and mypy conflicts
1 parent 39f0a38 commit 0f87d06

File tree

6 files changed

+29
-9
lines changed

6 files changed

+29
-9
lines changed

erniebot-agent/applications/erniebot_researcher/tools/utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from typing import Any, Dict, List, Union
77

88
import jsonlines
9-
import markdown # type: ignore
9+
import markdown # type: ignore[import-untyped]
1010
from langchain.docstore.document import Document
1111
from langchain.output_parsers.json import parse_json_markdown
1212
from weasyprint import CSS, HTML

erniebot-agent/src/erniebot_agent/agents/mixins/gradio_mixin.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def launch_gradio_demo(self: BaseAgent, **launch_kwargs: Any):
3030
# be constructed outside an event loop, which is probably not sensible.
3131
# TODO: Unified optional dependencies management
3232
try:
33-
import gradio as gr # type: ignore
33+
import gradio as gr # type: ignore[import-untyped]
3434
except ImportError:
3535
raise ImportError(
3636
"Could not import gradio, which is required for `launch_gradio_demo()`."

erniebot-agent/src/erniebot_agent/file/global_file_manager_handler.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
import weakref
1717
from typing import Any, NoReturn, Optional, final
1818

19-
import asyncio_atexit # type: ignore
19+
import asyncio_atexit # type: ignore[import-untyped]
2020
from typing_extensions import Self
2121

2222
from erniebot_agent.file.file_manager import FileManager
2323
from erniebot_agent.file.remote_file import AIStudioFileClient
2424
from erniebot_agent.utils import config_from_environ as C
2525

26-
_registry = weakref.WeakKeyDictionary() # type: ignore
26+
_registry: weakref.WeakKeyDictionary = weakref.WeakKeyDictionary()
2727

2828

2929
@final

erniebot-agent/src/erniebot_agent/tools/calculator_tool.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,21 @@ class CalculatorTool(Tool):
2424
output_type: Type[ToolParameterView] = CalculatorToolOutputView
2525

2626
async def __call__(self, math_formula: str) -> Dict[str, float]:
27-
return {"formula_result": eval(math_formula)}
27+
# XXX: In this eval-based implementation, non-mathematical Python
28+
# expressions are not rejected. Should we do regex checks to ensure that
29+
# the input is a mathematical expression?
30+
try:
31+
code = compile(math_formula, "<string>", "eval")
32+
except (SyntaxError, ValueError) as e:
33+
raise ValueError("Invalid input expression") from e
34+
try:
35+
result = eval(code, {"__builtins__": {}}, {})
36+
except NameError as e:
37+
names_not_allowed = code.co_names
38+
raise ValueError(f"Names {names_not_allowed} are not allowed in the expression.") from e
39+
if not isinstance(result, (float, int)):
40+
raise ValueError("The evaluation result of the expression is not a number.")
41+
return {"formula_result": result}
2842

2943
@property
3044
def examples(self) -> List[Message]:

erniebot-agent/src/erniebot_agent/utils/misc.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515

1616
class SingletonMeta(type):
17-
_insts = {} # type: ignore
17+
_insts: dict = {}
1818

1919
def __call__(cls, *args, **kwargs):
2020
# XXX: We note that the instance created in this way can be actually

erniebot/src/erniebot/utils/bos.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,15 @@ def upload_file_to_bos(
2626
access_key_id: Optional[str] = None,
2727
secret_access_key: Optional[str] = None,
2828
) -> str:
29-
from baidubce.auth.bce_credentials import BceCredentials # type: ignore
30-
from baidubce.bce_client_configuration import BceClientConfiguration # type: ignore
31-
from baidubce.services.bos.bos_client import BosClient # type: ignore
29+
from baidubce.auth.bce_credentials import ( # type: ignore[import-untyped]
30+
BceCredentials,
31+
)
32+
from baidubce.bce_client_configuration import ( # type: ignore[import-untyped]
33+
BceClientConfiguration,
34+
)
35+
from baidubce.services.bos.bos_client import ( # type: ignore[import-untyped]
36+
BosClient,
37+
)
3238

3339
b_config = BceClientConfiguration(
3440
credentials=BceCredentials(access_key_id, secret_access_key), endpoint=bos_host

0 commit comments

Comments
 (0)