Security checks for vulnerabilities and agentic risk
Overview
This appears to be a real DuckDB/Hugging Face analytics skill, but its preview server and helper expose powerful SQL, local data, file, network, and token behavior without enough scoping or safety controls.
Install only if you are comfortable reviewing and controlling a prototype-grade local data tool. Do not expose the preview server to a network; prefer running it only on loopback, avoid sensitive databases, do not use the arbitrary SQL endpoint with untrusted input, keep HF tokens out of committed .env files, and regenerate lockfiles from a trusted registry before using the native dependencies in production.
Back`);
}
} else {
res.statusCode = 404;
res.end('Not found');
}
server.listen(PORT, () => {
console.log(`Preview server running at http://localhost:${PORT}`);
```
The query is passed to the following unrestricted execution method in `lib/duckdb-helper.js:158-163`:
```js
async query(sql) {
const conn = await this.connect();
const result = await conn.run(sql);
const rows = await result.getRows();
return rows;
}
```
### Technical Analysis
The `/query` endpoint takes the complete SQL statement from the `sql` URL parameter and sends it directly to DuckDB. There is no authentication, authorization, statement allowlist, read-only mode, multi-statement rejection, or filesystem/network restriction.
Although the console message describes the service as being available at `localhost`, `server.listen(PORT)` does not explicitly bind to a loopback address. Depending on the platform, it normally listens on all available IPv4 or IPv6 interfaces. The service may consequently be reachable by other systems on the local network or through container, virtual-machine, or port-forwarding configurations.
DuckDB SQL is not limited to ordinary `SELECT` queries. Subject to the process permissions and DuckDB configuration, it can modify or delete database objects, read supported local files, export data to files, load installed extensions, an
...[truncated 1815 chars]
Remediation
View remediation
{
console.log(`Preview server running at http://127.0.0.1:${PORT}`);
});
```
2. Require strong authentication before permitting any database operation if non-loopback access is required.
3. Remove the arbitrary SQL endpoint from production builds. Replace it with narrowly scoped operations using validated table and column identifiers.
4. Open the database in read-only mode for preview use where possible.
5. If custom queries are required, parse and enforce a strict single-statement, read-only policy. Reject commands such as `COPY`, `ATTACH`, `INSTALL`, `LOAD`, `CREATE`, `DROP`, `DELETE`, `UPDATE`, and external file-reading functions.
6. Disable DuckDB external access and extension installation in the preview process unless explicitly required.
7. Use POST requests for stateful operations and implement CSRF tokens, strict Origin validation, and SameSite cookies.
8. Add request-size, query-time, memory, and concurrency limits to reduce denial-of-service risk.
]]>
T09 · Insecure Skill Coding Practices
Error
Location
lib/duckdb-helper.js:89
Finding
SQL Injection Through Interpolated Identifiers and File Paths
Content
View full analysis
Remediation
View remediation
T09 · Insecure Skill Coding Practices
Error
Location
examples/preview-server.js:21
Finding
Stored and Reflected HTML Injection in the Preview Interface
Back`);
}
```
### Technical Analysis
The application generates HTML by concatenating untrusted values directly into markup. The affected values include:
- Database table names.
- The `name` URL parameter.
- Database schema information.
- Database row values.
- Arbitrary query results.
- DuckDB error messages.
- The resolved database path.
`JSON.stringify()` doe
...[truncated 1985 chars]
Remediation
View remediation
', '>')
.replaceAll('"', '"')
.replaceAll("'", ''');
}
```
2. URL-encode query parameters with `encodeURIComponent()` rather than inserting them directly into `href` attributes.
3. Prefer returning database results as `application/json` and rendering them with safe DOM APIs such as `textContent`.
4. Use a maintained templating engine with automatic escaping enabled.
5. Never assign untrusted values to `innerHTML` in any future client-side interface.
6. Add a restrictive Content Security Policy, for example one that disallows inline scripts and limits network destinations.
7. Add headers including `X-Content-Type-Options: nosniff`, an appropriate `Referrer-Policy`, and frame restrictions.
8. Add tests containing ``, quotes, angle brackets, event-handler attributes, and script elements in table names, values, and error-producing input.
]]>
T08 · Insecure Dependencies
Warning
Location
package-lock.json:14
Finding
Native Dependencies Retrieved from a Third-Party npm Mirror
Suggesting that users store HF_TOKEN in a .env file next to the database encourages colocating credentials with project data in a way that is easy to leak through backups, source control, packaging, or accidental sharing. Because the token grants access to gated Hugging Face resources, exposure could allow unauthorized dataset access and account misuse.
Content
Scanner excerpt · SKILL.md (reported line 46)May include surrounding context.
bash
export HF_TOKEN=hf_your_token
# or put in .env next to data.duckdb
In code:
Credential Access
High
Category
Privilege Escalation
Confidence
95% confidence
Finding
The code is explicitly designed to discover and consume credentials from ambient sources (.env and environment variables), which is a credential-access behavior. In an agent-integrated tool, this can expose private tokens to unintended operations and broadens the blast radius if the helper is invoked on attacker-influenced inputs.
Content
Scanner excerpt · lib/duckdb-helper.js (reported line 47)May include surrounding context.
js
}
/**
* Try to load HF token from environment or .env
*/
async autoLoadHFToken() {
let token = process.env.HF_TOKEN || process.env.HUGGINGFACE_TOKEN;
Credential Access
High
Category
Privilege Escalation
Confidence
95% confidence
Finding
Reading a local .env file to extract HF_TOKEN is credential harvesting from local developer secrets, even if intended for convenience. This is especially risky in reusable agent skills because the caller may not expect the library to inspect nearby secret files at all.
Content
Scanner excerpt · lib/duckdb-helper.js (reported line 52)May include surrounding context.
js
async autoLoadHFToken() {
let token = process.env.HF_TOKEN || process.env.HUGGINGFACE_TOKEN;
if (!token) {
// Try .env file in project
const envPath = path.join(path.dirname(this.dbPath), '.env');
if (fs.existsSync(envPath)) {
const envContent = fs.readFileSync(envPath, 'utf8');
Credential Access
High
Category
Privilege Escalation
Confidence
95% confidence
Finding
Constructing a path to a neighboring .env file and reading it for tokens demonstrates direct access to local secret material. In the context of an analytics helper, this capability is more dangerous because it is not necessary for basic local file import/query operations and could be abused indirectly through agent workflows.
Content
Scanner excerpt · lib/duckdb-helper.js (reported line 53)May include surrounding context.
js
let token = process.env.HF_TOKEN || process.env.HUGGINGFACE_TOKEN;
if (!token) {
// Try .env file in project
const envPath = path.join(path.dirname(this.dbPath), '.env');
if (fs.existsSync(envPath)) {
const envContent = fs.readFileSync(envPath, 'utf8');
const match = envContent.match(/HF_TOKEN=([^\s]+)/);
Credential Access
High
Category
Privilege Escalation
Confidence
72% confidence
Finding
The documentation suggests placing an HF access token in a .env file next to data.duckdb, but does not warn about file permissions, accidental commits, or leakage through packaged desktop apps and support bundles. Since the token may grant access to gated/private datasets, poor secret-handling guidance can lead to credential exposure.
Content
Scanner excerpt · skills/xiaoqianran-duck/SKILL.md (reported line 46)May include surrounding context.
bash
export HF_TOKEN=hf_your_token
# or put in .env next to data.duckdb
In code:
Credential Access
High
Category
Privilege Escalation
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Content
Scanner excerpt · examples/hf-import.js (reported line 12)May include surrounding context.
js
// Optional: set HF token for gated datasets
// await helper.setHFTtoken('hf_your_token_here');
// or put HF_TOKEN=... in .env next to data.duckdb
const hfPath = 'hf://datasets/datasets-examples/doc-formats-parquet-1/data/train-00000-of-00001.parquet';
Credential Access
High
Category
Privilege Escalation
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Content
Scanner excerpt · skills/xiaoqianran-duck/examples/hf-import.js (reported line 12)May include surrounding context.
js
// Optional: set HF token for gated datasets
// await helper.setHFTtoken('hf_your_token_here');
// or put HF_TOKEN=... in .env next to data.duckdb
const hfPath = 'hf://datasets/datasets-examples/doc-formats-parquet-1/data/train-00000-of-00001.parquet';
Credential Access
High
Category
Privilege Escalation
Confidence
93% confidence
Finding
The code is explicitly designed to access credentials by reading Hugging Face tokens from environment variables and nearby configuration files. In an agent skill, automatic credential harvesting from the host environment is security-relevant because it can appropriate secrets without an explicit request from the user at the moment of use.
Content
Scanner excerpt · skills/xiaoqianran-duck/lib/duckdb-helper.js (reported line 47)May include surrounding context.
js
}
/**
* Try to load HF token from environment or .env
*/
async autoLoadHFToken() {
let token = process.env.HF_TOKEN || process.env.HUGGINGFACE_TOKEN;
Credential Access
High
Category
Privilege Escalation
Confidence
95% confidence
Finding
Reading a local .env file to extract HF_TOKEN broadens credential access beyond process-provided configuration and may pull secrets from the project directory unexpectedly. In a skill ecosystem, this increases the chance that unrelated developer secrets are used or exposed through authenticated remote operations.
Content
Scanner excerpt · skills/xiaoqianran-duck/lib/duckdb-helper.js (reported line 52)May include surrounding context.
js
async autoLoadHFToken() {
let token = process.env.HF_TOKEN || process.env.HUGGINGFACE_TOKEN;
if (!token) {
// Try .env file in project
const envPath = path.join(path.dirname(this.dbPath), '.env');
if (fs.existsSync(envPath)) {
const envContent = fs.readFileSync(envPath, 'utf8');
Credential Access
High
Category
Privilege Escalation
Confidence
95% confidence
Finding
The presence of hardcoded logic targeting '.env' files indicates intentional credential collection behavior from local filesystem context. While likely added for convenience, this is dangerous in agent-driven environments because it silently expands secret access and can cause authenticated actions under user credentials without transparent approval.
Content
Scanner excerpt · skills/xiaoqianran-duck/lib/duckdb-helper.js (reported line 53)May include surrounding context.
js
let token = process.env.HF_TOKEN || process.env.HUGGINGFACE_TOKEN;
if (!token) {
// Try .env file in project
const envPath = path.join(path.dirname(this.dbPath), '.env');
if (fs.existsSync(envPath)) {
const envContent = fs.readFileSync(envPath, 'utf8');
const match = envContent.match(/HF_TOKEN=([^\s]+)/);
Undeclared Tool Scope
Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill documents environment-variable use for HF_TOKEN and operational capabilities, but it does not declare any tool scope or permissions boundary in the skill metadata. In an agent setting, this increases the chance that the skill can access sensitive environment data without explicit user awareness or least-privilege constraints.
Content
No source excerpt is available for this finding.
Rp1
Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
Using npx xiaoqianran-duck without pinning a specific version causes execution of whatever package version is current at install time. This creates a supply-chain risk where a compromised or malicious future release could be fetched and executed unexpectedly.
Content
No source excerpt is available for this finding.
Rp1
Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
Using npx xiaoqianran-duck without pinning a specific version causes execution of whatever package version is current at install time. This creates a supply-chain risk where a compromised or malicious future release could be fetched and executed unexpectedly.
Content
No source excerpt is available for this finding.
Rp1
Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
Using npx xiaoqianran-duck without pinning a specific version causes execution of whatever package version is current at install time. This creates a supply-chain risk where a compromised or malicious future release could be fetched and executed unexpectedly.
Content
No source excerpt is available for this finding.
Missing User Warnings
Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding
The skill instructs users to place an HF access token in an environment variable or .env file but provides no warning about credential sensitivity, accidental commit risk, file permissions, or secret-handling hygiene. This is especially relevant because the tool accesses remote gated datasets and normalizes token use as part of routine workflow.
Content
No source excerpt is available for this finding.
Missing User Warnings
Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding
The documented preview server exposes local table browsing and query execution over HTTP, but the skill does not warn users about binding scope, network exposure, or the risk of serving sensitive local data. In a desktop data tool, this can unintentionally leak imported files or query results to other local users or network peers.
Content
No source excerpt is available for this finding.
Description-Behavior Mismatch
Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding
The preview server accepts a user-supplied sql parameter and passes it directly to helper.query(sql) with no validation, authentication, or restriction to read-only statements. Even though this is described as a local preview tool, arbitrary SQL can expose sensitive local data, modify or delete database contents, and potentially access external resources depending on DuckDB features enabled in the environment.
Content
No source excerpt is available for this finding.
Context-Inappropriate Capability
Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding
The helper automatically reads Hugging Face credentials from process environment variables and a nearby .env file, which expands its access beyond explicit user-provided dataset paths. In a data-import utility, silently harvesting credentials increases the chance of unintended credential use and accidental access to private remote resources.
Content
No source excerpt is available for this finding.
Missing User Warnings
Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding
Automatic token loading from environment variables or .env files happens without any user-facing disclosure, so users may unknowingly authorize authenticated network access. This weakens transparency and can cause private credentials to be used in contexts the operator did not intend.
Content
No source excerpt is available for this finding.
Description-Behavior Mismatch
Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding
The manifest emphasizes importing and querying analytical data, but this helper performs persistent mutations via CREATE OR REPLACE TABLE during imports and writes files during export. Those write-side behaviors are substantive operations, not merely read-only querying, and the description does not make that persistence/export behavior explicit.
Content
No source excerpt is available for this finding.
Missing User Warnings
Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding
Importing from hf:// triggers network access and may automatically use discovered Hugging Face credentials, but the helper provides no warning or consent boundary. In an agent setting, this can surprise users by contacting external services and accessing private datasets.
Content
No source excerpt is available for this finding.
Description-Behavior Mismatch
Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding
The helper can write query results to arbitrary filesystem paths without restriction or confirmation. If exposed through higher-level agent actions with untrusted input, this could overwrite files or facilitate unintended local data exfiltration to attacker-chosen locations.
Content
No source excerpt is available for this finding.
Description-Behavior Mismatch
Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding
The backend performs network access to Hugging Face and creates a local file as part of normal startup/example flow, even though the skill is described as a local analytics backend. This expands behavior beyond user-requested local analysis, can leak network metadata or trigger unapproved outbound connections, and may surprise applications embedding this backend such as Tauri/Electron apps.
Content
No source excerpt is available for this finding.
Context-Inappropriate Capability
Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding
Automatically installing and loading the httpfs extension on startup enables network-capable functionality without any user-driven need or consent. In an embedded desktop-app context, this increases attack surface, may trigger downloads or extension installation side effects, and makes a supposedly local tool perform remote-capable operations by default.
Content
No source excerpt is available for this finding.
Rp1
Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.