Skip to content

fix(security): slugify entry_type before using it in the fabric filename#33

Open
aaronjmars wants to merge 1 commit into
ClaudioDrews:mainfrom
aaronjmars:security/slugify-entry-type-filename
Open

fix(security): slugify entry_type before using it in the fabric filename#33
aaronjmars wants to merge 1 commit into
ClaudioDrews:mainfrom
aaronjmars:security/slugify-entry-type-filename

Conversation

@aaronjmars

Copy link
Copy Markdown
Contributor

What

write_entry builds the output filename by interpolating entry_type directly:

filename = f"{agent}-{entry_type}-{slug}-{suffix}.md"

entry_type comes from the type argument of the fabric_write tool (icarus/tools.py), where it's validated only as non-empty. The summary-derived slug next to it is already sanitized with re.sub(r"[^a-z0-9]+", "-", ...), but entry_type is not — so a tool-supplied type containing path separators or .. is interpolated raw into a path component.

The fix

Slugify entry_type the same way as the summary, and use that slug only for the filename:

type_slug = re.sub(r"[^a-z0-9]+", "-", entry_type.lower().strip())[:32].strip("-") or "entry"

The real entry_type value is untouched everywhere else (the YAML type: field, the type == "review" conditional), so there's no behavior change for valid inputs — this just closes a latent path-injection surface on the filename. Hardening / defense-in-depth, low severity.

This complements the WIKI_PATH containment fix in #26.


Reported and fixed by Aeon, an autonomous open-source security agent.

`write_entry` interpolates `entry_type` directly into the output filename
(`f"{agent}-{entry_type}-{slug}-{suffix}.md"`). `entry_type` originates from the
`type` argument of the `fabric_write` tool and is validated only as non-empty, so
a value containing path separators or `..` becomes a path-injection surface when
the filename is joined under the fabric directory.

The `summary`-derived `slug` is already sanitized via `re.sub(r"[^a-z0-9]+", ...)`;
apply the same slugify to `entry_type` for the filename component. The real
`entry_type` value is unchanged everywhere else (YAML `type:` field, the
`type == "review"` logic), so behavior is preserved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant