Tag Archives: Developer tips

Letter To The European Commission About Age Verification And Social Networks

от Божидар Божанов
лиценз CC BY

My previous post here in August was about the age verification plans of the European Commission. Since then the EC has proposed the EU KIDS Act, which implements the idea of age verification.

Yesterday I presented the alternative approach – heavily relying on parental control apps – on the OpenFest conference. Apart from proposing a local legislation in Bulgarian parliament, I’ve sent a letter the the European Commission. You can find it here. The text is as follows:


Dear President von der Leyen,
Dear Executive Vice-President Virkkunen,

Subject: The right approach to protecting children from the negative effects of social media

I’m writing this letter as a member of parliament from Bulgaria, as a former minister for digital transformation, as a technical expert and as a father.

Protecting children online has become a priority for the European Commission and for many EU governments, and rightly so. The threats online, the negative psychological effects of addictive designs and the algorithms that prioritize virality over quality have significant negative effects on children.

The European Commission has started addressing the addictive design problem, analyzes algorithmic bias and has undertaken an age verification initiative, in addition to long-term measures against CSAM, online crimes against children, etc.

While we all see the good intentions behind these initiatives, they sometimes lack the technical depth and the ambition to achieve swift results. My focus in this letter will be age verification, as the measure that is the most polarizing and may have significant negative side effects if done wrong. And I’m concerned that the currently selected approach by the European Commission is the wrong one.

The idea sounds simple – “social networks are proven to be detrimental to children’s mental health, and so they must not be allowed to use it. The way to do it is to add an age check before registration, so that only adults can use the service”. While simple to formulate, it’s much more difficult to implement, if not impossible.

There is an inherent paradox – if a solution is fully privacy-preserving, it’s ineffective. If it’s effective, it bears significant risks to privacy, as it will require every citizen to prove their identity online in order to use everyday services.

The European Commission has made a well-meaning attempt to design and implement a proper zero-knowledge proof of age. It’s a great tool, with proper cryptography, complex-yet-elegant. It has “just” one problem – it doesn’t account for the actual “threat actor” in this scenario – the user, who would try many things to circumvent the age limitation. As security consultant Paul Moore has brilliantly shown, you don’t have to compromise the age verification app in order to circumvent the flow – by a simple relay attack, where you just present someone else’s verified age credentials in order to use a service. The proof of concept was implemented as a chrome extension which relays age checks to 3rd party service, backed by an over-18 person’s device, which sends the proof to the service. That way a single adult can verify the accounts of all minors, and because of the necessary privacy guarantees, the relying party (the social network) won’t even know.

This is very likely to happen – “age verification as a service” providers will certainly pop-up to help minors get into social networks. What’s worse – some of these providers may collect children’s personal data, including phone number or social network account ID, in order to provide them with the much coveted proof of age. That data, purposefully or after an inevitable data breach, may be used by sex predators to target children. There are completely realistic nightmare scenarios, born from the good intention to limit the negative effects of social networks.

Even in a school context, a single over-18 (or over-16) student can lend their age verification app to help younger children register profiles. What are policy makers going to do then? Issue administrative fines for sharing age tokens/attestations? Criminalize it?

Any attempt to fix that technically, breaks the privacy guarantees; any attempt to fix it legally, is doomed to fail in enforcement.

My advice, in all my capacities listed in the beginning of this letter, is to abandon that approach and focus on a different approach – rely on parental control apps.

Parental control apps remain rudimentary, and perhaps there are reasons for this. They are not widely used and are often unintuitive and unreliable. However, they can be regulated and improved. They can also incorporate government-mandated lists of apps and domains restricted for children according to age. For example, a child protection agency could publish a list that parental control apps would be required to import automatically. Legislators could also require these apps to be pre-installed on every phone sold in their country. Parents would remain in control and could adjust the settings if they considered their children ready to use particular services responsibly.

Certain apps can be banned for under-14, others for under-16 and others – for under-18. Governments would have much better control over the exact services they deem risky for children, without the need for any changes on the service’s side. Or, if an app vendor wants to have it whitelisted, they may have to implement children-friendly versions.

Going further, this may eventually lead to platform-level parental control APIs, so that each app can read parental control settings, and on the other hand export parental control configuration options to be used in the parental control app.

What’s even better about this approach, is that VPNs can’t be used to circumvent it – it’s a device-level limitation, not service-level limitation, which needs to figure out the country of the user, which can only be done by their IP address.

And It’s completely privacy-preserving, as users don’t have to show or prove anything to anyone.
Of course, the harder part is making sure every child and parent has a parental control app installed. Information campaigns and teachers can help with that, and I’m sure it will achieve much better results than what we are seeing in Australia for example.
Even if the right age limitation measures are implemented, the efforts to limit the addictiveness and so-called “brainrot” on online platforms should continue.
We have proposed national legislation to implement the approach above. But in order to avoid fragmentation in the digital single market, and in order to have a working, cross-border model, where the experience of each country improves the model EU-wide, a solution should be discussed on a EU-level.

