tediousjs / node-mssql

Microsoft SQL Server client for Node.js
https://tediousjs.github.io/node-mssql
MIT License
2.23k stars 465 forks source link

dirty session #1483

Open tobiasgrossmann opened 1 year ago

tobiasgrossmann commented 1 year ago

I noticed that the connection pool is leaving a “dirty” session. Meaning, after putting a connection back to the pool, the next process taking it might find some session values stored in mssql. I use sp_set_session_context to store variables.

This is a security bug, as the standard way of implementing row level security is to use sp_set_session_context.

tested on: tedious: 14.1.0 mssql: 7.3.5

sql database: mssql azure database

Expected behaviour:

Session must be clean, connection re-used

Actual behaviour:

session is not cleaned.

dhensby commented 1 year ago

I'd say this is expected behaviour/misuse. Definitely not a security issued unless you can provide me with some real world examples about how an attacker could exploit this.

Connections are taken from the pool and then put back, depending on your using the pool/making requests (it's not clear here what that is as you've not provided any code) it is expected that changes you make to a connection will remain on that connection when it is returned to the pool and you must take care to ensure you're handling this appropriately.

If you're setting contexts on connections you need to make sure that you are resetting those before returning them to the pool.

tobiasgrossmann commented 1 year ago

Example, is provided by microsoft: "Scenario for users who connect to the database through a middle-tier application" https://learn.microsoft.com/en-us/sql/relational-databases/security/row-level-security?view=sql-server-ver16

Due to this error and following Microsoft's practice, the system can randomly disclose data to users who are not supposed to view it.

Think of salaries or medical records. That is a security issue, and one that can get expensive.

The connection is the physical communication channel between SQL Server and the application: the TCP socket, the named pipe, the shared memory region. The session in SQL Server corresponds to the definition of a [session]: a semi-permanent container of state for an information exchange. (Wikipedia)

It's just wrong to not distinguish them.

dhensby commented 1 year ago

Regarding the issue you have reported: as you haven't provided any example code, the support I can provide is limited. As I've said, you'll have to clear the session on the connection before returning it to the pool, that will resolve your problem as far as I can tell.

In terms of if this is a security issue: If you can't provide a proof-of-concept about how this is exploitable, then it's not a provable vulnerability and just an unfounded assertion.

If you're somehow adding context to a connection and then returning it to a pool and then pulling it from the pool again whilst not resetting the context and expecting it to magically now have some new context, that is misuse. The same way creating constructing a query in a way that is vulnerable to SQL injection is misuse and not a vulnerability of the library.

Just like SQL injection vulnerabilities, the fact you're not cleaning the connection context can be a security issue for your application but it's not a concern of the underlying library.

Now, if you're asking that when connections are returned or obtained from the pool that sp_reset_connection is called, then that's fair enough and is a feature request I'd be open to.

dhensby commented 1 year ago

For reference, here is a similar issue for SQLAlchemy

tobiasgrossmann commented 1 year ago

You are seriously asking me to copy and paste the example from microsoft to this ticket? https://learn.microsoft.com/en-us/sql/relational-databases/security/row-level-security?view=sql-server-ver16

It is the proof-of-concept.

SQLAlchemy is a different case, cause its the same process. In node.js with mssql it could be different processes and so different users sharing sessions. Which makes no sense. If this is by design, then the design is simple wrong. There is a reason for making a difference between session and connection.

dhensby commented 1 year ago

You are seriously asking me to copy and paste the example from microsoft to this ticket?

No, I'm asking for a PoC for how this library is vulnerable to a security issue. Specifically one showing that it's a fundamental flaw in the library vs consumers of the library not cleaning up after themselves. That means Node code that shows a predictable and reproducible problem and a rational as to why it's a flaw with the library and not user error.

SQLAlchemy is a different case

Yes, I said similar issue, not same. It's about session data being cleaned from the connection when releasing connections from a pool.

In node.js with mssql it could be different processes and so different users sharing sessions

Incorrect, an sql pool is not shared across processes. It may be shared across requests but Node is single process and single thread, not multi-process, so the pool is not shared across processes. Each instance of a node process will have its own pool.

[sharing database sessions across user sessions] makes no sense. If this is by design, then the design is simple wrong. There is a reason for making a difference between session and connection.

I think it depends on the perspective; however I would agree that most of the time you want to get a "clean" connection from the pool. I'm not disagreeing there and, as I said, happy to entertain the idea of cleaning the connection when it's released. What I'm saying is this is not a security issue.

tobiasgrossmann commented 1 year ago

Then please add this behavior to the documentation. That not only the connection is pooled, also the session and any may added data is.