{"data":{"skill":{"slug":"microsoft-python-appservice-deploy","name":"python-appservice-deploy","icon":"📦","repo":"https://github.com/microsoft/azure-skills/tree/main/.github/plugins/azure-skills/skills/python-appservice-deploy/","status":"approved","author":"microsoft","authorVersion":null,"skillstoreRevision":null},"audit":{"id":"ba80f01f-20a2-4a03-a188-575eed3c6d19","skill_id":"ff8799c3-e6b8-4cf4-862f-61a9ebfdd84b","version":1,"content_hash":"289b7d6864d1b123c8f750c57165570b","risk_level":"high","is_blocked":false,"safe_to_publish":false,"analysis_status":"ok","agent_auto_install_policy":"confirmation_required","manual_install_policy":"allowed","summary":"Most static findings are false positives from Azure CLI documentation, PowerShell examples, placeholder URLs, and required App Service bind addresses. The review confirms a high-risk command-injection concern in the retry helper scripts because they execute composed command strings that may include user-supplied Azure resource values.","remediation":[{"issue":"Retry helpers execute composed shell command strings.","severity":"high","suggestion":"Replace eval and powershell -Command with argument-array execution, or validate resource names against strict Azure-safe patterns before command construction."},{"issue":"Documentation allows user-specified resource names to be used verbatim.","severity":"medium","suggestion":"Document strict validation and shell quoting requirements for app names, resource groups, plans, regions, and subscription values."},{"issue":"Deployment examples contain many executable command snippets.","severity":"low","suggestion":"Keep commands scoped to Azure CLI and avoid adding network probes, secret reads, or commands unrelated to the requested deployment."}],"risk_factor_evidence":[{"factor":"external_commands","evidence":[{"file":"references/create-app.md","line_end":38,"line_start":38},{"file":"references/create-app.md","line_end":5,"line_start":5},{"file":"references/create-app.md","line_end":24,"line_start":24},{"file":"references/create-app.md","line_end":40,"line_start":40},{"file":"references/create-app.md","line_end":74,"line_start":74},{"file":"references/create-app.md","line_end":87,"line_start":87},{"file":"references/create-app.md","line_end":96,"line_start":96},{"file":"references/create-app.md","line_end":102,"line_start":102},{"file":"references/deploy-azcli.md","line_end":24,"line_start":22},{"file":"references/deploy-azcli.md","line_end":77,"line_start":76},{"file":"references/deploy-azcli.md","line_end":80,"line_start":78},{"file":"references/deploy-azcli.md","line_end":95,"line_start":95},{"file":"references/deploy-azcli.md","line_end":20,"line_start":20},{"file":"references/deploy-azcli.md","line_end":38,"line_start":38},{"file":"references/deploy-azcli.md","line_end":58,"line_start":58},{"file":"references/deploy-azcli.md","line_end":59,"line_start":59},{"file":"references/deploy-azcli.md","line_end":74,"line_start":74},{"file":"references/deploy-azcli.md","line_end":98,"line_start":98},{"file":"references/deploy-azd.md","line_end":18,"line_start":16},{"file":"references/deploy-azd.md","line_end":22,"line_start":20},{"file":"references/deploy-azd.md","line_end":19,"line_start":19},{"file":"references/deploy-azd.md","line_end":31,"line_start":31},{"file":"references/deploy-azd.md","line_end":72,"line_start":72},{"file":"references/deploy-azd.md","line_end":73,"line_start":73},{"file":"references/errors.md","line_end":8,"line_start":7},{"file":"references/errors.md","line_end":9,"line_start":8},{"file":"references/errors.md","line_end":10,"line_start":9},{"file":"references/errors.md","line_end":10,"line_start":10},{"file":"references/errors.md","line_end":41,"line_start":41},{"file":"references/post-deploy-message.md","line_end":71,"line_start":71},{"file":"references/startup-commands.md","line_end":26,"line_start":26},{"file":"references/startup-commands.md","line_end":47,"line_start":47},{"file":"references/startup-commands.md","line_end":58,"line_start":58},{"file":"references/startup-commands.md","line_end":71,"line_start":71},{"file":"references/transient-retry.md","line_end":42,"line_start":40},{"file":"references/transient-retry.md","line_end":37,"line_start":37},{"file":"references/transient-retry.md","line_end":38,"line_start":38},{"file":"scripts/generate-app-name.ps1","line_end":5,"line_start":5},{"file":"scripts/generate-app-name.sh","line_end":4,"line_start":4},{"file":"scripts/generate-app-name.sh","line_end":23,"line_start":23},{"file":"scripts/generate-app-name.sh","line_end":28,"line_start":26},{"file":"scripts/generate-app-name.sh","line_end":37,"line_start":37},{"file":"scripts/generate-app-name.sh","line_end":40,"line_start":40},{"file":"scripts/generate-app-name.sh","line_end":46,"line_start":46},{"file":"scripts/generate-app-name.sh","line_end":58,"line_start":58},{"file":"scripts/retry-az-create.ps1","line_end":3,"line_start":3},{"file":"scripts/retry-az-create.ps1","line_end":13,"line_start":13},{"file":"scripts/retry-az-create.ps1","line_end":15,"line_start":15},{"file":"scripts/retry-az-create.ps1","line_end":18,"line_start":17},{"file":"scripts/retry-az-create.ps1","line_end":22,"line_start":21},{"file":"scripts/retry-az-create.ps1","line_end":36,"line_start":36},{"file":"scripts/retry-az-create.ps1","line_end":39,"line_start":39},{"file":"scripts/retry-az-create.ps1","line_end":40,"line_start":40},{"file":"scripts/retry-az-create.sh","line_end":3,"line_start":3},{"file":"scripts/retry-az-create.sh","line_end":11,"line_start":11},{"file":"scripts/retry-az-create.sh","line_end":13,"line_start":13},{"file":"scripts/retry-az-create.sh","line_end":36,"line_start":36},{"file":"scripts/retry-az-create.sh","line_end":51,"line_start":51},{"file":"SKILL.md","line_end":12,"line_start":12},{"file":"SKILL.md","line_end":14,"line_start":14},{"file":"SKILL.md","line_end":18,"line_start":18},{"file":"SKILL.md","line_end":20,"line_start":20},{"file":"SKILL.md","line_end":21,"line_start":21},{"file":"SKILL.md","line_end":22,"line_start":22},{"file":"SKILL.md","line_end":23,"line_start":23},{"file":"SKILL.md","line_end":24,"line_start":24},{"file":"SKILL.md","line_end":29,"line_start":29},{"file":"SKILL.md","line_end":30,"line_start":30},{"file":"SKILL.md","line_end":31,"line_start":31},{"file":"SKILL.md","line_end":32,"line_start":32},{"file":"SKILL.md","line_end":36,"line_start":36}]},{"factor":"filesystem","evidence":[{"file":"references/create-app.md","line_end":23,"line_start":23},{"file":"references/create-app.md","line_end":24,"line_start":24},{"file":"references/create-app.md","line_end":5,"line_start":5},{"file":"references/create-app.md","line_end":38,"line_start":38},{"file":"references/create-app.md","line_end":71,"line_start":71},{"file":"references/create-app.md","line_end":84,"line_start":84},{"file":"references/create-app.md","line_end":99,"line_start":99},{"file":"references/transient-retry.md","line_end":31,"line_start":31},{"file":"references/transient-retry.md","line_end":37,"line_start":37},{"file":"scripts/generate-app-name.sh","line_end":36,"line_start":36},{"file":"scripts/generate-app-name.sh","line_end":39,"line_start":39},{"file":"scripts/generate-app-name.sh","line_end":40,"line_start":40},{"file":"scripts/retry-az-create.sh","line_end":36,"line_start":36}]},{"factor":"network","evidence":[{"file":"references/deploy-azcli.md","line_end":96,"line_start":96},{"file":"references/deploy-azcli.md","line_end":100,"line_start":100},{"file":"references/deploy-azcli.md","line_end":36,"line_start":36},{"file":"references/deploy-azcli.md","line_end":40,"line_start":40},{"file":"references/detect.md","line_end":68,"line_start":68},{"file":"references/post-deploy-message.md","line_end":19,"line_start":19},{"file":"references/post-deploy-message.md","line_end":36,"line_start":36},{"file":"references/post-deploy-message.md","line_end":49,"line_start":49},{"file":"references/post-deploy-message.md","line_end":51,"line_start":51},{"file":"references/startup-commands.md","line_end":24,"line_start":24},{"file":"references/startup-commands.md","line_end":28,"line_start":28},{"file":"references/startup-commands.md","line_end":45,"line_start":45},{"file":"references/startup-commands.md","line_end":49,"line_start":49},{"file":"references/startup-commands.md","line_end":56,"line_start":56},{"file":"references/startup-commands.md","line_end":60,"line_start":60},{"file":"references/startup-commands.md","line_end":69,"line_start":69},{"file":"references/startup-commands.md","line_end":73,"line_start":73},{"file":"SKILL.md","line_end":32,"line_start":32},{"file":"SKILL.md","line_end":22,"line_start":22}]}],"critical_findings":[],"high_findings":[{"title":"PowerShell invocation","locations":[{"file":"scripts/retry-az-create.ps1","line_end":40,"line_start":40}],"confidence":0.86,"description":"& powershell -NoProfile -Command $script 2>&1","review_kind":"capability","source_category":"external_commands","source_severity":"high","confidence_reasoning":"The script builds a PowerShell command string from ShowCommand and CreateCommand, then runs it with powershell -Command. If user-controlled resource names are interpolated into those strings, this can execute unintended commands."},{"title":"Shell command substitution","locations":[{"file":"scripts/retry-az-create.sh","line_end":36,"line_start":36}],"confidence":0.88,"description":"if err=$({ eval \"$SHOW_CMD -o none 2>/dev/null\" || eval \"$CREATE_CMD -o none\"; } 2>&1); then","review_kind":"capability","source_category":"external_commands","source_severity":"medium","confidence_reasoning":"The script executes caller-provided command strings through eval, and the workflow can include user-supplied Azure names. Without strict quoting or validation, shell metacharacters in those values can become command injection."},{"title":"Command Injection Through Retry Command Strings","locations":[{"file":"references/create-app.md","line_end":9,"line_start":9},{"file":"references/transient-retry.md","line_end":41,"line_start":31},{"file":"scripts/retry-az-create.sh","line_end":36,"line_start":36},{"file":"scripts/retry-az-create.ps1","line_end":40,"line_start":39}],"confidence":0.86,"description":"The workflow allows user-specified Azure names to be used verbatim, and the retry helpers execute composed command strings. Validate or safely quote all user-controlled resource names before passing them to shell or PowerShell execution.","review_kind":"security","source_category":"semantic","source_severity":"high","confidence_reasoning":"The injection sink is explicit in both retry helper scripts, and the documentation states that user-provided Azure names may be used verbatim. The issue depends on how callers quote values, so confidence is high but not absolute."}],"medium_findings":[],"low_findings":[],"dangerous_patterns":[],"files_scanned":13,"total_lines":985,"audit_model":"codex","audited_at":"2026-07-03T10:44:54.239+00:00","created_at":"2026-07-03T11:27:24.910638+00:00","static_findings":[],"finding_verdicts":[],"semantic_findings":[],"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":"high","confirmedFindingCount":1,"capabilityReviewCount":2,"needsReviewCount":0,"falsePositiveCount":0,"agentAutoInstallPolicy":"confirmation_required","manualInstallPolicy":"allowed","artifactSignatureState":"available","attestationState":"not_attestable","verificationState":"not_verified"},"isLatest":false}}