ros2-web-bridge icon indicating copy to clipboard operation
ros2-web-bridge copied to clipboard

State of authentication

Open simutisernestas opened this issue 4 years ago • 15 comments

What's the state of the authentication system? How would you go about implementing it?

simutisernestas avatar May 24 '21 12:05 simutisernestas

Do you mean kind of authentication , like, https://github.com/RobotWebTools/rosbridge_suite/blob/a09a964fb5956321aca3b296da367e21d3d2e044/ROSBRIDGE_PROTOCOL.md#2-the-rosbridge-protocol?

minggangw avatar May 24 '21 15:05 minggangw

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.

simutisernestas avatar May 24 '21 17:05 simutisernestas

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.

minggangw avatar May 27 '21 05:05 minggangw

Would a PR be welcome?

simutisernestas avatar May 27 '21 06:05 simutisernestas

Of course and you can share your idea using this thread to track the issue :)

minggangw avatar May 27 '21 14:05 minggangw

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.

simutisernestas avatar May 31 '21 13:05 simutisernestas

Thanks for your investigations! I will take a look soon.

minggangw avatar Jun 01 '21 03:06 minggangw

Hi @simutisernestas I have some questions

  • If we use the upgrade request to take the auth, do developers send the request through the JS functions by roslibjs or they have to send it explicitly by them self?
  • After the bridge receives 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 the bridge).
  • It seems that HTTP/2 doesn't allow the upgrade mechanism, it's for HTTP/1.1 only.

minggangw avatar Jun 04 '21 05:06 minggangw

  • ws connection is initialized inside roslibjs as I understand here. There is no option to pass additional data like cookies, etc. I'm triggering upgrade by simply connecting ws client to HTTP server port wscat -c ws://localhost:8080 and the connection is forwarded if authentication is successful. However, since roslibjs doesn'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.

simutisernestas avatar Jun 04 '21 10:06 simutisernestas

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.

minggangw avatar Jun 05 '21 15:06 minggangw

If we cannot call roslibjs directly, 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.

simutisernestas avatar Jun 07 '21 13:06 simutisernestas

So I think one feasible way is to extend the roslibjs interfaces together with rosbridge v2 Protocol to support the scenario you described, right?

minggangw avatar Jun 08 '21 03:06 minggangw

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:)

minggangw avatar Jun 08 '21 03:06 minggangw