Skip to content

Migrate BC Auth to login.hackers.bugcrowd.com with Legacy Fallback#92

Open
voidclick-labs wants to merge 1 commit into
sw33tLie:mainfrom
voidclick-labs:bc-hacker-auth-w-legacy
Open

Migrate BC Auth to login.hackers.bugcrowd.com with Legacy Fallback#92
voidclick-labs wants to merge 1 commit into
sw33tLie:mainfrom
voidclick-labs:bc-hacker-auth-w-legacy

Conversation

@voidclick-labs
Copy link
Copy Markdown

Full Disclosure I had claude write this code.

Bugcrowd Authentication Changes

Bugcrowd migrated their login from a custom form at identity.bugcrowd.com to Okta Identity Engine (IDX) at login.hackers.bugcrowd.com. This PR updates the auth flow to match and retains the original flow as a fallback.

  • Add new primary login flow via login.hackers.bugcrowd.com (Okta IDX)
  • Keep legacy identity.bugcrowd.com form flow as a silent fallback
  • Extract shared helpers to eliminate code duplication
  • Remove non-essential HTTP headers from all Okta IDX requests
  • Fix login performance regression caused by fallback ordering

New Auth Flow

GET identity.bugcrowd.com/login/hacker
  → identity.bugcrowd.com/login/hacker/oauth2/authorization/hacker
  → login.hackers.bugcrowd.com/oauth2/default/v1/authorize?...  (HTML with stateToken)
  → POST /idp/idx/introspect   (exchange stateToken → stateHandle)
  → POST /idp/idx/identify     (submit email)
  → POST /idp/idx/challenge/answer  (submit password)
  → POST /idp/idx/challenge/answer  (submit TOTP)
  → GET  success.href          (finalize session, collect cookies)

Changes

pkg/platforms/bugcrowd/bugcrowd.go

  • newLoginClient(proxy) — new helper: shared cookie-jar-backed retryablehttp.Client setup (previously duplicated). Sets RetryMax = 0 to prevent redirect side effects.
  • loginOktaIDX(email, password, otpSecret, proxy) — new primary flow: GETs identity.bugcrowd.com/login/hacker, follows redirect chain to Okta authorize page, hands off to runOktaIDXFlow.
  • runOktaIDXFlow(client, pageBody, email, password, otpSecret) — new shared helper: executes the full Okta IDX API sequence (introspect → identify → password challenge → TOTP challenge → token redirect). Used by both flows.
  • loginLegacy(email, password, otpSecret, proxy) — renamed from the previous inline logic in Login(). POSTs to identity.bugcrowd.com/login, follows redirect_to to Okta authorize page, then calls runOktaIDXFlow.
  • Login() — now tries loginOktaIDX first; falls back to loginLegacy on failure (logged at debug level).

Headers Removed

Header Reason
Origin CORS is browser-enforced; not validated server-side by Okta API
Referer Not required by any endpoint
Accept: application/json; okta-version=1.0.0 Go defaults to */*; Okta returns JSON regardless
X-Requested-With Browser convention only
X-Okta-User-Agent-Extended Injected by Okta JS widget; server does not require it

User-Agent, Content-Type, and X-Csrf-Token are retained (WAF detection, required by the API, and CSRF protection respectively). The application/ion+json; okta-version=1.0.0 content type on the introspect POST is also required.

Performance Fix

The original fallback tried the legacy flow first. Since identity.bugcrowd.com/login no longer returns redirect_to, the legacy flow always fails after 2 rate-limited requests (~2s wasted at 1 req/sec). Swapping the order so loginOktaIDX runs first eliminates this overhead in the common case.

Test Plan

  • go run main.go poll bc --config <config> completes login and returns scope data
  • Login succeeds with a valid email, password, and TOTP secret
  • WAF ban (403/406) is surfaced as a clear error message
  • Passing --proxy routes traffic through the proxy correctly

@voidclick-labs
Copy link
Copy Markdown
Author

See #91

@sw33tLie
Copy link
Copy Markdown
Owner

Thanks! Checking this asap

@sw33tLie
Copy link
Copy Markdown
Owner

sw33tLie commented Apr 16, 2026

This was already implemented in d1ffb90. But not with the fallback.

Are you aware of any account still having the old auth?

@sw33tLie sw33tLie closed this Apr 16, 2026
@sw33tLie sw33tLie reopened this Apr 16, 2026
@voidclick-labs
Copy link
Copy Markdown
Author

voidclick-labs commented Apr 16, 2026

Yeah I was seeing that commit, it looks like it was to use a browser token instead of the secrets in bbscope.yaml right?

Im unsure about any other account having the old auth.

My BC account is newer (made in the last couple of weeks) I genuinely could not auth using the main branch. Im assuming the main branch is working for most if not all users.

When I put in a BC help desk ticket to ask why I could not use that auth flow, I was told "There is an ongoing migration of hacker accounts to use the new authentication flow in https://login.hackers.bugcrowd.com/."

Main Branch Screenshot:
image

d1ffb90. Screenshot:
image

PR Code Screenshot:
image
image

^ I am a little worried this is a "works on my machine/account" situation.

@voidclick-labs
Copy link
Copy Markdown
Author

voidclick-labs commented Apr 16, 2026

I told claude to keep the auth flow in the main branch in, but the account I have doesnt let me test if it still works or not.

Having looked at some previous issues in the repo, it seems bc has had at-least 1 other account migration. Im unsure if this is the same account migration or a new one.

If it is a new one, I figured I'd save ya some time. Great tool, thanks for making it, its gonna be my upstream for my automation, and I didnt wanna hit ur website every hour. Lol Sorry its AI code, but shout out Caido Skills for the 1 shot fix.

@sw33tLie
Copy link
Copy Markdown
Owner

Seems like other users are reporting they don't have okta yet, considering to merge this soon

@voidclick-labs
Copy link
Copy Markdown
Author

Been running this in an hourly cron job since the PR. Havent had any issues yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants