A few months ago I came across a productive UI5 app that was also promoted on several channels and events. The interesting thing - to me - about this app was the usage of Web Components. On a YouTube đź”— video the architecture of the app đź”— was shared which allowed me to get an overview of the architecture. And the URL đź”— of the app was part of the video. As I click links and know things, I opened the app in my browser and started the dev tools.
The app
The web shop is a UI5 (freestyle) app. The site now looks differently compared to when I accessed it a few months ago. The direct links to the products or shopping car are gone. If you want to know how it looked before: there is the dev version of the app đź”—.
Left: dev version, right: productive version

Even with the navigation now gone, looking at the manifest file reveals some navigation targets. Here is one of the problems with these kinds of apps. Instead of having one for the public audience, and one for the authenticated users, these apps try to (or must) serve both audiences. UI5 apps are like OData services: their metadata is telling a lot about them.

There is a view for searching the catalog 🔗. This won’t reveal much as no data is retrieved.

OData services
Navigating through the app is nice, but most information comes from a backend. The OData information is in the manifest.json file.

There is one public and one private services. This means: the same app is for anonymous and authenticated users. This mixing of target groups in one app is nice. Customer has only one app to commission, outside users like me have only one app to use and analyze, and the developers must combine two different user cases in one app. Something that rarely works at first try.
The private service is protected by log-in, the public service đź”— (metadata đź”—) not.

The service already comes with annotations, but there are additional annotations available for both services. For the protected OData service, you can get annotations from the app.
https://webshop.stadt-zuerich.ch/public/annotations/annotation.xml đź”—
https://webshop.stadt-zuerich.ch/public/annotations/annotation_public.xml đź”—
The public service is accessible and is annotated. This is nice as it allows you to use the service as a source for your own Fiori Elements app. Nothing fancy. But still nicer than to read the raw OData output. For instance, for entity set Documents:

With this simple “trick” I was able to create a Fiori App for the entity set ShopOrder. This entity was removed rather quickly after reporting my findings. If you want to know why, continue reading.
Customer provided data
Using ShopOrder đź”— as the starting entity for the Fiori Elements app, I got a list with (many) entries as well as a detail page.
List:

Details:

There is some personal data included.
"CPD_Email": "___",
"CPD_FormOfAddress": "___",
"CPD_CustomerFullName": "___",
"CPD_StreetName": “___",
"CPD_HouseNumber": "___",
"CPD_CityName": "ZĂĽrich",
"CPD_PostalCode": "8037",
"CPD_Country": "CH",
Using a public telephone book service đź”— to see if the data matches some real persons: yes, real data.
Data leakage
Personal data from users of the web shop was accessible to anyone. Here I stopped, reported this to someone I knew worked with the app. I am not sure about the status of GDPR and Switzerland, but I guess this is also a problem there. As always, I assume that all following actions were carried out in accordance with the regulations. In case you are a user of the web shop, maybe you want to check if you are affected or not. All I know is that the entity ShopOrder was removed from the public service and the service and app are now better protected.
A common pattern is repeated here: the app tries to do too much: serve anonymous and authenticated users. This can work but is risky. The better approach is to separate the app and therefore the service based on the user. Have one app for anonymous users, and one app for authenticated users. Ask the question: is an app really needed for the anonymous user? Can a static web site be an alternative? In the backend, the anonymous service is often a copy of the one for authenticated users. This can be done, but also try to create separate services: separate service definition and coding. What is not exposed, cannot be leaked.