T09 · Insecure Skill Coding Practices
- Location
src/main.rs:11- Finding
GitHub OAuth Access Token Can Be Disclosed to an Attacker-Controlled Faucet Endpoint
- Content
View full analysis
Result<()> { // Fetch the GitHub client ID from the faucet let resp = get_json(&format!("{faucet_url}/auth/github/client_id"))?; let client_id = resp["client_id"] .as_str() .context("Failed to get client_id from faucet")?; // Start GitHub device flow let body = format!("client_id={client_id}&scope=user:email"); let device_resp = post_form("https://github.com/login/device/code", &body)?; let device_code = device_resp["device_code"] .as_str() .context("Missing device_code")?; let user_code = device_resp["user_code"] .as_str() .context("Missing user_code")?; let verification_uri = device_resp["verification_uri"] .as_str() .context("Missing verification_uri")?; let interval = device_resp["interval"].as_u64().unwrap_or(5); println!("Go to: {verification_uri}"); println!("Enter code: {user_code}"); println!(); println!("Waiting for authorization..."); // Poll for the access token let access_token = loop { std::thread::sleep(std::time::Duration::from_secs(interval)); let poll_body = format!( "client_id={client_id}&device_code={device_code}&grant_type=urn:ietf:params:oauth:grant-type:device_code" ); let poll_resp = post_form("https://github.com/login/oauth/access_token", &poll_body)?; if let Some(token) = poll_resp["access_token"].as_str() { break token.to_string(); } ...[truncated 3246 chars]- Remediation
View remediation
