fix: prevent extension command shadowing#1994
Conversation
There was a problem hiding this comment.
Pull request overview
This PR closes a security/reliability gap in the extension system by adding install-time validation that prevents extensions from shadowing core Spec Kit commands or colliding with commands/aliases from other installed extensions.
Changes:
- Add install-time validation in
ExtensionManagerto reject core-namespace shadowing, invalid alias shapes, and collisions with installed extensions. - Expand extension installation tests to cover core-namespace conflicts, malformed aliases, and cross-extension collisions.
- Update extension docs/templates/examples to use namespaced aliases instead of legacy short aliases.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/extensions.py |
Introduces core-command reservation and install-time conflict validation for command/alias names. |
tests/test_extensions.py |
Adds/updates tests asserting the new validation behavior and updated alias naming. |
extensions/template/extension.yml |
Updates template manifest example to use namespaced aliases. |
extensions/RFC-EXTENSION-SYSTEM.md |
Updates examples away from short aliases; needs wording alignment for “backward compatibility”. |
extensions/EXTENSION-USER-GUIDE.md |
Updates user-facing examples to show namespaced alias usage. |
extensions/EXTENSION-DEVELOPMENT-GUIDE.md |
Updates developer guidance to show namespaced alias usage. |
extensions/EXTENSION-API-REFERENCE.md |
Updates manifest reference to note alias restrictions (needs to reflect all new constraints). |
Comments suppressed due to low confidence (1)
src/specify_cli/extensions.py:518
- The install-time validation only checks that names match the
speckit.<namespace>.<command>pattern, but it doesn’t enforce that<namespace>matchesmanifest.id. As written, an extension could publish commands/aliases under another extension’s namespace (namespace squatting/impersonation), and also block the real extension from installing later. Consider rejecting command/alias names where the parsed namespace (match group 1) is not exactlymanifest.id.
namespace = match.group(1)
if namespace in CORE_COMMAND_NAMES:
raise ValidationError(
f"{kind.capitalize()} '{name}' conflicts with core command namespace '{namespace}'"
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback. If not applicable, please explain why
Addressed in I fixed all 3 Copilot items:
Validation:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@afurm This does not prevent presets from overriding commands? |
Correct. This change does not prevent presets from overriding commands. The new validation only runs in the extension install path ( So the intent here is narrower: prevent extensions from claiming core-command namespaces or another extension’s namespace. It does not change the existing preset override mechanism. |
|
Thank you! |
|
Thank you!!! |
Description
Fixes #1963.
This PR hardens extension installation so extensions cannot silently shadow core Spec Kit commands or collide with commands from other installed extensions.
Specifically, it:
speckit.*commandsspeckit.{extension}.{command}This is needed to close a security and reliability gap where an extension could overwrite core command files or another extension's command files during installation.
Testing
Ran
uv run specify --helpsuccessfully and confirmedextensioncommands are presentRan the full test suite successfully with
uv sync --extra test && uv run pytest(876 passed)Also ran
uv run --extra test pytest tests/test_extensions.pywhile developing the fixTested locally with
uv run specify --helpRan existing tests with
uv sync --extra test && uv run pytestTested with a sample project (not applicable for this change)
AI Disclosure
Used Codex to inspect the issue, implement the validation changes, update tests/docs, and run verification commands.