fix(security): chặn mở khoá Sandbox Security bằng ô trống
DEFAULT_CONFIG ship agent_security.sandbox_pw = "" kể từ commit3827552, và cấu hình đưa tới dialog luôn được deep-merge với defaults đó. Nghĩa là trên mọi bản cài không đặt COWORK_SANDBOX_PASSWORD, mật khẩu đã lưu là chuỗi rỗng — và phép so `pw == self._sandbox_pw` nhận luôn ô nhập trống. Bấm Unlock với ô trống là mở được toàn bộ nhóm Sandbox Security. Commit3827552chỉ sửa config.py nên bỏ sót bản sao thứ hai của literal nằm trong ui/settings_dialog.py, và chính nó tạo ra lỗ hổng rỗng này. Sửa: - gỡ literal credential khỏi mã nguồn (nó vốn là code chết: deep-merge làm tham số mặc định của .get() không bao giờ chạy); - chặn rỗng trước khi so, theo đúng mẫu mà MS365 unlock đã dùng; - so sánh timing-safe trên BYTES, không trên str — secrets.compare_digest ném TypeError với str ngoài ASCII, mà app mặc định tiếng Việt và phục vụ khách Nhật nên mật khẩu có dấu là input bình thường; - chưa đặt mật khẩu thì báo đúng trạng thái đó, không báo "sai mật khẩu" — người dùng sẽ gõ lại mãi một thứ không tồn tại. Root cause: ui/settings_dialog.py:104 (bản cũ) Test: tests/ui/test_sandbox_unlock_security.py LƯU Ý CHO REVIEWER: literal cũ vẫn nằm trong 6 commit của Git history. Gỡ ở đây không gỡ khỏi lịch sử — cần xoay credential trên các máy còn giá trị đó trong config.json. Không rewrite history (SECURITY.md). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -153,6 +153,7 @@ STRINGS: Dict[str, Dict[str, str]] = {
|
||||
"settings.group.general": {"en": "General", "ja": "一般", "vi": "Chung"},
|
||||
"settings.group.provider": {"en": "AI Provider", "ja": "AI プロバイダー", "vi": "Nhà cung cấp AI"},
|
||||
"settings.group.parameter": {"en": "Parameter", "ja": "Parameter", "vi": "Parameter"},
|
||||
"settings.group.about": {"en": "About", "ja": "このアプリについて", "vi": "Giới thiệu"},
|
||||
"settings.param_section_pricing": {
|
||||
"en": "Model pricing", "ja": "モデル価格", "vi": "Bảng giá model"},
|
||||
"settings.pricing_url_label": {
|
||||
@@ -328,6 +329,27 @@ STRINGS: Dict[str, Dict[str, str]] = {
|
||||
"settings.group.sandbox": {
|
||||
"en": "Sandbox Security Layer", "ja": "サンドボックス セキュリティ層",
|
||||
"vi": "Sandbox Security Layer"},
|
||||
"settings.sec_enabled": {
|
||||
"en": "Enable Agent Security (command validation)",
|
||||
"ja": "エージェントセキュリティを有効化(コマンド検証)",
|
||||
"vi": "Bật Agent Security (kiểm tra lệnh)"},
|
||||
"settings.sec_enabled_tooltip": {
|
||||
"en": "Turn the whole Agent Security layer on or off.",
|
||||
"ja": "エージェントセキュリティ層全体をオン/オフします。",
|
||||
"vi": "Bật/tắt toàn bộ tầng Agent Security."},
|
||||
"settings.ai_check": {
|
||||
"en": "AI check commands", "ja": "AIによるコマンド検査",
|
||||
"vi": "AI kiểm tra lệnh"},
|
||||
"settings.ai_check_tooltip": {
|
||||
"en": "Let the control agent review a command with AI before it runs.",
|
||||
"ja": "実行前に制御エージェントがAIでコマンドを確認します。",
|
||||
"vi": "Cho control-agent dùng AI xét lệnh trước khi chạy."},
|
||||
"settings.sandbox_pw_unset_title": {
|
||||
"en": "Sandbox Security", "ja": "サンドボックスセキュリティ", "vi": "Bảo mật Sandbox"},
|
||||
"settings.sandbox_pw_unset_body": {
|
||||
"en": "No sandbox password is set yet, so these settings stay locked. Set COWORK_SANDBOX_PASSWORD, or ask your administrator.",
|
||||
"ja": "サンドボックスのパスワードが未設定のため、この設定はロックされたままです。COWORK_SANDBOX_PASSWORD を設定するか、管理者にお問い合わせください。",
|
||||
"vi": "Chưa đặt mật khẩu sandbox nên nhóm thiết lập này vẫn khóa. Hãy đặt COWORK_SANDBOX_PASSWORD, hoặc liên hệ quản trị viên."},
|
||||
"settings.sandbox_confirm_commands": {
|
||||
"en": "Confirm before Cowork runs a command",
|
||||
"ja": "Cowork がコマンドを実行する前に確認する",
|
||||
|
||||
Reference in New Issue
Block a user