> Perhaps you have no sympathy for web applications that store sensitive data in query strings, as that’s widely recognized as an insecure pattern. The URL fragment is more serious. That otherwise is a safe way to store sensitive information, so it’s alarming to see a third-party library sending a copy to an external server.
> Firefox Send and Mega.nz are both examples of popular web apps that use the URL fragment to store client-side encryption keys so that users can save end-to-end encrypted files to the cloud without the server ever having access to the underlying data.
The URL fragment is not designed to be any more secure than anything else in the URL, it's just a funny quirk of how web browsers evolved that it doesn't happen to be sent to the webserver. That popular platforms are (mis)using it to pass information without that information hitting their webservers is unfortunate. But it doesn't mean that the URL Fragment is somehow special or should be thought of as "secure" - that's not a guarantee that the URL scheme makes.
For example, those fragments will easily appear in browser history for anyone else who uses your same device...
That's an interesting point. I did take it for granted that browsers guarantee web apps that they don't send the URL fragment to the server. I've never looked into it, but your comment sent me to read RFC 3986.
From my reading, the RFC does seem to prohibit browsers from sending the URL fragment:
>Fragment identifiers have a special role in information retrieval systems as the primary form of client-side indirect referencing... As such, the fragment identifier is not used in the scheme-specific processing of a URI; instead, the fragment identifier is separated from the rest of the URI prior to a dereference, and thus the identifying information within the fragment itself is dereferenced solely by the user agent, regardless of the URI scheme.
Granted, the wording isn't 100% clear, so maybe I'm imposing my own hopeful interpretation on the RFC.
I agree that if I were storing, say, military secrets, I wouldn't choose the URL fragment as a storage medium. But if the expectation is "this is a place where I can put user data and the browser won't leak it to other places," then the URL fragment seems to me a sensible place to store data, on par with browser local storage.
This is in contrast with plain URLs which third party servers receive through the HTTP referer header. The browser leaks query parameters to other places, too, notably HTTP proxies. But Stripe's JS library was the first I'd seen of a system that exposes URL fragments to an external service.
Putting secret information in a URI is explicitly called out as a bad idea in the very RFC you reference:
> URI producers should not provide a URI that contains a username or password that is intended to be secret. URIs are frequently displayed by browsers, stored in clear text bookmarks, and logged by user agent history and intermediary applications (proxies).
As an aside, if you're going to be making any security judgments from an RFC, every RFC since RFC2223 has a Security Considerations section. You usually want to start there.
It's fairly obvious that this is about keeping secrets from other users locally whereas the fragment discussion is about keeping secrets from the server and that these two are not the same thing. People reasonably see the fragment as none of the server's business independently of whether it's any other local user's business (the latter fact itself being no one else's business to care about).
I've found some places say localStorage is insecure, but both OWASP [0] and MDN [1] say it isolates by origin. Third party scripts from different origins shouldn't be able to access it, but a successful XSS attack could have access.
The fragment is, at the very least, exposed to JavaScript. It's also has several problems which are explicitly called out (for the query string) in your own link: Shoulder surfing, cache, history
This is sort of fair as a statement of principles but I think OAuth2 gets you into the same kind of trouble with special security status for the fragment.
Yes. I’m debating in my head who is correct here. Maybe Oauth2 is colouring my judgement a bit but I feel the fragment should NOT be sent to the server unless there are extremely good reasons. Let’s try to keep the understanding of what happens to certain things consistent even if we have the power to abuse them.
I read the initial post when it was trending on HN, and had previously noticed that line in Stripe's Privacy Policy. I remember checking immediately afterward that my company was only loading Stripe's js on our billing page. I'm a skeptic by nature, so even after reading pc's response I still didn't feel great.
Then I got to reading this new post:
> Amid the discussion on Hacker News, a user expressed concern that, despite Stripe’s current good intentions, user data could fall into the wrong hands in the event that another company purchased Stripe ... Perhaps in direct response to that exchange, the new privacy policy includes this clause:
> > Any other entity which buys us or part of our business will have the right to continue to use your Personal Data, but only in the manner set out in this Privacy Policy unless you agree otherwise.
This is fantastic. I've yet to see a requirement such as this in any Privacy Policy I've read. In fact, I hadn't even considered the possibility of such cleverness. This is now my new gold standard for the company sale terms of any practical privacy policy. I'm going to look into updating my company's privacy policy to reflect this language.
> Any other entity which buys us or part of our business will have the right to continue to use your Personal Data, but only in the manner set out in this Privacy Policy unless you agree otherwise.
I thought this was implied in any contract. A change of owner doesn't mean the terms of the contract stop being applied.
I can't speak to the implication, but I've yet to read a policy that didn't explicitly outline how it handles business transfers. Some examples from different industries (the first 3 random sites I thought of):
AirBnB [0]
> If Airbnb undertakes or is involved in any merger, acquisition, reorganization, sale of assets, bankruptcy, or insolvency event, then we may sell, transfer or share some or all of our assets, including your information in connection with such transaction or in contemplation of such transaction (e.g., due diligence). In this event, we will notify you before your personal information is transferred and becomes subject to a different privacy policy.
Segment [1]
> We may sell, transfer or otherwise share some or all of our business or assets, including your personal information, in connection with a business deal (or potential business deal) such as a merger, consolidation, acquisition, reorganization or sale of assets, or in the event of bankruptcy, in which case we will make reasonable efforts to require the recipient to honor this Privacy Policy.
Repl.it [2]
> We share or disclose information only in the following cases ... - As necessary in the event of a proposed or actual reorganization, merger, sale, joint venture, assignment, transfer, financing, or other disposition of all or any portion of our business, assets, or stock.
Those are about your data as a customer though. It's obvious that if a company is acquired, the new owner also takes the customer list, and active customers have very different rights regarding data protection than the customer's customers that visit their website and do not know that data is being collected about them.
If e.g. Google would sell Google Analytics to Facebook, they cannot use the Analytics data to track users and send them emails, since it wasn't originally agreed upon with the GA-users. They very much can send an email to every GA user and offer them the new FBGA premium service.
IME companies change privacy policy seemingly on a whim, and present current users with an interstitial next time they try and log in, gating the immediate gratification of use of the service with a big green OK button, virtually guaranteeing acceptance.
It would be much harder for Stripe to do that transitively, though, and presumably the vendors, i.e. Stripe's customers, can't grant this on users' behalf.
Generally speaking, it's pretty shocking how utterly abysmal crisis/damage-control PR is for companies. Rather than "never letting a good crisis go to waste", most companies/leaders just dig a deeper hole.
A small part of me would love to just start a Crisis PR firm for tech companies.
Regardless of who's right or wrong, it's really nice to see a leader come out and actually face criticisms with a cool head, and at least from my point of view, not bullshit legal language. Even better if it does encourage positive change.
(Specifically about Stripe, I am positively biased because once I submitted some feedback and their product team immediately jumped to communicate with me as to how to best design and implement the feature.)
I don't think most companies have the capacity to handle it well in the first place. I think the outliers like Stripe are different because they have a very hands on CEO who can cut through all the tape, IIRC they also have a fairly learn and very technical organization with strong domain knowledge in areas where the tape is cut. Most orgs are non-engineering orgs, most CEOs are not technical, most large orgs have far too much bureaucracy to cut through it.
If you're a CEO or a senior executive, I personally would expect that you're 100% capable of responding to criticism without losing your mind or spending $5,000 for a lawyer to send you some copy-pasta of "We take your feedback very seriously and will consider your opinion." and then never doing anything.
I'm not suggesting the leader be the one to personally go and fix the problem, but they certainly should have the communication skills to navigate it and organize a solution.
I feel like many companies don’t want to commit to giving up a potential revenue stream, even if they’re not tapping it. So you get ignored or mealy mouth responses.
I think the real difference here is that pc has had morals and a moral biz model from the getgo. He doesn't have to try to half-apologize for something that is incredibly damning but essential to the business model. This instance was mostly just miscommunication, and he took quick, calm, and excellent steps to address the miscommunication.
I don't recall seeing such an amazing response to a critic blogpost from a company, ever. This is another big +1 for Stripe on my book. I am not a paying customer (yet!) because of life but already want to throw money at them!
I'm not so impressed. Instead of contacting authorities and privacy organizations, they decided that they had to design, implement and run this system by themselves. And instead of informing users, we had to find out from the work of a researcher. It's just bad. In their communication they are asking for forgiveness, but they should have asked for permission.
This is not how companies should deal with privacy.
Personally I think this has been a good pointer that we need to be careful about what we trust third party libraries and frameworks to do.
I in no way believe that Stripe had any intentions of doing anything wrong, however it is good to hold people accountable and ensure that what they do is above board. I have personal examples of companies caring very little about users data, except when they might be caught out for it.
>I in no way believe that Stripe had any intentions of doing anything wrong, however it is good to hold people accountable and ensure that what they do is above board. I have personal examples of companies caring very little about users data, except when they might be caught out for it.
Very much agree. I think Stripe is demonstrating responsible behavior here, and the best way to further encourage that is to show that people actually care what they do and will raise alarms when they overstep, even inadvertently.
If only PayPal were as accessible and responsive as stripe. There is a serious regression in their API right now : it is so bad and obvious it shouldn't of even made it past their internal testing stage. Been there for 2 weeks now. You think I can get anyones attention at paypal? They don't even seem to have a decent issue ticketing system to track it.
In fairness, Stripe also kind of brushed this off until it got more attention.
There are StackOverflow posts going back to 2017[0] and Github issues with direct acknowledgement from Stripe employees with no solution offered.[1]
I even reached out to Stripe support before publishing my first post, and they told me that the collection behavior was by design and in my users' best interest.[2]
I've been very impressed by Stripe's response here, but it's demonstrably not the same response they deliver to customers who go through normal support channels.
I’m sure I’ll get downvoted but why should it be? Stripe has thousands of items in the backlog across many areas, and in a larger company there’s prioritization at many different levels.
I’m happy that they addressed this but I often see on HN that folks expect that an email to support staff gets the same level of support/awareness as a highly viewed post on HN does.
As a Stripe customer, there are several things that I’d love to see improved or modified but I don’t expect all, if any, of them to make it into the roadmap immediately as they’re trying to scale & fix really big issues that have already been identified.
Do I wish it was possible for businesses to address every single customer/consumer complaint? Of course, but that’s not the reality we live in.
Also - I’m not letting any company off the hook with this statement, there’s plenty of companies out there that intentionally neglect glaring issues because they don’t want to deal with the noise that comes along with it but Stripe hasn’t really even been one of those companies.
Sometimes it is the best company policy to ignore items until they go away, and to deal with the ones that rise to the top naturally.
>I’m sure I’ll get downvoted but why should it be? Stripe has thousands of items in the backlog across many areas, and in a larger company there’s prioritization at many different levels.
>I’m happy that they addressed this but I often see on HN that folks expect that an email to support staff gets the same level of support/awareness as a highly viewed post on HN does.
I agree that Stripe of course can't give the same time and attention to every support request that they give to issues that bubble to the top of HN. The parent commenter was saying that PayPal didn't escalate as well as Stripe, and I was pointing out that Stripe didn't prioritize this either until it got attention.
But one point I'd like to add is that not all issues are equal. If there's an issue like an account takeover vulnerability, I think most people would agree that something is seriously wrong if a company only gives it top priority when it receives publicity. And then there are minor issues like "why don't you support dark mode?" I think it's fine if dark mode got regular priority and then got bumped up when there was a massive outcry where thousands of users said they were desperate for dark mode.
When people criticize a company for only addressing an issue when it reaches the front page of HN, the argument is that the company's internal process for prioritizing the issue failed. But this criticism is always going to be subjective because everyone has their own particular priorities of what should be fixed and at what priority. It's also limited in that commenters have no insight into the competing priorities within the company.
I think it is appropriate to criticize a company for failing to give issues proper priority until they get more attention, but I think you're right that we should be doing it with an appropriate degree of humility, recognizing that prioritization is subjective and we don't have all the information.
"We do not use, share, rent or sell the Personal Data of our Users’ Customers for interest-based advertising. "
Better version would be all advertising instead of interest-based advertising Also "personal" data excludes lots of data. Personal data just means data that is attached an identified person. Lot of ad targeting is at an anonymous ID, they don't really know the person.
This is not how any of this works. You don't write a privacy policy listing all the things you don't do; you write it listing and justifying the things that you do.
They literally wrote what they won't do. They were just very specific with it, which suggests they may use, share, rent and sell the personal data for non-interest-based advertising, e.g. demographic-based advertising and want to keep the option on the table.
I understood from the start that this data was for fraud protection. At the time of my initial article, Stripe had not clearly disclosed the extent of their tracking nor stated any limitations on how they would use the data. I tried hard to avoid accusing Stripe of nefarious behavior, so if there are specific sections in my post that failed to do this, please let me know.
Regardless of Stripe's intentions, I believe there needs to be clear agreement about what data Stripe collects and what limits they'll observe in using that data. If we blindly allow Stripe to collect whatever data their JS library has access to as long as their intentions are good, we put ourselves at risk if that data falls into the wrong hands.
I think Stripe shows a serious commitment to privacy and security, but there's always an inherent risk in storing copies of data with a third party. The more data that Stripe collects, the greater that risk, so clients should have a say in whether that increase in risk is worth the improvement they receive in the accuracy of Stripe's fraud protection.
> I understood from the start that this data was for fraud protection.
If we're being honest with ourselves, the title of your original blog post ("Stripe is Silently Recording Your Movements On its Customers' Websites") is worded like they're being being sneaky and have something to hide.
I gave a lot of thought to how to word it to not project intention onto Stripe. But I did think one of the most important parts of the story was Stripe's lack of disclosure about the behavior.
I considered and rejected "secretly" and "surreptitiously" because they suggested intention. "Silently" was the best word I could think of to convey the lack of disclosure while minimizing judgmental undertones. I understand that it still does suggest something underhanded, so maybe it would have been better for me to omit the word entirely.
How about "Stripe records Your Movements On its Customers Websites"? Does it still not convey the meaning? But yeah, click bait titles drive traffic to the blog and to your website (portfolio rebalancer) that you linked in your blog post. May be you will end up in page 1 of Google when some one searches "Stripe Privacy". Smart strategy and all in all a win :-)
"Stripe records cursor movement on customer websites as part of its fraud control efforts" - that's probably the real title. But obviously doesn't get the traffic.
> [..] we put ourselves at risk if that data falls into the wrong hands.
This argument confuses me. You you are willing to trust Stripe with your customers' address and credit card details. You trust that their Javascript doesn't send this to an attacker.
What other data are you worried about falling into the wrong hands?
Oh, there's tons of sensitive data beyond just financial details.
As an extreme example, suppose I ran a paid email service and allowed Stripe to collect any data they wanted, including page contents and keystrokes. That would give Stripe a massive amount of sensitive user data.
As a more realistic example, suppose that I ran a dating site and the log of URLs that Stripe currently collects exposes which profiles users are viewing and whom they're communicating with. If a user's credit card details are stolen, that's a bummer, but it happens all the time. If a user's dating site behavior was published, many people would consider that a serious violation more severe than having to order a new credit card.
If you have ANY third-party scripts running on your site you have a risk that they are spying on your users by choice or they've been hacked, e.g. Ticketmaster/Magecart[1].
In both your examples, you'd want to restrict what third-party code lives on what part of the site. In a similar way, you don't want your adtech partners running code on your checkout pages. You want to remove the need to trust entirely.
Your second scenario doesn't feel that realistic at all. You are worried that Stripe is going to have enough URLs logged to have a useful dating history for a user and then somebody is going to hack Stripe to gain access to this data (perhaps a nefarious employee), exfiltrate enough of it to reconstruct, then publish the history.
If this is a concern, you should have total control over your entire infrastructure. If you are on AWS perhaps there's a chance that somebody will hack ELB so they can get a complete history of all your users too?
>If you have ANY third-party scripts running on your site you have a risk that they are spying on your users by choice or they've been hacked, e.g. Ticketmaster/Magecart[1].
>In both your examples, you'd want to restrict what third-party code lives on what part of the site. In a similar way, you don't want your adtech partners running code on your checkout pages. You want to remove the need to trust entirely.
Yes, I agree. I wrote my first post because I believed many users mistakenly thought that Stripe wouldn't execute until the user called loadStripe, as I found it unintuitive that Stripe actually loaded and began tracking before the app ever called the library. The post included steps for limiting Stripe to individual pages and using CSP to enforce protections.
>Your second scenario doesn't feel that realistic at all. You are worried that Stripe is going to have enough URLs logged to have a useful dating history for a user and then somebody is going to hack Stripe to gain access to this data (perhaps a nefarious employee), exfiltrate enough of it to reconstruct, then publish the history.
>If this is a concern, you should have total control over your entire infrastructure. If you are on AWS perhaps there's a chance that somebody will hack ELB so they can get a complete history of all your users too?
To clarify, I don't believe that it's the most likely vector of attack. If I'm a small enough player that I need to rely on Stripe for payment processing, Stripe almost undoubtedly has a better security team than I do.
I'm just saying that in line with your first point, the safest form of trust is no trust at all. If Stripe gives me the ability to limit how much data they collect from my site, it reduces the risk of the data being leaked in transit or in Stripe's storage. I agree those risks are low given Stripe's track record, but they're still higher than if Stripe wasn't collecting sensitive data at all.
Script makers have a an implicit (and explicit mandate in the EU) responsibility to be upfront with what they do. No one will be happy if stripe or Google Analytics started including a bitcoin miner.
In this example, stripe did not exactly disclose what they collected or how they use it at first. They did not provide a way to opt out. Now they do.
It seems a diversion to compare this to someone hacking ELB and stealing data. Yes, all data can be hacked, just like how governments CAN warrantlessly wiretap you through FISA. It doesn’t mean we shouldn’t fight for 4th amendment when the government raids your house without a search warrant.
> Stripe updated their JavaScript library to give clients the ability to opt-out of deep data collection. They can now load the <script> tag with the advancedFraudSignals=false parameter to disable this functionality:
If this is set on the client-side, what stops an attacker from editing the page to disable the fraud detection sites that want to use it?
Sure, but that in and of itself would be a major fraud signal. If 99% of the traffic from a site is coming into their fraud system, and yours isn't, that would be an even bigger fraud signal that if it were on.
They mention the use of a script parameter. Can't bots just set this parameter on any website using stripe to bypass this detection, or is this enforced on Stripes end as well?
I am sure it is enforced on the Stripe backend. Basically it sounds like there are two options:
1. Do not set the script parameter, let Stripe collect the data, and have them do fraud detection, which will result in better risk scores and more transactions approved.
2. Do set the parameter, prevent Strip from collecting the data, and prevent them from doing the fraud detection (since they have no data to feed the detector). This may result in a higher risk score (meaning higher fees) and/or fewer transactions approved.
Bots that use stolen cards to make purchases (or use legitimate SaaS apps as a vector to test if a card number if valid)
Stripe "tracks" user data that they run through some fancy ML thing to try to detect if the person is a bot or a real human -- based on, presumably, patterns in user mouse movement, delay in moving between inputs, interval between keystrokes, etc.
But we have other ways of testing for bots. See for example Google's Recaptcha (again, example, and not my main point). I don't see why we need to give away our personal information to yet another big company, especially if the information comes from web surfing behavior that has nothing to do with payment.
And in case this is all still necessary, can't this be handled by some trusted party instead of the company that already knows about all our online payment transactions? Compartmentalization is a very important concept in user privacy.
How do you think ReCaptcha (at least ReCaptchaV3) works? It's gathers the same kind of "personal" data (mouse movements, etc.) to feed an ML model to determine whether the client is a robot.
And it adds much more user friction, essentially requires having a logged in Google account, and may not be as accurate. Nevermind that it is outsourcing that protection to Google, who will definitely use your personal data to sell targeted ads. I don't think Stripe's fraud detection behavior is unreasonable here, and if you're willing to accept fraud liability, you're given the option to disable it (and run your own recaptcha, if you like).
> In contrast, Stripe collects also data from webpages that are not payment pages.
Like recaptcha, whether the Stripe code is included on a given page is solely up to the author of that page.
While I may tend to agree with OP's requests for increased transparency, that desire does not lend its support to other claims about how Stripe's code works. Putting it on every page is not required. Unless I am mistaken, putting it on every page is not even suggested by Stripe. Why anyone would put Stripe or any other third-party code on every page indiscriminately, without considering whether it was necessary, is beyond me.
> Include the Stripe.js script on each page of your site—it should always be loaded directly from https://js.stripe.com, rather than included in a bundle or hosted yourself.
> To best leverage Stripe’s advanced fraud functionality, include this script on every page, not just the checkout page. This allows Stripe to detect suspicious behavior that may be indicative of fraud as customers browse your website.
You realize for recaptcha to work best you are supposed to use it on all forms and actions and background of pages?
"reCAPTCHA works best when it has the most context about interactions with your site, which comes from seeing both legitimate and abusive behavior. For this reason, we recommend including reCAPTCHA verification on forms or actions as well as in the background of pages for analytics."
When you say reCaptcha doesn't capture user data are you lying? Have you actually implemented any of this and tried to fight fraud. I ask because you and the original author are making a lot of big claims and ill intent assumptions that literally ANYONE dealing with large scale fraud attempts would see through immediately.
Seriously, everyone else is sticking all sorts of beacons on websites for this - that's currently how it is being done.
I'm not sure Google's Recaptcha is a good example. They use the same methods and their business model is using your personal data to target ads to you.
> Perhaps you have no sympathy for web applications that store sensitive data in query strings, as that’s widely recognized as an insecure pattern. The URL fragment is more serious. That otherwise is a safe way to store sensitive information, so it’s alarming to see a third-party library sending a copy to an external server.
> Firefox Send and Mega.nz are both examples of popular web apps that use the URL fragment to store client-side encryption keys so that users can save end-to-end encrypted files to the cloud without the server ever having access to the underlying data.
The URL fragment is not designed to be any more secure than anything else in the URL, it's just a funny quirk of how web browsers evolved that it doesn't happen to be sent to the webserver. That popular platforms are (mis)using it to pass information without that information hitting their webservers is unfortunate. But it doesn't mean that the URL Fragment is somehow special or should be thought of as "secure" - that's not a guarantee that the URL scheme makes.
For example, those fragments will easily appear in browser history for anyone else who uses your same device...