{"data":{"skill":{"slug":"googleworkspace-gws-sheets-append","name":"gws-sheets-append","icon":"📦","repo":"https://github.com/googleworkspace/cli/tree/main/skills/gws-sheets-append/","status":"approved","author":"googleworkspace","authorVersion":null,"skillstoreRevision":null},"audit":{"id":"42aac242-4592-49f6-8d6c-bb3a121256c9","skill_id":"36c52542-fb44-4f32-926b-4cc669c7f9ce","version":3,"content_hash":"fd364b87ac2136fb365b7e7f75d376f2","risk_level":"high","is_blocked":false,"safe_to_publish":false,"analysis_status":"ok","agent_auto_install_policy":"confirmation_required","manual_install_policy":"allowed","summary":"No prompt injection attempt was found in SKILL.md. Most static backtick findings are Markdown formatting, but the skill intentionally runs gws commands that append data to Google Sheets. The line 16 sibling-file prerequisite crosses the skill boundary and should be made package-safe.","remediation":[{"issue":"External write command can modify cloud spreadsheet data.","severity":"medium","suggestion":"Require explicit user confirmation that includes the spreadsheet ID, target range, and a brief value summary before running gws sheets +append."},{"issue":"The skill references a sibling path outside its package.","severity":"high","suggestion":"Package shared guidance with the skill or use a marketplace-supported include mechanism instead of ../ paths."},{"issue":"Caller-provided values can include sensitive information.","severity":"medium","suggestion":"Review values for secrets and personal data before appending, and reject untrusted spreadsheet IDs unless the user confirms ownership."}],"risk_factor_evidence":[{"factor":"external_commands","evidence":[{"file":"SKILL.md","line_end":16,"line_start":16},{"file":"SKILL.md","line_end":24,"line_start":22},{"file":"SKILL.md","line_end":30,"line_start":24},{"file":"SKILL.md","line_end":31,"line_start":30},{"file":"SKILL.md","line_end":32,"line_start":31},{"file":"SKILL.md","line_end":33,"line_start":32},{"file":"SKILL.md","line_end":33,"line_start":33},{"file":"SKILL.md","line_end":41,"line_start":37}]},{"factor":"filesystem","evidence":[{"file":"SKILL.md","line_end":16,"line_start":16},{"file":"SKILL.md","line_end":54,"line_start":54},{"file":"SKILL.md","line_end":55,"line_start":55}]}],"critical_findings":[],"high_findings":[{"title":"Path traversal sequence","locations":[{"file":"SKILL.md","line_end":16,"line_start":16}],"confidence":0.67,"description":"> **PREREQUISITE:** Read `../gws-shared/SKILL.md` for auth, global flags, and security rules. If mis","review_kind":"capability","source_category":"filesystem","source_severity":"high","confidence_reasoning":"Line 16 directs the agent to read ../gws-shared/SKILL.md, which crosses this skill package boundary. The target is fixed and likely benign, but the relative traversal is still a real filesystem access pattern."}],"medium_findings":[{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":16,"line_start":16}],"confidence":0.64,"description":"> **PREREQUISITE:** Read `../gws-shared/SKILL.md` for auth, global flags, and security rules. If mis","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"Line 16 tells the agent to run the gws CLI if shared skill guidance is missing. This is intended setup behavior, but it is still an external command with local side effects."},{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":24,"line_start":22}],"confidence":0.72,"description":"```bash","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"The usage block shows an intended gws command that appends data to a spreadsheet. It is not Ruby backtick execution, but executing it can modify a user Google Sheet."},{"title":"Ruby/shell backtick execution","locations":[{"file":"SKILL.md","line_end":41,"line_start":37}],"confidence":0.76,"description":"```bash","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"The example block contains gws sheets +append commands that write caller-provided values to Google Sheets. The commands are intended, but they can change cloud data if run without consent."},{"title":"Cloud Spreadsheet Write Can Leak Sensitive Data","locations":[{"file":"SKILL.md","line_end":40,"line_start":37},{"file":"SKILL.md","line_end":50,"line_start":49}],"confidence":0.86,"description":"The skill writes caller-provided values to a Google Sheet. Sensitive data can be exposed if the spreadsheet ID is untrusted or values are copied without review.","review_kind":"security","source_category":"semantic","source_severity":"medium","confidence_reasoning":"The examples append values to Google Sheets, and the skill explicitly labels it as a write command requiring confirmation. This confirms a real data disclosure risk when consent or destination validation is weak."}],"low_findings":[],"dangerous_patterns":[],"files_scanned":1,"total_lines":56,"audit_model":"codex","audited_at":"2026-07-05T15:41:51.172+00:00","created_at":"2026-07-05T16:55:58.870826+00:00","static_findings":[{"id":"external_commands:SKILL.md:16:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"> **PREREQUISITE:** Read `../gws-shared/SKILL.md` for auth, global flags, and security rules. If mis","category":"external_commands","line_end":16,"severity":"medium","line_start":16},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":24,"severity":"medium","line_start":22},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```","category":"external_commands","line_end":30,"severity":"medium","line_start":24},{"id":"external_commands:SKILL.md:30:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `--spreadsheet` | ✓ | — | Spreadsheet ID |","category":"external_commands","line_end":31,"severity":"medium","line_start":30},{"id":"external_commands:SKILL.md:31:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `--values` | — | — | Comma-separated values (simple strings) |","category":"external_commands","line_end":32,"severity":"medium","line_start":31},{"id":"external_commands:SKILL.md:32:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `--json-values` | — | — | JSON array of rows, e.g. '[[\"a\",\"b\"],[\"c\",\"d\"]]' |","category":"external_commands","line_end":33,"severity":"medium","line_start":32},{"id":"external_commands:SKILL.md:33:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"| `--range` | — | `A1` | Target range in A1 notation (e.g. 'Sheet2!A1') to select a specific tab |","category":"external_commands","line_end":33,"severity":"medium","line_start":33},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","file":"SKILL.md","pattern":"Ruby/shell backtick execution","snippet":"```bash","category":"external_commands","line_end":41,"severity":"medium","line_start":37},{"id":"filesystem:SKILL.md:16:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"> **PREREQUISITE:** Read `../gws-shared/SKILL.md` for auth, global flags, and security rules. If mis","category":"filesystem","line_end":16,"severity":"high","line_start":16},{"id":"filesystem:SKILL.md:54:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"- [gws-shared](../gws-shared/SKILL.md) — Global flags and auth","category":"filesystem","line_end":54,"severity":"high","line_start":54},{"id":"filesystem:SKILL.md:55:path-traversal-sequence","file":"SKILL.md","pattern":"Path traversal sequence","snippet":"- [gws-sheets](../gws-sheets/SKILL.md) — All read and write spreadsheets commands","category":"filesystem","line_end":55,"severity":"high","line_start":55}],"finding_verdicts":[{"id":"external_commands:SKILL.md:16:ruby-shell-backtick-execution","reason":"Line 16 tells the agent to run the gws CLI if shared skill guidance is missing. This is intended setup behavior, but it is still an external command with local side effects.","verdict":"confirmed","severity":"medium","confidence":0.64},{"id":"external_commands:SKILL.md:22:ruby-shell-backtick-execution","reason":"The usage block shows an intended gws command that appends data to a spreadsheet. It is not Ruby backtick execution, but executing it can modify a user Google Sheet.","verdict":"confirmed","severity":"medium","confidence":0.72},{"id":"external_commands:SKILL.md:24:ruby-shell-backtick-execution","reason":"The cited range starts at a Markdown code-fence close and continues into a flag table. It documents parameters and does not execute shell or Ruby code.","verdict":"false_positive","confidence":0.9},{"id":"external_commands:SKILL.md:30:ruby-shell-backtick-execution","reason":"Line 30 is a Markdown table entry for the --spreadsheet flag. The backticks are formatting only and do not create command execution.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:SKILL.md:31:ruby-shell-backtick-execution","reason":"Line 31 is a Markdown table entry for the --values flag. It is documentation for a CLI option, not executable code.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:SKILL.md:32:ruby-shell-backtick-execution","reason":"Line 32 documents the --json-values option and includes quoted example data. The Markdown backticks do not invoke a shell.","verdict":"false_positive","confidence":0.93},{"id":"external_commands:SKILL.md:33:ruby-shell-backtick-execution","reason":"Line 33 documents the --range flag in a Markdown table. There is no dynamic command construction or backtick execution.","verdict":"false_positive","confidence":0.94},{"id":"external_commands:SKILL.md:37:ruby-shell-backtick-execution","reason":"The example block contains gws sheets +append commands that write caller-provided values to Google Sheets. The commands are intended, but they can change cloud data if run without consent.","verdict":"confirmed","severity":"medium","confidence":0.76},{"id":"filesystem:SKILL.md:16:path-traversal-sequence","reason":"Line 16 directs the agent to read ../gws-shared/SKILL.md, which crosses this skill package boundary. The target is fixed and likely benign, but the relative traversal is still a real filesystem access pattern.","verdict":"confirmed","severity":"high","confidence":0.67},{"id":"filesystem:SKILL.md:54:path-traversal-sequence","reason":"Line 54 is a See Also Markdown link to sibling documentation. It is not a dynamic file read and does not expose arbitrary filesystem paths.","verdict":"false_positive","confidence":0.86},{"id":"filesystem:SKILL.md:55:path-traversal-sequence","reason":"Line 55 is a static Markdown link to another skill document. It is a cross-reference, not path traversal against user input or secrets.","verdict":"false_positive","confidence":0.86}],"semantic_findings":[{"title":"Cloud Spreadsheet Write Can Leak Sensitive Data","severity":"medium","locations":[{"file":"SKILL.md","line_end":40,"line_start":37},{"file":"SKILL.md","line_end":50,"line_start":49}],"confidence":0.86,"description":"The skill writes caller-provided values to a Google Sheet. Sensitive data can be exposed if the spreadsheet ID is untrusted or values are copied without review.","confidence_reasoning":"The examples append values to Google Sheets, and the skill explicitly labels it as a write command requiring confirmation. This confirms a real data disclosure risk when consent or destination validation is weak."}],"subject_marketplace_commit_sha":null,"subject_content_hash":null,"subject_tree_hash":null,"subject_plugin_path":null,"audit_payload_hash":null,"confirmed_risk_level":null,"scanner_version":null,"policy_version":null,"subject":{"marketplaceCommitSha":null,"contentHash":null,"treeHash":null,"pluginPath":null,"auditPayloadHash":null},"scannerVersion":null,"policyVersion":null},"auditTranslation":null,"localization":{"requestedLocale":"en","contentLocale":"en","availableLocales":["en"],"fallbackToEnglish":false},"attestation":{"availability":"not_attestable","url":null,"status":null,"reason":"confirmed_risk_level does not match the canonical trust resolver"},"trust":{"publicState":"public","auditState":"complete","auditCurrentness":null,"confirmedRiskLevel":"medium","confirmedFindingCount":1,"capabilityReviewCount":4,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"confirmation_required","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"not_attestable","verificationState":"not_verified"},"isLatest":false}}