Hoe een vastgoedbedrijf van Blackstone Social Security-nummers, geboortedata, adressen en andere aanvraaggegevens blootlegde via een GraphQL-autorisatiefout

Het vinden van huisvesting in New York City is moeilijk; dat weet iedereen. Wat echter niet iedereen weet, is dat het makkelijker is om de laatste vier cijfers van iemands Social Security-nummer (SSN) te vinden dan een appartement...

Ik was bezig met een huuraanvraag bij Beam Living, een bedrijf uit de portefeuille van Blackstone. Ik volgde de normale stappen, maar als iemand die bewust met veiligheid omgaat, houd ik altijd het netwerktabblad open tijdens het surfen. Zo kan ik controleren of ik mijn gevoelige informatie niet invoer op een website die een 'script kiddie' (of GLM-5.2) eenvoudig zou kunnen kraken.

Toen ik mijn Social Security-nummer invoerde, dacht ik dat het verstandig zou zijn om de GraphQL-queries die dit verwerkten te inspecteren.

De GraphQL-query

In eerste instantie zag ik niets bijzonders. Maar toen ik naar mijn hoofdprofiel ging, zag ik een aanroep naar pd-dlcore.beamliving.com/graphql met de volgende payload:

{
  "operationName": "contact",
  "variables": {
    "contactId": "[email protected]"
  }
}

De volledige GraphQL-query:

query contact($contactId: String!) {
  contact(contactId: $contactId) {
    ...contactInfo
    __typename
  }
}

fragment contactInfo on ContactDtoModel {
  incomeVerificationMethod
  incomeCheckStatus
  incomeCheckReferenceId
  creditScore
  address
  applicationStatus
  city
  companyOrSchool
  consentDate
  consentIp
  country
  dateOfBirth
  emailAddress
  emergencyContact {
    emergencyContactEmail
    emergencyContactName
    emergencyContactPhone
    emergencyContactRelationship
    __typename
  }
  firstName
  id
  identityVerificationSubmittedDate
  incomeCheckDate
  isCurrentLeasee
  jobTitle
  lastName
  noSsn
  occupation
  pets {
    birthDay
    breed
    id
    isServiceDog
    licenseNumber
    name
    rabiesExpirationDate
    weight
    __typename
  }
  postalCode
  preferredName
  screeningFeePaid
  ssnInfo
  state
  status {
    ...applicationStatus
    __typename
  }
  telephone
  __typename
}

fragment applicationStatus on StatusDtoModel {
  applicationProgress {
    basicInfo {
      actionRequired
      __typename
    }
    dogsInformation {
      actionRequired
      __typename
    }
    emergencyContact {
      actionRequired
      __typename
    }
    identityVerification {
      actionRequired
      __typename
    }
    incomeVerification {
      actionRequired
      __typename
    }
    payments {
      actionRequired
      __typename
    }
    review {
      actionRequired
      __typename
    }
    __typename
  }
  progressDetails {
    applicationForm {
      description
      status
      __typename
    }
    firstMonthRent {
      description
      status
      __typename
    }
    identityVerification {
      description
      identityVerificationCompletedDate
      identityVerificationStatus
      identityVerificationSubmittedDate
      status
      __typename
    }
    incomeVerification {
      description
      status
      __typename
    }
    leaseGuarantee {
      description
      status
      __typename
    }
    leaseSigning {
      description
      signatureId
      status
      __typename
    }
    managerReview {
      managerReview
      managerReviewDecisionCode
      status
      __typename
    }
    securityDeposit {
      description
      paymentLink
      securityReplacement
      __typename
    }
    backgroundScreeningCheck {
      status
      __typename
    }
    creditCheck {
      status
      __typename
    }
    __typename
  }
  guestCardCreated
  unitReservationFailed
  __typename
}

Hoewel dit niet noodzakelijkerwijs slecht is, is het altijd een waarschuwingsteken ('smell') wanneer het e-mailadres van een gebruiker in een GraphQL-query wordt meegegeven, in plaats van dit af te leiden uit de sessiecookie.

