T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:137
- Finding
- Facebook access token may be exposed through request URLs and exception logging<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 74–75 and 137–169 **Vulnerability Type**: Credential exposure through URL query parameters and unsanitized error logging **Risk Level**: High ### Vulnerable Code ```powershell $fb = Get-Content "$HOME/.config/fb-page/credentials.json" -Raw | ConvertFrom-Json $r = Invoke-RestMethod "https://graph.facebook.com/v25.0/me?access_token=$($fb.FB_PAGE_TOKEN)" -ErrorAction Stop ``` ```powershell try { $convs = (Invoke-RestMethod "https://graph.facebook.com/v25.0/$pageId/conversations?fields=id,updated_time&limit=20&access_token=$token").data foreach ($conv in $convs) { $lastSeen = if ($state."$($conv.id)") { [datetime]::Parse($state."$($conv.id)") } else { (Get-Date).ToUniversalTime().AddSeconds(-$lookback) } if ([datetime]::Parse($conv.updated_time) -le $lastSeen) { continue } $msgs = (Invoke-RestMethod "https://graph.facebook.com/v25.0/$($conv.id)/messages?fields=message,from,created_time&limit=10&access_token=$token").data foreach ($msg in ($msgs | Sort-Object created_time)) { if ([datetime]::Parse($msg.created_time) -le $lastSeen) { continue } $senderId = if ($msg.from) { $msg.from.id } else { '' } if ($senderId -eq $pageId) { continue } $sender = if ($msg.from) { $msg.from.name } else { 'Unknown' } $text = if ($msg.message) { $msg.message } elseif ($msg.sticker) { '[sticker]' } else { '[attachment]' } Write-Log "FORWARD | $sender | Conv:$($conv.id)" $notify = "New FB Message`nFrom: $sender`nMessage: $text`nConv ID: $($conv.id)" Start-Job -ScriptBlock { param($ch, $tg, $m) & openclaw message send --channel $ch --target $tg --message $m 2>$null } -ArgumentList $channel, $target, $notify | Out-Null } $state | Add-Member -NotePropertyName $conv.id -NotePrope ...[truncated 2563 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Pass the token in an authorization header rather than a URL query parameter: ```powershell $headers = @{ Authorization = "Bearer $token" } $convsUri = "https://graph.facebook.com/v25.0/$pageId/conversations?fields=id,updated_time&limit=20" $convs = (Invoke-RestMethod -Uri $convsUri -Headers $headers -Method Get -ErrorAction Stop).data ``` Apply the same pattern to the credential test and message retrieval request. 2. Never write the complete exception object directly to disk. Record only an allowlisted error category, HTTP status code, and sanitized API error code. 3. Add a redaction function that removes authorization headers, `access_token` parameters, token values, and full request URIs before any diagnostic text is logged. 4. Restrict logging to messages such as: ```powershell catch { $status = if ($_.Exception.Response) { [int]$_.Exception.Response.StatusCode } else { "unknown" } Write-Log "Facebook API request failed. HTTP status: $status" } ``` 5. Review and securely delete existing logs, then rotate the Facebook Page token if a log may already contain it. 6. Continue applying restrictive file permissions, but do not rely on permissions as a substitute for preventing credentials from entering logs. ]]>
