SkillTotal

Is pandas safe?

No malicious indicators - review capabilities before installing
Notable — review in context (capabilities are not malware):
  • Python shell/command execution
  • Unsafe deserialization
  • Python dynamic code execution

pandas is an AI python_package analyzed by SkillTotal's deterministic static scanner. The scan found no malicious indicators, though 6 risky constructs are reported for review. It can: dynamic code execution, filesystem read, filesystem write, network egress and shell execution — capabilities are what the code can do, not a verdict on intent. Risk score 20/100 (low).

pandas 3.0.3

python_package · pypi:pandas
LOW
20
/ 100 risk score
Snapshot · scanned Jul 5, 2026 · pandas@3.0.3 · engine 0.32.0 / ruleset 30

Automated static-analysis result. It can contain false positives and false negatives, and is not a claim about the intent of pandas's authors. Report a false positive.

Capabilities — what this component can do (not a risk score):
dynamic code executionfilesystem readfilesystem writenetwork egressshell execution

Findings (6)

HIGHUnsafe deserializationST-DESERIALIZE-PY

It loads data with a format that can rebuild arbitrary objects (e.g. pickle, or unsafe YAML).

return pickle.load(handles.handle)

Why it matters: Feeding such a loader untrusted data can execute code hidden inside that data.

Fix: Deserialize untrusted data with a safe format/loader: JSON, or yaml.safe_load / Loader=SafeLoader. Reserve pickle/marshal for data you fully control.

HIGHPython dynamic code executionST-DYN-PY

The code turns strings into live code at runtime (eval / new Function / exec).

return str(CreateTable(self.table).compile(self.pd_sql.con))

Why it matters: If those strings aren't fixed and trusted, they become a way to run arbitrary code.

Fix: Avoid evaluating dynamically constructed code; if unavoidable, ensure the input is a trusted constant and never derived from external data.

HIGHPython shell/command executionST-SHELL-PY

The component can run operating-system commands or spawn processes.

