A Blackstone real estate company exposed SSN digits, DOBs, addresses and more
Update: This post received some attention on Hacker News — see the discussion thread. Finding housing in NYC is hard. Everyone knows that. But what not everyone knows is that it is easier to find the last four digits of someone’s Social Security number than an apartment… I was applying for a lease on Beam Living, a Blackstone portfolio company. I went through the normal flows, but (as a security-conscious individual) I always have my network tab open as I browse the web to make sure I am not putting my sensitive information into a website that a script kiddie (or GLM-5.2) could easily break into. As I was submitting my Social Security number, I figured I should check out the GraphQL (rip, used to be the hot thing) queries that were processing it. The GraphQL query At first, I didn’t see anything of note. But when I went to my main profile, I saw a call to pd-dlcore.beamliving.com/graphql with the payload: { "operationName": "contact", "variables": { "contactId": "[email protected]" } } 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 } While not necessarily bad, supplying a user’s email into a GraphQL query like this, as opposed to just deriving it from the session cookie, is always a smell. The obvious test So I did the obvious thing – I took a friend’s email (I knew he had also used the service) and… boom. The last four digits of his Social Security number, date of birth, home address, IP address, phone number, etc., etc. The impact was not limited to my application or my building. Beam Living used this leasing portal across its communities: 8 Spruce StuyTown Peter Cooper Village Kips Bay Court Parker Towers Anyone who had applied through that shared portal—and whose record remained in the system— had their Social Security number information, date of birth, home address, IP address, phone number, and other application data accessible to any one who knew their email address. Disclosure and the silent patch I immediately stopped testing and disclosed it to Beam Living. The disclosure process wasn’t ideal – I had to send many emails and eventually got on a phone call with someone from the Beam Living team. They said they had checked and there was no issue at all. I went back to try the exploit again and it had been silently patched. So I am glad that the issue is fixed, but this is not how companies (especially ones owned by giants like Blackstone) should handle disclosure… The disclosure timeline went like this: June 14: I emailed [email protected] to report a serious vulnerability exposing applicants’ and guarantors’ PII—including the last four digits of SSNs, credit scores, dates of birth, addresses, and phone numbers. I asked how to disclose this vulnerability responsibly. June 16: After receiving no reply, I followed up, emphasized the severity, and again asked Beam Living to confirm the correct disclosure channel or connect me with its security team. I received no response. June 23: I told my Beam Living leasing agent that I had found a serious vulnerability exposing SSN digits, dates of birth, phone numbers, addresses, and other applicant data through an email address. I asked to be connected with the right team for responsible disclosure. June 24: I followed up and warned that the vulnerability was still live. The leasing agent said my report had been forwarded to a team for investigation. June 26–July 8: I continued trying to reach someone. On July 1 and again on July 8, I explicitly warned that my data—and other users’ data—was still exposed. July 9: After a phone conversation, Beam Living’s Resident Experience team asked me to send details so they could pass them to the Technology team. I retested immediately afterward and found that the issue had finally been patched. I offered to coordinate disclosure and said I planned to publish after giving them time to respond. After July 9: I connected with Beam Living’s head of Operations, who was very nice, and told her that I intended to disclose the vulnerability publicly. Oh well! I alerted them that I was going to post this blog, and I hope I don’t get my lease canceled…