T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/server.py:85- Finding
Filesystem access controls are disabled by default
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is purpose-aligned, but it opens a powerful unauthenticated local QGIS control server that can read and write files and optionally run Python code with weak default containment.
Install only for trusted local workflows. Run the server under a low-privilege account, keep it bound to localhost, stop it when not needed, set QGIS_ALLOWED_PATHS to dedicated input/output folders, and do not enable PYQGIS_ENABLE_EXEC unless you are in an isolated environment where arbitrary Python execution is acceptable. Confirm output paths before write or render operations because the server can create or overwrite files.
scripts/server.py:85Filesystem access controls are disabled by default
scripts/server.py:145The configured path whitelist can be bypassed using nested or relative paths
scripts/server.py:242Unbounded HTTP request bodies can exhaust memory or block the service
scripts/server.py:395Unbounded rendering dimensions permit memory and CPU exhaustion
The API advertises /pyqgis as executing arbitrary PyQGIS code, but the implementation uses unrestricted Python exec() with a globals dict that still allows access to Python builtins and imports. This mismatch understates the attack surface and can lead users to enable a full arbitrary-code-execution endpoint under the mistaken belief that it is limited to PyQGIS scripting.
The documentation claims path allowlisting applies to /call and /pyqgis, but /pyqgis executes arbitrary Python code, which can trivially bypass any string-based path check by constructing paths at runtime, importing os/pathlib, or performing non-file actions entirely outside the validator. This creates a dangerous false sense of protection for operators who may rely on the documented whitelist as a security boundary.
The /pyqgis endpoint executes user-supplied code with Python exec(), which permits arbitrary Python execution, not just limited PyQGIS operations. Any local process able to reach 127.0.0.1 can read/write files, run OS commands, access network resources through Python, and fully compromise the QGIS process and its data.
t0 = time.time()
try:
with redirect_stdout(buf):
exec(code, g) # noqa: S102 - 显式开启的逃生舱口
except Exception as e:
return self._send(err(e, traceback=traceback.format_exc()[-1500:]))
return self._send(ok({"stdout": buf.getvalue(),
The entire skill description and user-facing instructions are written in Chinese, with no indication that users may choose another language or that the skill is intended only for a Chinese-language audience. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
任意能发 HTTP 请求的智能体:无需任何客户端,直接 curl:
curl -s http://127.0.0.1:8767/health
curl -s "http://127.0.0.1:8767/search?q=buffer"
curl -s -X POST http://127.0.0.1:8767/call -H "Content-Type: application/json" \
-d '{"name":"native:buffer","arguments":{"INPUT":"C:/data/roads.shp","DISTANCE":500,"OUTPUT":"C:/out/roads_buf.gpkg"}}'
The README explicitly advertises a /pyqgis endpoint that can execute arbitrary PyQGIS code, and the safety warning is brief and easy to overlook relative to the powerful capability being exposed. In an agent-integrated context, even localhost-only execution can let a prompt-driven client run arbitrary local code, access files, or modify projects if the endpoint is enabled, so the documentation should make the risk much more prominent.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Probe whether the service is up:
curl -s http://127.0.0.1:8767/health
# {"status":"ok","server":"qgis-agent-server","version":"1.0","algorithms":1000,"providers":6,...}
Although the endpoint is localhost, the skill instructs the agent to send project metadata and filesystem paths over HTTP to a local service and to open/save project files on request. In this context, localhost acts as an inter-process trust boundary; a compromised or overly permissive local server could expose sensitive geospatial data, layer metadata, and enable unauthorized file access or modification.
# Inspect the current project and layers (field list, feature count, CRS)
curl -s http://127.0.0.1:8767/project
# Open / save a project
curl -s -X POST http://127.0.0.1:8767/project/open -H "Content-Type: application/json" -d '{"path":"C:/data/demo.qgz"}'
This is the Chinese-language duplicate of the same localhost project-inspection and open/save workflow. The risk is not classic external transmission, but disclosure of project structure, CRS, field lists, and file paths to a separate local HTTP service plus potential unauthorized file operations if the service is misconfigured or abused.
# 查看当前工程与图层(含字段列表、要素数、CRS)
curl -s http://127.0.0.1:8767/project
# 打开 / 保存工程
curl -s -X POST http://127.0.0.1:8767/project/open -H "Content-Type: application/json" -d '{"path":"C:/data/demo.qgz"}'
The entire API documentation is written in Chinese, with no indication that language selection is optional or that the skill is intentionally limited to a Chinese-speaking audience. This can constitute a language/locale policy violation when a specific language is imposed without user opt-in or documented justification.
The documentation describes a /pyqgis endpoint that can be enabled to run PyQGIS code, but it does not explicitly warn that this is effectively arbitrary code execution inside the QGIS host process. Even though it is disabled by default and bound to 127.0.0.1, local exposure still creates substantial risk because any local user, malware, browser-assisted localhost attack, or chained agent/tool misuse could execute code once the flag is enabled.
Natural-language policy issues apply to all file types, including markdown. This file forces a specific language for all headings, instructions, and examples, with no opt-in, alternate locale, or justification that the skill is region- or language-specific.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
curl -s -X POST http://127.0.0.1:8767/call -H "Content-Type: application/json" -d '{
"name": "native:buffer",
"arguments": {"INPUT":"D:/data/roads.shp","DISTANCE":500,"SEGMENTS":5,
"END_CAP_STYLE":0,"JOIN_STYLE":0,"OUTPUT":"D:/out/roads_buf_500m.gpkg"}
The module docstring presents the service description, API overview, and safety notes entirely in Chinese, and the runtime startup messages are also emitted in Chinese. This imposes a specific language on users and operators without any documented opt-in, fallback, or locale selection, which matches the language/locale policy violation criteria.
Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.
g = {"QgsApplication": QgsApplication, "QgsProject": QgsProject,
"QgsVectorLayer": QgsVectorLayer, "QgsRectangle": QgsRectangle,
"QgsWkbTypes": QgsWkbTypes, "Processing": Processing, "registry": REGISTRY,
"processing": __import__("processing")}
t0 = time.time()
try:
with redirect_stdout(buf):
The response returned by api_docs() contains user-facing endpoint descriptions entirely in Chinese. Because these strings are surfaced to clients programmatically and there is no mechanism to request another language or opt in to Chinese, the server enforces a locale choice.
The example instructs the agent to save results as a GeoPackage and render a preview image, which can modify or create user files. The nearby example text does not warn that the workflow may write output files or encourage confirmation before choosing output paths, which is relevant for markdown-based skill descriptions.
The /call endpoint allows caller-controlled output paths, which means the service can write files to locations selected by the requester. Without a clear warning and path restrictions, users may underestimate the risk of overwriting files, planting data in sensitive directories, or abusing the service as a filesystem write primitive through agent-driven or local requests.
This markdown file contains many example commands that create output files such as .gpkg, .tif, and .png, which can overwrite existing files or alter user data locations. The document provides usage examples but does not include a user-facing warning about file creation/overwrite effects or the need to verify output paths before running them.