T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/outdoor_monitoring.py:40- Finding
Workspace-wide fallback identity permits cross-user access to monitoring reports
- Content
View full analysis
Vulnerability Details
File Location:
scripts/outdoor_monitoring.py:40, 55-60;skills/smyx_common/scripts/config.py:153-160;skills/smyx_common/scripts/util.py:414-471;skills/smyx_analysis/scripts/skill.py:154-160
Vulnerability Type: Broken user isolation and improper authorization context
Risk Level: HighVulnerable Code
scripts/outdoor_monitoring.py:40, 55-60:python parser.add_argument("--open-id", required=False, help=argparse.SUPPRESS) ... # Initialize the internal user identity. OpenIdUtil.resolve_current_open_id( args.open_id, use_current=bool(args.open_id) ) if args.list: open_id = ConstantEnum.CURRENT__OPEN_ID result = show_analyze_list(open_id) print(result) exit(0)skills/smyx_common/scripts/config.py:153-160:python openclaw_sender_open_id = os.environ.get("OPENCLAW_SENDER_OPEN_ID") openclaw_sender_username = os.environ.get("OPENCLAW_SENDER_USERNAME") feishu_open_id = os.environ.get("FEISHU_OPEN_ID") if openclaw_sender_open_id: cls.CURRENT__OPEN_ID = openclaw_sender_open_id if openclaw_sender_username: cls.CURRENT__USER_NAME = openclaw_sender_usernameskills/smyx_common/scripts/util.py:414-471:python @classmethod def get_api_key_file_open_id(cls): """Read the internal identity from data/smyx-api-key.txt.""" api_key_path = os.path.join( cls.get_workspace_data_dir(), "smyx-api-key.txt" ) try: if not os.path.exists(api_key_path): return None with open(api_key_path, "r", encoding="utf-8") as f: value = f.read().strip() return value or None except Exception as e: CommonUtil.trace_exception_stack(e) return None @classmethod def get_or_create_default_open_id(cls): from .dao import UserDao, User import uuid user_dao = UserDao() user = user_dao.get_fir ...[truncated 4878 chars]- Remediation
View remediation
Remediation Suggestions
-
Preserve the authenticated upstream identity for every request. When
OPENCLAW_SENDER_OPEN_IDor another trusted sender identity has been initialized, call identity resolution withuse_current=True. -
Eliminate workspace-global fallback identities in multi-user deployments. If no authenticated identity is available, reject history retrieval and sensitive analysis submission rather than silently assigning all callers to one account.
-
Pass the resolved identity explicitly through the complete call chain instead of relying on mutable process-global fields:
python resolved_open_id = OpenIdUtil.resolve_current_open_id( args.open_id, use_current=True ) result = show_analyze_list(resolved_open_id) -
Do not discard
open_idinget_output_analysis_list(). Bind the authenticated principal to the server-side request and enforce report ownership on the remote API. Client-supplied identity fields must not be treated as proof of identity. -
Remove the hidden
--open-idoverride from untrusted entry points, or require a trusted, authenticated invocation context before accepting it. Arbitrary identity selection must not alter the account used for authorization. -
Store tokens and account state per authenticated user or tenant rather than in a workspace-wide default database record. Include tenant and user identifiers in database lookup keys.
-
Add integration tests with two distinct upstream users to verify that:
- Each analysis is associated with the correct user.
- Each history query returns only that user’s reports.
- Missing identity fails closed.
- A caller cannot select another user through
--open-id.
-
Review and migrate reports already associated with the shared fallback account. Existing mixed records should be reassigned where ownership can be established or restricted until ownership is resolved.
-
