... | @@ -31,19 +31,45 @@ A proposal is to have it as the user information, which would have two benefits: |
... | @@ -31,19 +31,45 @@ A proposal is to have it as the user information, which would have two benefits: |
|
1. it would match the order on the bridge string;
|
|
1. it would match the order on the bridge string;
|
|
2. we would have a separate URI part for it.
|
|
2. we would have a separate URI part for it.
|
|
|
|
|
|
The alternative is placing it after the fingerprint, separated with a slash. Both are optional, but the fingerprint has a fixed length, and the transports are just a few known strings, so detecting them should be trivial anyway.
|
|
The alternatives are placing it after the fingerprint, separated with a slash, or to have the transport in the query string.
|
|
|
|
|
|
The final alternative is to have the transport in the query string.
|
|
|
|
|
|
|
|
## Other parameters
|
|
## Other parameters
|
|
|
|
|
|
Other parameters depend on the transport. They can be added to the query, percent-encoded, and separated by an ampersand. On the final bridge string, they will be separated by a space. The parameter order must be preserved when converting the bridge URL to the bridge string.
|
|
Other parameters depend on the transport. They can be added to the query, percent-encoded, and separated by an ampersand. On the final bridge string, they will be separated by a space. The parameter order must be preserved when converting the bridge URL to the bridge string.
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
A vanilla bridge without transport:
|
|
|
|
```
|
|
|
|
bridge://38.229.1.78:80/C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4
|
|
|
|
```
|
|
|
|
|
|
|
|
An obfs4 bridge:
|
|
|
|
```
|
|
|
|
bridge://38.229.1.78:80/C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4/obfs4?cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg&iat-mode=1
|
|
|
|
```
|
|
|
|
|
|
|
|
The builtin snowflake bridge:
|
|
|
|
```
|
|
|
|
bridge://0.0.3.0:1/2B280B23E1107BB62ABFC40DDCC8824814F80A72/snowflake
|
|
|
|
```
|
|
|
|
|
|
|
|
A meek bridge:
|
|
|
|
```
|
|
|
|
bridge://0.0.2.0:2/97700DFE9F483596DDA6264C4D7DF7641E1E39CE/meek?url=https%3A%2F%2Fmeek.azureedge.net%2F&front=ajax.aspnetcdn.com
|
|
|
|
```
|
|
|
|
|
|
|
|
# Recommendations to implementers
|
|
|
|
|
|
|
|
There is a long history of attacks based on custom URIs[^1][^2][^3], they tend to open a door for remote attackers to execute programs locally. We have to assume a bridge URI might be forged by a remote attacker, and sanitize them before using them.
|
|
|
|
|
|
|
|
Every implementation should sanitize the URIs carefully, for example remove any exploitable characters, like `%0A` (the new line character) that might be used to inject commands into the `torrc`.
|
|
|
|
|
|
# The HTTP(S) fallback
|
|
# The HTTP(S) fallback
|
|
|
|
|
|
The disadvantage of a custom scheme is that applications may only recognize a few common ones (`http`, `https`, `mailto`, etc...).
|
|
The disadvantage of a custom scheme is that applications may only recognize a few common ones (`http`, `https`, `mailto`, etc...).
|
|
|
|
|
|
On Android, apps can be registered as handlers for HTTP links with a specific host.
|
|
On Android, apps can be registered as handlers for HTTP links with a specific host[^4].
|
|
|
|
|
|
For other platforms, the URL could be opened on the browser, which could, in turn, redirect to the `bridge://` URL. We should also add the decoded bridge string, the instructions to add it to Tor Browser/other apps, and a small introduction to bridges/Tor.
|
|
For other platforms, the URL could be opened on the browser, which could, in turn, redirect to the `bridge://` URL. We should also add the decoded bridge string, the instructions to add it to Tor Browser/other apps, and a small introduction to bridges/Tor.
|
|
|
|
|
... | @@ -53,9 +79,12 @@ As for the format, we could just base64-encode the bridge string. |
... | @@ -53,9 +79,12 @@ As for the format, we could just base64-encode the bridge string. |
|
|
|
|
|
# The QR code
|
|
# The QR code
|
|
|
|
|
|
Using the `bridge://` scheme makes the QR shorter and less dense.
|
|
We could use the `bridge://` scheme also for the QR codes.
|
|
|
|
|
|
However, we should implement its decoding and ask for camera permission on Android. This may be annoying for users of a privacy-focused app, but we could explain that it is needed only for this reason and that they can revoke it on the settings.
|
|
However, we should implement its decoding and ask for camera permission on Android. This may be annoying for users of a security/privacy-focused app, but we could explain that it is needed only for this reason and that they can revoke it on the settings.
|
|
|
|
|
|
|
|
Bridge URIs do not address the problem of multiple bridges in the same QR.
|
|
|
|
An idea could be to separate them by newlines.
|
|
|
|
|
|
# The human-friendly ID
|
|
# The human-friendly ID
|
|
|
|
|
... | @@ -63,7 +92,7 @@ Bridge sharing is prone to errors, especially if done through copy&paste. |
... | @@ -63,7 +92,7 @@ Bridge sharing is prone to errors, especially if done through copy&paste. |
|
|
|
|
|
Therefore, we have added a checksum of the bridge string to Tor Browser.
|
|
Therefore, we have added a checksum of the bridge string to Tor Browser.
|
|
|
|
|
|
It is the FNV-1a hash of the bridge string (trimmed of any leading and trailing white spaces). Since FNV-1a works on bytes, the bridge string should be converted to UTF-8, even though bridge strings use only ASCII characters currently.
|
|
It is the FNV-1a hash[^5] of the bridge string (trimmed of any leading and trailing white spaces). Since FNV-1a works on bytes, the bridge string should be converted to UTF-8, even though bridge strings use only ASCII characters currently.
|
|
|
|
|
|
For maximum compatibility amongst platforms, architectures, and programming languages, the hash is computed using **signed** 32-bit integers. We checked, for example, that the Tor Browser JS implementation is interoperable with a C++ implementation.
|
|
For maximum compatibility amongst platforms, architectures, and programming languages, the hash is computed using **signed** 32-bit integers. We checked, for example, that the Tor Browser JS implementation is interoperable with a C++ implementation.
|
|
|
|
|
... | @@ -85,5 +114,9 @@ Finally, the 32-bit hash is split into 4 (unsigned) bytes, which are used as ind |
... | @@ -85,5 +114,9 @@ Finally, the 32-bit hash is split into 4 (unsigned) bytes, which are used as ind |
|
|
|
|
|
* The original discussion, on legacy/trac#15035
|
|
* The original discussion, on legacy/trac#15035
|
|
* [Some implementations based on that discussion](https://gitlab.com/torproject/Bridge-URLs/)
|
|
* [Some implementations based on that discussion](https://gitlab.com/torproject/Bridge-URLs/)
|
|
* [Android Intent Filters](https://developer.android.com/guide/components/intents-filters), to associate URIs to apps
|
|
|
|
* [FNV hashes](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) |
|
[^1]: https://parsiya.net/blog/2021-03-17-attack-surface-analysis-part-2-custom-protocol-handlers/
|
|
\ No newline at end of file |
|
[^2]: https://blog.malwarebytes.com/exploits-and-vulnerabilities/2021/12/vulnerability-in-windows-10-uri-handler-leads-to-remote-code-execution/
|
|
|
|
[^3]: https://positive.security/blog/url-open-rce
|
|
|
|
[^4]: [Android Intent Filters](https://developer.android.com/guide/components/intents-filters), to associate URIs to apps
|
|
|
|
[^5]: [FNV hashes](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) |
|
|
|
\ No newline at end of file |