raw_locales = subprocess.check_output(["locale", "-a"])
process = subprocess.Popen(
                [command, *args],
                cwd=cwd,
                env=env,
                stdout=subprocess.PIPE,
                stderr=(subprocess.PIPE if hide_stderr else None),
                **pop …
with subprocess.Popen(
            ["pbcopy", "w"], stdin=subprocess.PIPE, close_fds=True
        ) as p:
with subprocess.Popen(
            ["pbpaste", "r"], stdout=subprocess.PIPE, close_fds=True
        ) as p:
with subprocess.Popen(
            ["xclip", "-selection", selection], stdin=subprocess.PIPE, close_fds=True
        ) as p:
with subprocess.Popen(
            ["xclip", "-selection", selection, "-o"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            close_fds=True,
        ) as p:
with subprocess.Popen(
            ["xsel", selection_flag, "-i"], stdin=subprocess.PIPE, close_fds=True
        ) as p:
with subprocess.Popen(
            ["xsel", selection_flag, "-o"], stdout=subprocess.PIPE, close_fds=True
        ) as p:
subprocess.check_call(args, close_fds=True)
p = subprocess.Popen(args, stdin=subprocess.PIPE, close_fds=True)
p = subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)
with subprocess.Popen(
            [
                "qdbus",
                "org.kde.klipper",
                "/klipper",
                "setClipboardContents",
                text.encode(ENCODING),
            ],
            stdin=sub …
with subprocess.Popen(
            ["qdbus", "org.kde.klipper", "/klipper", "getClipboardContents"],
            stdout=subprocess.PIPE,
            close_fds=True,
        ) as p:
with subprocess.Popen(["clip.exe"], stdin=subprocess.PIPE, close_fds=True) as p:
with subprocess.Popen(
            ["powershell.exe", "-command", "Get-Clipboard"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            close_fds=True,
        ) as p:

Why it matters: Powerful and often legitimate — confirm the commands aren't built from untrusted input.

Fix: Confirm the command and its arguments are fully controlled and not derived from untrusted input; avoid shell=True.

MEDIUMPython filesystem readST-FS-PY-READ

The component reads files from disk.

with open(pxifile, encoding="utf-8") as f:
with open(versionfile_abs, encoding="utf-8") as fobj:
with open("/dev/clipboard", encoding="utf-8") as fd:
handle = open(
                handle,
                ioargs.mode,
                encoding=ioargs.encoding,
                errors=errors,
                newline="",
            )
handle = open(handle, ioargs.mode)
handle = open(handle, "rb")
kwargs["open_with"] = lambda path, _: fsspec.open(
                path, "wb", **(storage_options or {})
            ).open()
buf = self._read_bytes(const.align_1_offset, const.align_1_length)
buf = self._read_bytes(const.align_2_offset, const.align_2_length)
buf = self._read_bytes(const.endianness_offset, const.endianness_length)
buf = self._read_bytes(const.encoding_offset, const.encoding_length)[0]
return self._read_bytes(offset, 1)[0]
subheader_signature = self._read_bytes(subheader_offset, self._int_length)
buf = self._read_bytes(offset, text_block_size)
buf = self._read_bytes(offset1, self._lcp)
buf = self._read_bytes(offset1, self._lcp)
buf = self._read_bytes(offset1, self._lcp)
buf = self._read_bytes(offset1, self._lcs)

Why it matters: Usually legitimate, but worth confirming it can't be steered into reading sensitive files.

Fix: Confirm which files are read and that paths cannot be influenced by untrusted input to reach sensitive locations.

MEDIUMPython filesystem write/deleteST-FS-PY-WRITE

The component writes or deletes files on disk.

with open(outfile, "w", encoding="utf-8") as f:
with open(path, "w", encoding="utf-8") as file:
with open(buf, "w", encoding="utf-8") as f:
with open("/dev/clipboard", "w", encoding="utf-8") as fd:
with open(buf, "w", encoding=encoding, newline="") as f:
os.unlink(self._fname)
self._write_bytes(vl.generate_value_label(self._byteorder))
self._write_bytes(struct.pack("b", 114))
self._write_bytes(struct.pack(byteorder + "h", self.nvar)[:2])
self._write_bytes(struct.pack(byteorder + "i", self.nobs)[:4])
self._write_bytes(self._null_terminate_bytes(_pad_bytes("", 80)))
self._write_bytes(
                self._null_terminate_bytes(_pad_bytes(data_label[:80], 80))
            )
self._write_bytes(self._null_terminate_bytes(ts))
self._write_bytes(struct.pack("B", typ))
self._write_bytes(records.tobytes())
self._write_bytes(bytes("<stata_dta>", "utf-8"))
self._write_bytes(self._tag(bio.getvalue(), "header"))
self._write_bytes(self._tag(bio.getvalue(), "map"))
self._write_bytes(self._tag(bio.getvalue(), "variable_types"))
self._write_bytes(self._tag(bio.getvalue(), "varnames"))
self._write_bytes(self._tag(b"\x00" * sort_size * (self.nvar + 1), "sortlist"))
self._write_bytes(self._tag(bio.getvalue(), "formats"))
self._write_bytes(self._tag(bio.getvalue(), "value_label_names"))
self._write_bytes(self._tag(bio.getvalue(), "variable_labels"))
self._write_bytes(self._tag(bio.getvalue(), "variable_labels"))

Why it matters: Usually legitimate, but worth confirming the paths can't be controlled by untrusted input.

Fix: Confirm which files are written/deleted and that paths cannot be influenced by untrusted input.

MEDIUMPython network egressST-NET-PY

The component makes outbound network requests.

from urllib.parse import (
    urljoin,
    urlparse as parse_url,
    uses_netloc,
    uses_params,
    uses_relative,
)
return parse_url(url).scheme in _VALID_URLS
import urllib.request
return urllib.request.urlopen(*args, **kwargs)  # noqa: TID251
import urllib.request
req_info = urllib.request.Request(filepath_or_buffer, headers=storage_options)
from urllib.request import pathname2url
return urljoin("file:", pathname2url(path))

Why it matters: Usually legitimate, but confirm the destinations are expected and no sensitive data leaves.

Fix: Confirm the destination hosts are expected and that no sensitive data is sent off-host.

Check your own component

Run the same evidence-backed scan on any MCP server, agent skill, or package.

Scan your own component

Or get notified if this component's risk changes:

How we determine this: deterministic static analysis (regex + AST), evidence-anchored, no code execution. Methodology →