Skip to content

feat(security): prevent write_file overwriting non-empty files#4026

Open
1105623876 wants to merge 3 commits intoagentscope-ai:mainfrom
1105623876:feat/write-file-overwrite-guard
Open

feat(security): prevent write_file overwriting non-empty files#4026
1105623876 wants to merge 3 commits intoagentscope-ai:mainfrom
1105623876:feat/write-file-overwrite-guard

Conversation

@1105623876
Copy link
Copy Markdown

Description

This PR adds a file-state-aware tool guard for write_file.

write_file is intended for creating new files or writing empty files, but using it on an existing non-empty file can
silently overwrite content. This PR adds WriteFileOverwriteGuardian, which blocks write_file when the target path
already exists as a non-empty regular file and guides the agent to use edit_file instead.

New files and existing empty files are still allowed.

The behavior is configurable through security.file_guard.prevent_write_file_overwrite, which defaults to true and
also respects the parent security.file_guard.enabled switch.

Related Issue: Fixes #4020

Security Considerations: This change strengthens tool-call safety by preventing accidental destructive overwrites
through write_file. The new guard is controlled by security.file_guard.prevent_write_file_overwrite and also
respects security.file_guard.enabled.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Refactoring

Component(s) Affected

  • Core / Backend (app, agents, config, providers, utils, local_models)
  • Console (frontend web UI)
  • Channels (DingTalk, Feishu, QQ, Discord, iMessage, etc.)
  • Skills
  • CLI
  • Documentation (website)
  • Tests
  • CI/CD
  • Scripts / Deploy

Checklist

  • I ran pre-commit run --all-files locally and it passes
  • If pre-commit auto-fixed files, I committed those changes and reran checks
  • I ran tests locally (pytest or as relevant) and they pass
  • Documentation updated (if needed)
  • Ready for review

For Channel Changes (DingTalk, Feishu, QQ, Console, etc.)

  • I ran ./scripts/check-channels.sh (or ./scripts/check-channels.sh --changed) and it passes
  • Contract test exists in tests/contract/channels/test_<channel>_contract.py (REQUIRED)
  • Contract test implements create_instance() with proper channel initialization
  • All 19 contract verification points pass (see tests/contract/channels/__init__.py)
  • Optional: Unit tests in tests/unit/channels/test_<channel>.py for complex internal logic

Testing

Tested the new guardian behavior with unit tests covering:

  • write_file allows new files.
  • write_file allows existing empty files.
  • write_file blocks existing non-empty files.
  • Other tools such as edit_file are not affected.
  • The new security.file_guard.prevent_write_file_overwrite switch disables this guard when set to false.
  • The default ToolGuardEngine registers the new guardian.

Also ran the full tests/unit/security suite.

Local Verification Evidence

$env:PYTHONPATH='src'
D:\.qwenpaw\venv\Scripts\python.exe -m pytest tests/unit/security/test_file_guardian.py
# 6 passed, 2 warnings in 1.32s

$env:PYTHONPATH='src'
D:\.qwenpaw\venv\Scripts\python.exe -m pytest tests/unit/security
# 23 passed, 2 warnings in 1.32s

pre-commit run --all-files was not run locally.

Warnings observed during pytest are due to the local environment not having pytest-asyncio installed, so pytest
reports unknown asyncio config options. The tested security cases passed.

Additional Notes

This PR does not extend custom_rules or security.file_guard.sensitive_files. The new guard is a filesystem-state check
rather than a regex rule or sensitive-path rule, so it is implemented as a separate guardian under the file guard
system.

@github-project-automation github-project-automation Bot moved this to Todo in QwenPaw May 4, 2026
@github-actions github-actions Bot added the first-time-contributor PR created by a first time contributor label May 4, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Welcome to QwenPaw! 🐾

Hi @1105623876, thank you for your first Pull Request! 🎉

🙌 Join Developer Community

Thanks so much for your contribution! We'd love to invite you to join the official QwenPaw developer group! You can find the Discord and DingTalk group links under the "Developer Community" section on our docs page:
https://qwenpaw.agentscope.io/docs/community

We truly appreciate your enthusiasm—and look forward to your future contributions! 😊

We'll review your PR soon.

@1105623876 1105623876 requested a deployment to maintainer-approved May 5, 2026 02:53 — with GitHub Actions Waiting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

first-time-contributor PR created by a first time contributor

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

[Feature]: :对 MEMORY/AGENTS/SOUL 文件强制只读(工具层限制 write_file)

1 participant