Yours sincerely,
Bozhidar Bozhanov,
Member of parliament of the Republic of Bulgaria

The post Letter To The European Commission About Age Verification And Social Networks appeared first on Bozho's tech blog.

Wiretap Detector App For Catching IMSI Catchers

от Божидар Божанов
лиценз CC BY

Cell-site simulators (also sometimes called Stingrays and IMSI-Catchers) are interception devices used to spy on mobile network communication. A couple of volunteers, including myself, have built an app – Wiretap Detector – that uses heuristics to detect these devices. Below are the slides from a talk that I have (in my native language) on a local tech conference.

It works by applying the following:

  • Compares public IP with the announced IP ranges of the telecom – Gets ASN based on the initial IP and uses https://ip.guide
  • Detects changes on the first 2 hops of traceroute
  • Detects changes in the combination of (geocoordinates, cell identifier)

No such application is perfect or guaranteed to detect interception, because of the nature of the mobile technology. Furthermore, it can’t detect legal interception using direct streaming of calls and messages from the telecom to an interception interface at some government agency.

The app is open source, feel free to contribute. There is a long TODO list, which would improve detection and user experience

The post Wiretap Detector App For Catching IMSI Catchers appeared first on Bozho's tech blog.

Don’t Reinvent Date Formats

от Божидар Божанов
лиценз CC BY

Microsoft Exchange has a bug that practically stops email. (The public sector is primarily using Exchange, so many of the institutions I’m responsible for as a minister, have their email “stuck”). The bug is described here, and fortunately, has a solution.

But let me say something simple and obvious: don’t reinvent date formats, please. When in doubt, use ISO 8601 or epoch millis (in UTC), or RFC 2822. Nothing else makes sense.

Certainly treating an int as a date is an abysmal idea (it doesn’t even save that much resources). 202201010000 is not a date format worth considering.

(As a side note, another advice – add automate tests for future timestamps. Sometiimes they catch odd behavior).

I’ll finish with Jon Skeet’s talk on dates, strings and numbers.

The post Don’t Reinvent Date Formats appeared first on Bozho's tech blog.

Simple Things That Are Actually Hard: User Authentication

от Божидар Божанов
лиценз CC BY

You build a system. User authentication is the component that is always there, regardless of the functionality of the system. And by now it should be simple to implement it – just “drag” some ready-to-use authentication module, or configure it with some basic options (e.g. Spring Security), and you’re done.

Well, no. It’s the most obvious thing and yet it’s extremely complicated to get right. It’s not just login form -> check username/password -> set cookie. It has a lot of other things to think about:

  • Cookie security – how to make it so that a cookie doesn’t leak or can’t be forged. Should you even have a cookie, or use some stateless approach like JWT, use SameSite lax or strict?
  • Bind cookie to IP and logout user if IP changes?
  • Password requirements – minimum length, special characters? UI to help with selecting a password?
  • Storing passwords in the database – bcrypt, scrypt, PBKDF2, SHA with multiple iterations?
  • Allow storing in the browser? Generally “yes”, but some applications deliberately hash it before sending it, so that it can’t be stored automatically
  • Email vs username – do you need a username at all? Should change of email be allowed?
  • Rate-limiting authentication attempts – how many failed logins should block the account, for how long, should admins get notifications or at least logs for locked accounts? Is the limit per IP, per account, a combination of those?
  • Captcha – do you need captcha at all, which one, and after how many attempts? Is Re-Captcha an option?
  • Password reset – password reset token database table or expiring links with HMAC? Rate-limit password reset?
  • SSO – should your service should support LDAP/ActiveDirectory authentication (probably yes), should it support SAML 2.0 or OpenID Connect, and if yes, which ones? Or all of them? Should it ONLY support SSO, rather than internal authentication?
  • 2FA – TOTP or other? Implement the whole 2FA flow, including enable/disable and use or backup codes; add option to not ask for 2FA for a particular device for a period of time? Configuring subset of AD/LDAP users to authenticate based on certain group memberships?
  • Force 2FA by admin configuration – implement time window for activating 2FA after a global option is enabled?
  • Login by link – should the option to send a one-time login link be email be supported?
  • XSS protection – make sure no XSS vulnerabilities exist especially on the login page (but not only, as XSS can steal cookies)
  • Dedicated authentication log – keep a history of all logins, with time, IP, user agent
  • Force logout – is the ability to logout a logged-in device needed, how to implement it, e.g. with stateless tokens it’s not trivial.
  • Keeping a mobile device logged in – what should be stored client-side? (certainly not the password)
  • Working behind proxy – if the client IP matters (it does), make sure the X-Forwarded-For header is parsed
  • Capture login timezone for user and store it in the session to adjust times in the UI?
  • TLS Mutual authentication – if we need to support hardware token authentication with private key, we should enable TLS mutual. What should be in the truststore, does the web server support per-page mutual TLS or should we use a subdomain, if there’s a load balancer / reverse proxy, does it support it and how to forward certificate details?
  • Require account activation or let the user login immediately after registration? Require account approval by back-office staff?
  • Initial password setting for accounts created by admins – generate initial password and force changing it on first login? Don’t generate password and start from a password reset flow?
  • Login anomalies – how to detect them and should you inform the user? Should you rely on 3rd party tools (e.g. a SIEM), or have such functionality built-in?

