transitive-bullshit / bing-chat

Node.js client for Bing's new AI-powered search. It's like ChatGPT on steroids 🔥
MIT License
1.22k stars 127 forks source link

Reverse engineered oauth #25

Open nitanmarcel opened 1 year ago

nitanmarcel commented 1 year ago

I don't really know JavaScript or typescript in this case, so I'm going just to put a link to my work.

Unfortunately this should be done server side, since it requires the same client id, the app or desktop needs and I don't think would be safe to share it in plain text.

Anyway, I though I should share my work with this repo :)

https://github.com/nitanmarcel/sydney-telegram/blob/main/bot_oauth.py

kingcc commented 1 year ago

I simply converted it without testing. @nitanmarcel

// Node.js 19

/**
 * Auth with code
 *
 * @param {*} authCode
 * @param {*} client_id
 *
 * @returns { has_sydney: boolean, cookies }
 */
async function auth(authCode, client_id) {
    let access_token = null
    let cookies = null
    let has_sydney = false

    const token_url = "https://login.live.com/oauth20_token.srf"

    const headers = {
        "User-Agent":
            "Mozilla/5.0 (Linux; Android 11; WayDroid x86_64 Device Build/RQ3A.211001.001; ) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.118 Safari/537.36 BingSapphire/24.1.410310303",
        "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
    }

    {
        const params = {
            client_id,
            code: authCode,
            redirect_uri: "https://login.live.com/oauth20_desktop.srf",
            grant_type: "authorization_code",
        }
        const url = `${token_url}?client_id=${client_id}&code=${authCode}&redirect_uri=https://login.live.com/oauth20_desktop.srf&grant_type=authorization_code`
        const response = await fetch(url, {
            method: "POST",
            headers: headers,
            body: JSON.stringify(params),
        })
        if (response.status === 200) {
            const js = await response.json()
            access_token = js["access_token"]
        }
    }

    {
        const params = {
            client_id: client_id,
            code: authCode,
            redirect_uri: "https://login.live.com/oauth20_desktop.srf",
            grant_type: "authorization_code",
        }
        const url = `https://ssl.bing.com/fd/auth/signin?action=token&provider=windows_live_id&save_token=0&token=${access_token}`
        const response = await fetch(url + "?" + new URLSearchParams(params), {
            headers: headers,
        })
        if (response.status === 200) {
            const js = await response.json()
            if (js.success) {
                cookies = response.headers.get("cookie_jar")
                has_sydney = true
            }
        }
    }

    if (cookies) {
        const url = "https://www.bing.com/sydchat"
        const response = await fetch(url, {
            headers: headers,
        })
        if (response.status !== 200) {
            cookies = null
            has_sydney = false
        }
    }

    return { cookies, has_sydney }
}
nitanmarcel commented 1 year ago

I simply converted it without testing. @nitanmarcel

// Node.js 19

/**
 * Auth with code
 *
 * @param {*} authCode
 * @param {*} client_id
 *
 * @returns { has_sydney: boolean, cookies }
 */
async function auth(authCode, client_id = "0000000040170455") {
    let access_token = null
    let cookies = null
    let has_sydney = false

    const token_url = "https://login.live.com/oauth20_token.srf"

    const headers = {
        "User-Agent":
            "Mozilla/5.0 (Linux; Android 11; WayDroid x86_64 Device Build/RQ3A.211001.001; ) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.118 Safari/537.36 BingSapphire/24.1.410310303",
        "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
    }

    {
        const params = {
            client_id,
            code: authCode,
            redirect_uri: "https://login.live.com/oauth20_desktop.srf",
            grant_type: "authorization_code",
        }
        const url = `${token_url}?client_id=${client_id}&code=${authCode}&redirect_uri=https://login.live.com/oauth20_desktop.srf&grant_type=authorization_code`
        const response = await fetch(url, {
            method: "POST",
            headers: headers,
            body: JSON.stringify(params),
        })
        if (response.status === 200) {
            const js = await response.json()
            access_token = js["access_token"]
        }
    }

    {
        const params = {
            client_id: client_id,
            code: authCode,
            redirect_uri: "https://login.live.com/oauth20_desktop.srf",
            grant_type: "authorization_code",
        }
        const url = `https://ssl.bing.com/fd/auth/signin?action=token&provider=windows_live_id&save_token=0&token=${access_token}`
        const response = await fetch(url + "?" + new URLSearchParams(params), {
            headers: headers,
        })
        if (response.status === 200) {
            const js = await response.json()
            if (js.success) {
                cookies = response.headers.get("cookie_jar")
                has_sydney = true
            }
        }
    }

    if (cookies) {
        const url = "https://www.bing.com/sydchat"
        const response = await fetch(url, {
            headers: headers,
        })
        if (response.status !== 200) {
            cookies = null
            has_sydney = false
        }
    }

    return { cookies, has_sydney }
}

I would probably try to hide the client id to avoid trouble ^^ but looks ok to me. Don't forget the parsing of the code from the auth url: https://github.com/nitanmarcel/sydney-telegram/blob/main/bot_oauth.py#L11

Actually I do get when checking if it has sydney

image

kingcc commented 1 year ago

Okay, I'm gonna hide the client_id :) btw could try console.log(await auth(...)) to avoid Promise { <pending> }

nitanmarcel commented 1 year ago

console.log(await auth(...))

➜ pcap node auth.js (node:152010) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time (Use node --trace-warnings ... to show where the warning was created) { cookies: null, has_sydney: false } ➜ pcap directory

Probably my code is messy as I just copied it from my tests., most likely something is missing xD

nitanmarcel commented 1 year ago

@kingcc

the fixed code:

https://www.diffchecker.com/izZomiRC

cleaned up my code too, maybe it's easier to read

https://github.com/nitanmarcel/sydney-telegram/blob/main/bot_oauth.py#L20