State of authentication
What's the state of the authentication system? How would you go about implementing it?
Do you mean kind of authentication , like, https://github.com/RobotWebTools/rosbridge_suite/blob/a09a964fb5956321aca3b296da367e21d3d2e044/ROSBRIDGE_PROTOCOL.md#2-the-rosbridge-protocol?
Something like that, basically to only allow connection from authenticated parties. Either by implementing auth described by the protocol or restricting the access in other ways. Would be interesting to hear your opinion about any options on how to achieve that.
Sorry for the delay, we haven't had any plan to implement the auth function. Currently, the ros2-web-bridge only offers some basic functions for the ROS2 system.
Would a PR be welcome?
Of course and you can share your idea using this thread to track the issue :)
nodejs ws library suggests auth through HTTP request by upgrading a client and forwarding to WebSocket connection. This seems quite straightforward and a much simpler option than implementing web bridge auth protocol. I've tested a dummy example here: https://github.com/simutisernestas/ros2-web-bridge/commit/c1759861164438781cdd0e7157892e24d01fe5a9#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346R115. Maybe it would be possible to take auth function as input from a user, which would decouple web bridge and client authorization and give a lot of flexibility when trying to achieve that. Let me know what do you think about this.
Also, the bridge buffer here https://github.com/simutisernestas/ros2-web-bridge/commit/c1759861164438781cdd0e7157892e24d01fe5a9#diff-c3f564a77784c0f2110861cc1cbb0cd3bfc98fe67af82d6b15396fe8d859128fR65 is not cleared if malformed input is sent. I think this is a bug.
Thanks for your investigations! I will take a look soon.
Hi @simutisernestas I have some questions
- If we use the
upgraderequest to take the auth, do developers send the request through the JS functions byroslibjsor they have to send it explicitly by them self? - After the
bridgereceives the auth, who will be responsible to verify it? (I suppose the service vendor which the client wants to request should do this instead of thebridge). - It seems that HTTP/2 doesn't allow the
upgrademechanism, it's for HTTP/1.1 only.
- ws connection is initialized inside
roslibjsas I understand here. There is no option to pass additional data like cookies, etc. I'm triggeringupgradeby simply connecting ws client to HTTP server portwscat -c ws://localhost:8080and the connection is forwarded if authentication is successful. However, sinceroslibjsdoesn't support passing additional data this would require changing connect function. Ideally, you would do something similar as mentioned here if cookies are present in the request:
**wsHttpServer**.on('upgrade', function (req, socket, head) {
var validationResult = validateCookie(req.headers.cookie);
if (validationResult) {
//...
} else {
socket.write('HTTP/1.1 401 Web Socket Protocol Handshake\r\n' +
'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'\r\n');
socket.close();
socket.destroy();
return;
}
//...
});
-
Good question. With the current toy example, you can simply bypass upgrading and connect directly to
ws://localhost:9090. Thus, authorization of the request must be handled too. What do you mean by service vendor? If I understand you correctly this would be handed over to a ROS2 node and authors providing the actual service implementation. Of course, this is possible but ROS2 users are taking advantage of many open-source packages which do not have such capabilities and those services would be open for attackers. Are there any other possibilities? Implementing authorization directly on the bridge seems cumbersome too. -
HTTP wiki page states: "Like HTTP/2, HTTP/3 does not obsolete previous major versions of the protocol.". I don't think that HTTP/1.1 is going away in the foreseeable future. Please correct me if I'm missing something.
P.S. If you have any other ideas on how to achieve authentication & authorization for ros2 web clients would be nice to hear them and explore any possible solution/implementations.
There is no option to pass additional data like cookies,
If we cannot call roslibjs directly, how can we take extra information used to authenticate? (considering running in a web browser without nodejs support)
service vendor
I mean if a client is sending requests to a service to do something (e.g. calculate the sum of two integer numbers), the service itself should decide whether to serve the request from a specific client.
As ROS2 uses DDS-Security, I'm wondering if we can leverage this feature? Some reference I found:
- https://design.ros2.org/articles/ros2_dds_security.html
- https://ubuntu.com/blog/what-is-sros-2
- https://github.com/ros2/sros2
and there is an open issue for the sros in rclnodejs.
If we cannot call
roslibjsdirectly, how can we take extra information used to authenticate? (considering running in a web browser without nodejs support)
One option would be to modify roslibjs to take in extra arguments like cookies when initializing a connection. This would allow to implement authentication scheme as described previously. However, access control must be handled in the bridge too in that case.
As ROS2 uses DDS-Security, I'm wondering if we can leverage this feature?
As I understand SROS2 allows to restrict certain nodes from subscribing/publishing to selected topics. ros2-web-bridge acts as a node in the network thus as far as SROS2 is concerned ros2-web-bridge is acting as a single user. One could disable any publishing from this node, which would remove any possibility of unauthorized write to a system. Yet this does not cover all use cases. For instance, I would like to allow admin users to control a robot through a browser while prohibiting regular users to do so. Please correct me if I'm wrong.
So I think one feasible way is to extend the roslibjs interfaces together with rosbridge v2 Protocol to support the scenario you described, right?
BTW, we are planing to have a working group for the WebRobotTools, so I think this is a good opportunity to move forward, because neither roslibjs nor the rosbridge was deigned for ROS2 and we can propose some ROS2 specific requirements under this working group, welcome to join:)