neobotnet / blog / company-of-the-week
company of the week·7 min read

company of the week: latitude financial

Latitude Financial's public web surface across 20 in-scope domains: the brands behind it, the development logins it leaves open, and the source maps and tokens it publishes.

Latitude Financial is a regulated consumer-credit company: the lender behind a wall of store-branded cards (GO Mastercard, Gem Visa, 28 Degrees, David Jones, CareCredit) that most of its customers have never thought of as "Latitude" at all. It runs a public bug bounty on Bugcrowd, so its public web surface is in scope for outside research.

We pointed neobotnet at that surface. What follows isn't an exploit — it's the shortlist a researcher would build before trying one. The full index is in /urls; these are the parts worth a second look.

20
in-scope roots
1,150
dns resolved
155
live web servers
308
source maps
4,503
urls indexed

read from dns: the architecture

The scope is twenty root domains, and almost none of them say "Latitude." They're the products: gomastercard.com.au, gemvisa.com.au, 28degreescard.com.au, interestfree.com.au, carecredit.com.au, latitudepay.*. You can read the corporate structure straight from DNS: one lender, a dozen consumer brands, and a twenty-first name that isn't a brand at all. That last one is lfscnp.com, the platform. 785 of the 1,150 resolving hostnames — 68% — live under it. The brand sites are a thin marketing veneer. lfscnp.com is the machine.

Two things fall out of the naming, before any of these hosts is probed for real.

  • The brands share one back office. Manage a 28 Degrees card, a GO Mastercard, a Gem Visa, or an Interest Free plan, and it's a different hostname every time but the same app every time, titled Latitude Service Centre. The merchant side collapses the same way, into one Latitude Partner Hub. One application reached through ten front doors is one bug reached through ten front doors.
  • The non-production estate names itself. -np means non-prod, and the segment before it names the platform team: originations-np (loan origination), digitalservicing-np (the Service Centre), merchant-services-np (checkout), se-platform-np (security engineering). The convention is a schematic. -np in a hostname tells an outsider exactly where to find the unhardened copy of a production system.

read from http: the auth surface

Production identity is locked down, as you'd want from a lender — the prod Okta endpoints, the OAuth webhooks, and the supporting services all answer 403. A few doors aren't shut, and they're the development ones. Dev tenants are the interesting find here, because a development login that's reachable from the internet is a development login an outsider can test.

  • A development Okta tenant, live on the open internet. auth.dev.se-platform-np.lfscnp.com serves a working sign-in page titled okta-dev-08654269. Dev identity tenants aren't production: they tend to carry test accounts, relaxed or disabled MFA, debug settings, and secrets that were never meant to leave an internal network. This is the door worth a researcher's time.
  • A training range, live in prod. appsec-dojo-prod.security.lfscnp.com is an AppSec Dojo — an app that ships deliberate vulnerabilities for security training. A reachable target that's vulnerable by design is still a reachable target.

read from javascript: the blueprint

Latitude publishes 308 .js.map source-map files, and neobotnet fetches and parses every one. A source map is the sidecar that turns a minified bundle back into its original tree, and 177 of these include sourcesContent — they don't just name the source files, they contain them. The richest is the checkout: checkout.latitudefinancial.com ships maps reconstructing 4,742 source files, the entire payment front end. For a researcher this isn't a vulnerability — it's the map you read before you look for one. Here's what that map gives up:

  • The API the front end talks to. Endpoint paths, parameter names, and request shapes — the server-side surface, described by the client that calls it.
  • The checks that are supposed to stop you. Client-side validation, feature flags, and role logic are all readable, which is exactly where you look for a rule the server forgets to enforce.
  • The routes nothing links to. Admin views, internal tools, and half-finished features live in the bundle long before they appear on a page.
  • A test build that equals production. The same checkout bundle hash appears on prod .com, prod .com.au, and master.checkout.test.merchant-services-np.lfscnp.com. The softer non-prod copy runs identical code, so anything learned there applies verbatim to the real one.

read from the urls: the needles

Every parameter on every URL is classified against a signal taxonomy — tokens, credentials, cloud keys, cross-domain redirects, internal IPs, path traversal, cloud-metadata SSRF targets — so a human reads the dozen that matter instead of the thousands that don't.

On Latitude, most of the corpus is clean: no cloud keys, no credentials, effectively no PII in parameters. Then the is_jwt signal fired thirteen times.

Thirteen crawled URLs carry a JSON Web Token in a token= query parameter. A JWT's payload is signed, not encrypted — anyone holding the URL can read it — so neobotnet does. They're bearer tokens issued by a service called applybuy-checkout-service: seven grant transaction:read,write, six grant customer:read, each scoped to a single customer/transaction resource. Access tokens for a checkout API, sitting in URLs that Latitude's own pages linked to — which is precisely how an outside crawler ended up holding them.

Every one of these expired in 2022 or early 2023. We're not publishing a live credential; there isn't one to publish. The problem is the pattern, not these tokens. A bearer token in a query string doesn't stay there — it lands in CDN and proxy logs, in browser history, in the Referer header handed to every third-party script on the page (Latitude's run Tealium and analytics), and, as demonstrated, in the index of anyone crawling the site. Tokens belong in an Authorization header or a short-lived POST body, never in a URL. The fix is worth doing even though these are dead: the next batch won't be.

run this query →

JWT bearer tokens sitting in token= URL parameters, in /urls

The smaller leads, each a shape worth checking rather than a finding — and each a query you can run yourself:

  • An OAuth redirect_uri pointing inward. One sign-in flow carries a redirect_uri aimed at identity-search.prod.se-platform.lfscnp.com — Latitude's own identity platform, so not an open redirect. But it leaks an internal production hostname, and a login callback is always worth testing for loose validation. run this query →

    redirect_uri parameters in /urls

  • A custom file-download handler. /DownloadFile.axd on the investor site (investors.latitudefinancial.com.au) — an ASP.NET download handler, the classic shape to test for path traversal or IDOR. run this query →

    DownloadFile.axd handler in /urls

  • A legacy merchant portal. merchantportal.gemfinance.co.nz runs SiteMinder over Struts (/smpsso/login/loginStart.do, .do = Java Struts) — an older stack that carries its own CVE history. run this query →

    SiteMinder / Struts merchant portal in /urls

what it adds up to

Three things here are worth a fix, in rough order of how much they'd help an attacker. The exposed development auth tenants come first — start with the dev Okta. Then the production source maps shipping sourcesContent. Then the bearer tokens that end up in URLs. None of them is exotic, and none needs a heroic remediation. They're the kind of gap that accumulates quietly in a large estate and stays there until someone outside points at it. To Latitude's credit, most of the platform is already locked: the bulk of the -np estate answers 403, and the URL corpus is clean of secrets.

Two things stated plainly. Every item above is a signal, not a confirmed vulnerability — neobotnet surfaces the shape; confirming exploitability is the researcher's job. And the right destination for anything live is Latitude's Bugcrowd program, not a blog post.

next week

neobotnet runs the same pass on a different in-scope program every week. Subscribe via RSS or browse the company of the week archive.