Hacker News new | ask | show | jobs
by sehrope 2709 days ago
The intended usage is that the client tells the server, "I want to load data from a file /path/to/data.txt on my local filesystem" in a SQL command. As part of the protocol for executing the query the server sends a message to the client to request the contents of /path/to/data.txt. Unfortunately client's don't validate the file request and will send any file (ex: /path/to/secrets.txt) even if there was no legit data request in their command.

This has been an issue with MySQL client drivers for years. I found and fixed the same issue in MariaDB Connector/J (JDBC driver (wire compatible with MySQL databases) in 2015. It rejects LOCAL DATA requests from the server unless the client app preregistered an InputStream (Java interface for generic stream of bytes) as data for the command being executing.

This is one of the many many reasons I love open source database drivers. I was able to find and fix this issue only because I could see the source code. Similar "features" in proprietary databases could go unnoticed for years and even when discovered may not have feature flags to disable them.

5 comments

Similarly, MySQL Connector/J also used to attempt to deserialize binary data that looked like a serialized Java object (CVE-2017-3523). Doing this with untrusted data can often be used to obtain arbitrary code execution. Connecting to an untrusted server does not appear to be a use-case that received enough attention.
This seems like a weird design choice. Why would you need to load a file from the file system as part of a select?

Unless I'm missing some kind of use case this seems like a bad protocol design.

Loading a CSV is a common use case. PostgreSQL has a similar \COPY command used for a similar purpose (but that's a client side command not server side as far as I know),
psql’s \copy command utilizes the server’s COPY functionality, which absolutely can read and write files on the server or run commands there [1].

  COPY with a file name instructs the PostgreSQL server to directly read from or
  write to a file.  The file must be accessible by the PostgreSQL user (the user
  ID the server runs as) and the name must be specified from the viewpoint of the
  server.

Clients using COPY, including psql’s \copy, often pass STDIN or STDOUT as the “file”, which allows data to be transmitted over the wire rather from the server’s filesystem.

https://www.postgresql.org/docs/11/sql-copy.html

https://www.postgresql.org/docs/9.0/sql-copy.html

PostgreSQL COPY can read or write to server files, though it requires superuser permissions.

There is also COPY FROM/TO STDIN/STDOUT, which allows the client to send the files on the same connection.

Performance reasons.
I cannot agree that this is the example of open source advantage.

For me it is an example of bad protocol design in the first place.

Bad protocol design occurs in both OSS and proprietary.

However, with proprietary software the protocol is unknown unless it has been published. With OSS, you at least have the source code of the implementation.

As you should know, proprietary software relies on the owners to fix the problem. With OSS, "anyone" can provide a fix - and even if the owner does not wish to include the fix in the official build (which would look very bad on them, in this instance), "anyone" can apply it to their own copy.

Meaning, it's vastly easier for a 3rd party to discover and fix OSS, than proprietary software.

"However, with proprietary software the protocol is unknown unless it has been published" this is not true. Proprietary software does not necessarily mean opaque protocols. It's chicken and egg question.

1) IIS is proprietary server, but speaks open HTTP protocol. Proprietary software may implement well known protocol. This is probably most of the cases. 2) SQL Server is proprietary software, but speaks documented protocol - TDS. Specification is published. 3) Oracle Database is proprietary software and speaks undocumented TNS protocol.

Protocol is just a specification. If design meant to be secure it is way better.

There are proprietary HTTP clients, but no HTTP server can request file from client. So HTTP protocol is better than MySql protocol. If someone will write custom open source MySql client it will probably be affected. So this is bad design. If someone will write custom open source HTTP client it will not be affected. So this is good design.

Open source does not overweight bad design. I see no sense in "open source v. bad design". Bad design is bad design, no matter what the license is. There is nothing good is keeping bad software alive just because it's open source. The fact that you can play with code and fix security bug is very nice at most. The fact that protocol was misdesigned is paramount.

Right? I said "the protocol is unknown unless it has been published". HTTP has been published.

No one has said nor implied that OSS had any effect on the protocol.

The assertion was, the patcher was thankful it was open source. If it were not, (s)he would not have been able to fix it.

It's strange to blame the client, while it's actually the fault of the server. A DB server should not be able to pipe an arbitrary file to the client.
You've got it backwards - the DB server can pipe an arbitrary file from the client. So it is considered the fault of the client - it should not allow that. Since the mysql client is the one receiving the request and it should apply standard security practices by not blindly trusting an incoming request and instead validating that the path is equal to an earlier client load request sent to the server. (Although a better approach IMO would be to modify the wire protocol so the server "request" does not use the file name, but instead uses an ID from the earlier client request)
You misunderstood what's happening here. A rogue server can request the client to read any file on the client's file system, and the client will comply without validation that the client actually requested this.
That’s not what this is about. The intended use is: Client tells server to load a file, server sends request for file, client sends file. Except that the client will send the server whatever file it requests. In fact the client doesn’t even need to tell the server to request a file. The server can just request whateve file it wants whenever it likes and the client will send it.
Uh. Ok. "I was able to find and fix this issue only because I could see the source code." This is how all security issues happen. If I was as terrible person, i would create scripts that pray upon people that didnt' patch.
People find vulnerabilities in closed source software too, they just don't have the source to patch it.
Actually, I think there are cases where people have patched closed source software. Binary patches are possible, just harder to write. (Not trying to say you're wrong: it's definitely easier if one has the source. Only that some humans are both determined and skilled, and some incredible stuff comes from that combination.)

IIRC, there was a flaw in Flash patched in this manner; it was using memcpy(), which requires the source and destination regions to not overlap, but, they did. In this case, it's fairly simple: one just needs to call memmove(), which conveniently takes the same args in the same order.

(IIRC, there was a lot of consternation getting Adobe to fix that properly, given how obvious the bug was.)