And that’s for the most obvious feature that every application has. No wonder it has been implemented incorrectly many, many times. The IT world is complex and nothing is simple. Sending email isn’t simple, authentication isn’t simple, logging isn’t simple. Working with strings and dates isn’t simple, sanitizing input and output isn’t simple.

We have done a poor job in building the frameworks and tools to help us with all those things. We can’t really ignore them, we have to think about them actively and take conscious, informed decisions.

The post Simple Things That Are Actually Hard: User Authentication appeared first on Bozho's tech blog.

Obtaining TLS Client Certificates In Spring Integration

от Божидар Божанов
лиценз CC BY

Spring Integration is a very powerful and extensible framework for, well, integrations. But sometimes it’s not trivial how to get some information that yo need. In my case – a certificate used for mutual authentication in a TLS (syslog over TLS) connection. You have a Java method that receives a Message and ideally you’d want to get the certificate chain used by the client to authenticate itself (e.g. you may need to extract the CN).

Fortunately, Spring Integration is flexible. And it can be done, but it’s a bit convoluted. I’ll use XML notation, but the same can be achieved through Java config.

<bean id="nioConnectionSupport" class="com.yourcompany.util.net.TLSMutualNioConnectionSupport">
        <constructor-arg ref="sslContextSupport" />
        <constructor-arg value="false" />
</bean>
<bean id="interceptorFactoryChain" class="org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain">
        <property name="interceptors">
            <bean class="com.yourcompany.util.net.TLSSyslogInterceptorFactory" />
        </property>
</bean>

<int-ip:tcp-connection-factory id="tlsConnectionFactory" type="server" port="${tcp.tls.port}"
                                   using-nio="true" nio-connection-support="nioConnectionSupport"
                                   single-use="false" interceptor-factory-chain="interceptorFactoryChain" />

The sslContextSupport would typically be a org.springframework.integration.ip.tcp.connection.DefaultTcpSSLContextSupport or a custom implementation (e.g. if you want to use a “blind” trust store)

Then you’d need the two classes. You can check them at their respective gists: TLSSyslogInterceptorFactory and TLSMutualNioConnectionSupport.

What do these classes do? The TLSSyslogInterceptorFactory sets a new header for the message that contains the client ceritficates. The TLSMutualNioConnectionSupport class sets the “wantClientAuth” option on the SSL Engine. There is another option – “needClientAuth” which would for client authentication, rather than just support it. Depending on the use case you can use one or the other.

Then you can obtain the certificates at your handler method via:

Certificate[] certificates = (Certificate[]) message.getHeaders().get(TLSSyslogInterceptorFactory.TLS_CLIENT_CERTIFICATES);

A small tip I wanted to share to help the next one trying to achieve that.

The post Obtaining TLS Client Certificates In Spring Integration appeared first on Bozho's tech blog.

Every Serialization Framework Should Have Its Own Transient Annotation

от Божидар Божанов
лиценз CC BY

We’ve all used dozens of serialization frameworks – for JSON, XML, binary, and ORMs (which are effectively serialization frameworks for relational databases). And there’s always the moment when you need to exclude some field from an object – make it “transient”.

So far so good, but then comes the point where one object is used by several serialization frameworks within the same project/runtime. That’s not necessarily the case, but let me discuss the two alternatives first:

  • Use the same object for all serializations (JSON/XML for APIs, binary serialization for internal archiving, ORM/database) – preferred if there are only minor differences between the serialized/persisted fields. Using the same object saves a lot of tedious transferring between DTOs.
  • Use different DTOs for different serializations – that becomes a necessity when scenarios become more complex and using the same object becomes a patchwork of customizations and exceptions

Note that both strategies can exist within the same project – there are simple objects and complex objects, and you can only have a variety of DTOs for the latter. But let’s discuss the first option.

If each serialization framework has its own “transient” annotation, it’s easy to tweak the serialization of one or two fields. More importantly, it will have predictable behavior. If not, then you may be forced to have separate DTOs even for classes where one field differs in behavior across the serialization targets.

For example the other day I had the following surprise – we use Java binary serialization (ObjectOutputStream) for some internal buffering of large collections, and the objects are then indexed. In a completely separate part of the application, objects of the same class get indexed with additional properties that are irrelevant for the binary serialization and therefore marked with the Java transient modifier. It turns out, GSON respects the “transient” modifier and these fields are never indexed.

In conclusion, this post has two points. The first is – expect any behavior from serialization frameworks and have tests to verify different serialization scenarios. And the second is for framework designers – don’t reuse transient modifiers/annotations from the language itself or from other frameworks, it’s counterintuitive.

The post Every Serialization Framework Should Have Its Own Transient Annotation appeared first on Bozho's tech blog.