spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

Check settings files and --settings for a permission modeBrowse files
The security check looked for defaultMode only in an inline 'settings'
input. Also read the file a 'settings' input or a --settings flag in
claude_args names, when it is inside the repository, and fail if it sets
a permission mode.
Claude authored 25 days ago parent b1922f2 · commit a83eb8099fd9
1 changed file+32 -5compared with b1922f2
M.github/scripts/check_workflow_hardening.py
@@ -141,14 +141,41 @@
141141 f"'claude_args' has '--permission-mode {mode}'. "
142142 "Change it to '--permission-mode auto'"
143143 )
144- if "defaultMode" in str(inputs.get("settings", "")):
145- return (
146- "remove 'defaultMode' from the step's 'settings': "
147- "'settings' must not set a permission mode"
148- )
144+ settings = [("the step's 'settings'", inputs.get("settings", ""))]
145+ settings += [
146+ ("'--settings' in 'claude_args'", args[index + 1])
147+ for index, arg in enumerate(args)
148+ if arg == "--settings" and index + 1 < len(args)
149+ ]
150+ settings += [
151+ ("'--settings' in 'claude_args'", arg.split("=", 1)[1])
152+ for arg in args
153+ if arg.startswith("--settings=")
154+ ]
155+ for where, value in settings:
156+ if "defaultMode" in settings_text(value):
157+ return f"remove 'defaultMode' from {where}: settings must not set a permission mode"
149158 return None
150159
151160
161+def settings_text(value) -> str:
162+ """The settings JSON a 'settings' value stands for: the value itself, or the contents of
163+ the file it names when it is a path inside the repository."""
164+ text = str(value or "").strip()
165+ if not text or text.startswith("{"):
166+ return text
167+ path = pathlib.Path(text)
168+ root = pathlib.Path.cwd().resolve()
169+ try:
170+ resolved = path.resolve()
171+ resolved.relative_to(root)
172+ except (OSError, ValueError):
173+ return text
174+ if resolved.is_file():
175+ return resolved.read_text(encoding="utf-8", errors="replace")
176+ return text
177+
178+
152179 def check_job(file_name: str, job_id: str, job: dict) -> list[str]:
153180 key = f"{file_name}:{job_id}"
154181 where = f".github/workflows/{file_name}: job '{job_id}'"