Also though from a resource perspective it seems t...
# nebula
w
Also though from a resource perspective it seems then I can re-connect and just keep using the same session ID, which is good considering that the default expiration for a session is 8hrs. From a security perspective though if I can reuse the session ID and not have to auth then there should be additional protections in place like this session came from this IP addresss.
w
@Will Droste Thanks for the great question, I did some tests:
Copy code
from <http://nebula3.gclient.net|nebula3.gclient.net> import ConnectionPool
from nebula3.Config import Config

config = Config()
config.max_connection_pool_size = 10
connection_pool = ConnectionPool()
# client connecting to graphd
connection_pool.init([('127.0.0.1', 9669)], config)

from nebula3.gclient.net.AuthResult import AuthResult
from nebula3.gclient.net.Session import Session

session = connection_pool.get_session('root', 'nebula')
session_id = session._session_id


# simulate another client connecting to graphd2
connection_pool2 = ConnectionPool()
connection_pool2.init([('127.0.0.1', 49433)], config)


connection = connection_pool2.get_connection()

auth_result = AuthResult(session_id, 0, b'UTC')

session_from_evil = Session(connection, auth_result, connection_pool, True)

session_from_evil.execute("SHOW HOSTS")
# it worked!!!
# Out[28]: ResultSet(keys: ['Host', 'Port', 'HTTP port', 'Status', 'Leader count', 'Leader distribution', 'Partition distribution', 'Version'], values: ["storaged0", 9779, 19779, "ONLINE", 9, "basketballplayer:3, moviegraph:3, test:3", "basketballplayer:3, moviegraph:3, test:3", "3.3.0"],["storaged1", 9779, 19779, "ONLINE", 9, "basketballplayer:3, moviegraph:3, test:3", "basketballplayer:3, moviegraph:3, test:3", "3.3.0"],["storaged2", 9779, 19779, "ONLINE", 12, "basketballplayer:4, moviegraph:4, test:4", "basketballplayer:4, moviegraph:4, test:4", "3.3.0"])

# In [31]: session._session_id == session_from_evil._session_id
# Out[31]: True

# In [32]: session._connection == session_from_evil._connection
# Out[32]: False
So can you just pass in the
sessoinId
in to any connection?
The interface seems not yet allow passing(at least from python client) sessionID, but it’s actually totally doable as my test.
Is the session ID unique enough not be a security concern. For instance if you make a connection to Nebula can somebody guess a
sessionId
just be doing
YIELD 1
statements?
Yes, unfortunately, this is doable, I don’t have security background, this looks very bad or, do you have any suggestions/expected behaviors in such scenario?
Also though from a resource perspective it seems then I can re-connect and just keep using the same session ID, which is good considering that the default expiration for a session is 8hrs. From a security perspective though if I can reuse the session ID and not have to auth then there should be additional protections in place like this session came from this IP addresss. (edited)
Yes, the session to be persistent in metaD came with the intuition to enable cross-client/cross GraphD reuse auth context, but as you mentioned, maybe we should enable strict mode to optionally add verification of source_IP etc on this?
w
If we are to think of this like connecting to a web service the general security approach is this.
• Authenticate and return a token that one can not be guessed so for instance a JWT or some other PEM. Its basically a encrypted signed piece of meta-data • Expire that token after a given set time (provided in the meta-data) • When a client attempts to use an expired token return an auth error so they can refresh it or create a new one
👍 1
Basically you have a stateless service with a stateful token, it should be encrypted or obfuscated such that it can't can be guessed and then the server should let the client know when it expires so they can create a new one. And on each request validate the token to insure the client is authorized.
Also I didn't see the ability to expire a
session
on the server side. If there is an anomaly or too many sessions are created it would be good to have a command to expire particular ones as well as all of them
1
From the
thrift
interface the sessionId is passed here
Copy code
final var resp = client.executeWithParameter(sessionId, stmt.getBytes(UTF_8), parameterMap);
Yes
optionally add verification of source_IP etc on this?
that would be my first approach to this, that a client must send the same session ID from the same IP. In my mind it would be easy to add to the GraphService.
❤️ 1
w