De voor de hand liggende test

Ik deed vervolgens wat voor de hand lag: ik nam het e-mailadres van een vriend (ik wist dat hij ook gebruik had gemaakt van de dienst) en... boem. De laatste vier cijfers van zijn Social Security-nummer, geboortedatum, woonadres, IP-adres, telefoonnummer, enzovoort waren direct zichtbaar.

De impact was niet beperkt tot mijn eigen aanvraag of mijn gebouw. Beam Living gebruikte dit verhuurportaal in al haar complexen:

  • 8 Spruce
  • StuyTown
  • Peter Cooper Village
  • Kips Bay Court
  • Parker Towers

Iedereen die via dit gedeelde portaal had gesolliciteerd — en wiens gegevens in het systeem stonden — had zijn Social Security-informatie, geboortedatum, woonadres, IP-adres, telefoonnummer en andere aanvraaggegevens toegankelijk voor iedereen die hun e-mailadres kende.

Melding en de stille patch

Ik stopte onmiddellijk met testen en meldde het lek bij Beam Living. Het meldingsproces verliep niet ideaal; ik moest veel e-mails sturen en uiteindelijk een telefoongesprek voeren met iemand van het team van Beam Living. Zij gaven aan dat ze het hadden gecontroleerd en dat er helemaal geen probleem was. Toen ik opnieuw probeerde het lek te exploiteren, bleek dat het stilletjes was gepatcht. Ik ben blij dat het probleem is opgelost, maar dit is niet hoe bedrijven (zeker niet bedrijven in handen van giganten als Blackstone) met meldingen zouden moeten omgaan.

Het tijdspad van de melding verliep als volgt:

  • 14 juni: Ik stuurde een e-mail naar [email protected] om een ernstige kwetsbaarheid te melden die PII (persoonlijk identificeerbare informatie) van aanvragers en garantstellers blootlegde — waaronder de laatste vier cijfers van SSN's, creditscores, geboortedata, adressen en telefoonnummers. Ik vroeg hoe ik deze kwetsbaarheid op een verantwoorde manier kon melden.
  • 16 juni: Nadat ik geen antwoord had ontvangen, volgde ik op. Ik benadrukte de ernst van de situatie en vroeg Beam Living opnieuw om het juiste meldingskanaal te bevestigen of me in contact te brengen met het securityteam. Ik ontving geen reactie.
  • 23 juni: Ik liet mijn verhuuragent van Beam Living weten dat ik een ernstige kwetsbaarheid had gevonden waarbij SSN-cijfers, geboortedata, telefoonnummers, adressen en andere aanvraaggegevens via een e-mailadres werden blootgesteld. Ik vroeg om in contact te worden gebracht met het juiste team voor een verantwoorde melding.
  • 24 juni: Ik volgde opnieuw op en waarschuwde dat de kwetsbaarheid nog steeds live was. De verhuuragent gaf aan dat mijn rapport was doorgestuurd naar een team voor onderzoek.
  • 26 juni – 8 juli: Ik bleef proberen iemand te bereiken. Op 1 juli en opnieuw op 8 juli waarschuwde ik expliciet dat mijn gegevens — en die van andere gebruikers — nog steeds blootgesteld waren.
  • 9 juli: Na een telefoongesprek vroeg het Resident Experience-team van Beam Living me om details te sturen, zodat zij deze aan het Technology-team konden doorgeven. Ik testte direct daarna opnieuw en stelde vast dat het probleem eindelijk was gepatcht. Ik bood aan om de publicatie te coördineren en gaf aan dat ik van plan was dit te publiceren nadat ik hen tijd had gegeven om te reageren.
  • Na 9 juli: Ik kwam in contact met het hoofd Operations van Beam Living, die erg vriendelijk was, en liet haar weten dat ik de kwetsbaarheid publiekelijk wilde maken.

Nou ja! Ik heb hen gewaarschuwd dat ik deze blogpost zou plaatsen, en ik hoop dat mijn huurcontract hierdoor niet wordt opgezegd...