Code Monkey home page Code Monkey logo

Comments (17)

mofelee avatar mofelee commented on July 24, 2024 1

https://docs.emqx.com/en/emqx/latest/access-control/authz/authz.html

I found where this feature is located. Thank you very, very much for your patient answers. EMQX is a fantastic project!

from emqx.

qzhuyan avatar qzhuyan commented on July 24, 2024

Thanks for the suggestions, just some comments:

Enhanced security by restricting subscriptions to exact topics.

If you want to exact match on topic, ACL should be written in a way of exact match. In your case, must be c/37be7dc7-b564-4c32-8347-5c2fc1a25e00/public_key

because even we implemented the 'exact_match' parameter, it will reject 'c/+/public_key' but it will not reject topics
like
c/37be7dc7-b564-4c32-8347-5c2fc1a25e00/public_key
c/123/public_key
c/37be7dc7-b564-4c32-8347-00000000000/public_key

In case you are not aware, there is a common method to use
topic-placeholders

Greater control over topic access, preventing unintended access through wildcards.

In case you are not aware, you could disable wildcard subscription:
see subscription-settings

from emqx.

mofelee avatar mofelee commented on July 24, 2024

@qzhuyan

In our scenario, all users persist their public_key to c/{my_uuid}/public_key. This public_key is intended for communication with other parties, so it is not possible to know in advance who the ACL should permit. Additionally, attempting to guess or collide UUIDs is not a simple task.

If subscribing to c/+/public_key is allowed, it could lead to a situation where every time a user sends their public_key to the MQTT broker for persistence, someone could receive a notification. A malicious user could monitor how many users are online and discover their UUIDs.

Moreover, when a user subscribes to c/+/public_key, they would receive all persisted public keys in the system, exposing all user UUIDs in the system.

from emqx.

mofelee avatar mofelee commented on July 24, 2024

Implementing this feature seems straightforward. When checking the ACL, if exact_match=true, simply verify that the subscribed topic does not contain # or + symbols.

from emqx.

zmstone avatar zmstone commented on July 24, 2024
  1. You can technically issue one a different JWT for each client. i.e. bake the uuid into JWT, instead of sharing one token for many clients.

  2. As William pointed out above, you can use placeholders in "topic" like this:

{
  "topic": "c/${username}/public_key",
  "action": "subscribe",
  "permission": "allow"
}

from emqx.

mofelee avatar mofelee commented on July 24, 2024
  1. You can technically issue one a different JWT for each client. i.e. bake the uuid into JWT, instead of sharing one token for many clients.
  2. As William pointed out above, you can use placeholders in "topic" like this:
{
  "topic": "c/${username}/public_key",
  "action": "subscribe",
  "permission": "allow"
}

If I have 100 users who need to get their keys, should I include 100 ACL rules in the JWT token, or one rule with exact_match=true ?

Or, is there a way to prevent others from using wildcard matches in the ACL, but allow specific feature matches? Additionally, this topic does not conform to the single responsibility principle. One topic field contains both topic filtering and topic subscription responsibilities. I believe that filtering allowed topics and subscription rules should not be handled by the same topic field.

from emqx.

mofelee avatar mofelee commented on July 24, 2024

The term exact_match is somewhat abstract. Alternatively, is it possible to provide a way to filter subscribable topics using regular expressions? This would make the ACL more powerful.

from emqx.

zmstone avatar zmstone commented on July 24, 2024

One JWT includes only the ACL rules which are applies to this single client which is using the token. But not for other clients.

from emqx.

mofelee avatar mofelee commented on July 24, 2024

One JWT includes only the ACL rules which are applies to this single client which is using the token. But not for other clients.

I think you might not fully understand the scenario I'm describing. Let me organize my content. I'm not a native English speaker, so there might be some issues with my description. Please bear with me.

from emqx.

zmstone avatar zmstone commented on July 24, 2024

I don't know why you are so obsessed with the exact_match idea.
It is not needed in JWT because one token is for one client.

If you want a in-general rule to allow subscribing to a/# exactly, but not a/1 or a/2, there is eq syntax in ACL rules.
use "topic": "eq c/+/public_key", to allow subscribing exactly to c/+/public_key.

here is an example with eq in JWT: https://gist.github.com/zmstone/464a72e382c83eb369c6765b034c08ad

from emqx.

mofelee avatar mofelee commented on July 24, 2024

@zmstone

Yes, this is the feature I need. Is this feature already implemented in JWT? I couldn't find it in the documentation.

from emqx.

zmstone avatar zmstone commented on July 24, 2024

Yes, I'll add it to the doc later.
But I don't think that's the feature you needed.

If I have 100 users who need to get their keys, should I include 100 ACL rules in the JWT token, or one rule with exact_match=true ?

This question shows that you don't really fully understand what ACL in JWT means.

from emqx.

mofelee avatar mofelee commented on July 24, 2024

Yes, I'll add it to the doc later. But I don't think that's the feature you needed.

If I have 100 users who need to get their keys, should I include 100 ACL rules in the JWT token, or one rule with exact_match=true ?

This question shows that you don't really fully understand what ACL in JWT means.

I have an authorization center that releases random signed tokens. These tokens only include four functions: publishing messages to others, publishing one's public key to their own UUID, allowing subscription to others' public keys. This system does not restrict any client from sending messages to others. Of course, we have another API to get the UUIDs of both parties in communication. If we allow subscribing to c/+/public_key, all user UUIDs will be leaked directly at the MQTT layer.

In other words, it's like giving each person entering the system an IP address. This IP address does not restrict any users from sending packets to each other, but I want user A to be able to get user B's public key through B's ID, and B can also get A's public key to communicate.

I don't want each user to go online and have someone directly get their IP unless the user has the time to ping all the IPs on the network. Additionally, trying to ping other users' 'IP' through UUID should be difficult.

from emqx.

zmstone avatar zmstone commented on July 24, 2024

I'd like to revisit what you wrote in the original post:

When a user subscribes to c/37be7dc7-b564-4c32-8347-5c2fc1a25e00/public_key, the subscription should be allowed.
However, if the user attempts to subscribe to c/+/public_key, the subscription should be denied.

If the "user" is the client itself, the above is where you want to get, below rules should work (the second rule is not necessary, but just added to be more explict)

[{
  "topic": "c/${username}/public_key",
  "action": "subscribe",
  "permission": "allow"
},
{
  "topic": "#",
  "action": "subscribe",
  "permission": "deny"
}]

${username} can also be${clientid}, or ${client_attrs.uuid} if you can extract the uuid from some factor of the client like certificate etc.

Now fast-forwarding to the above post

allowing subscription to others' public keys.

This would require others to subscribe c/+/public_key.
But then you also said something contradicting:

If we allow subscribing to c/+/public_key, all user UUIDs will be leaked directly at the MQTT layer.

from emqx.

mofelee avatar mofelee commented on July 24, 2024

@zmstone

Sorry, I know you want to help me solve the problem, but I tried it yesterday, "eq" didn't solve my problem.

from emqx.

zmstone avatar zmstone commented on July 24, 2024

换中文吧

from emqx.

zmstone avatar zmstone commented on July 24, 2024

related discussion #13265

from emqx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.