Many applications provide an option to download some data as a CSV file. More often than not, this downloaded data is user controlled data. For instance, take the scenario where an administrator can export the data of all the users as a CSV file. The fields in the file include the details filled by the users. So technically, the administrator is exporting user controlled data. What if a user injects something malicious in his details? This can lead to CSV injection. As an application developer, you can not control what a user enters. You can sanitise it, though.
Recently, while performing a pentest for a client, I came across a similar functionality as mentioned above. In the admin panel, there was an option to ‘Export data as CSV’. Any admin could export data as a CSV file. The first thing that came to my mind was the possibility of CSV or Formula Injection. So, I went ahead and exported the data. Well, not to my surprise, the data contained user information entered by the users of the application, basically ‘user-controlled data’. I tested further and indeed the application was vulnerable to CSV Injection.
As you all know, a CSV file format is used to store tabular data where each attribute value is separated by a delimiter i.e. comma (hence the name “comma separated value”). Though other delimiters such as space can also be used, the point here is to separate the attribute values.
How does a simple CSV file pose a threat?
After downloading the CSV file, a user may choose to open it in spreadsheet software such as Microsoft Excel or LibreOffice. A malicious user could have inserted a malicious formula (starting with =) that got included in the CSV file when the data was exported. This happened due to the inability of the web application to properly sanitise the user input. When the file is opened in Excel or LibreOffice, the contents of the cell containing the formula might get executed.
Suppose an application allows an admin to export application’s user data as a CSV file. The data exported contains the username and password of the users. Let us consider two specific cases as to how an attacker can attack the admin of the application.
Case1: Running system level commands
In this case, we suppose that the admin opens the CSV file in MS-Excel. It’s funny to note how popping up a calculator has become a standard step while testing vulnerabilities such as remote code execution on a Windows machine. We are going to do the same thing here, running the famous ‘calc.exe’.
1. Let’s say, this is how the malicious CSV file exported by the victim looks. The highlighted part shows the malicious command that would run on the victim’s machine. The malicious command was entered as a username by the attacker. Since the application did not sanitise the input, it was allowed.
2. Once the victim opens the CSV file in Microsoft Excel, he gets the following warning.
3. Since the CSV came from a trusted source, the victim may enable the running of active content. Again, an additional warning pops up stating that Excel wants to open another application. In our case, it is cmd.exe.
4. Again, since the victim trusts the file, he clicks on “Yes”. The command runs (calc.exe) and the victim can see a calculator opened in his window. The real attack won’t be running the calculator. Instead, a malicious program would be run affecting the victim’s system.
Case 2: Stealing information
In this case, let us see how the HYPERLINK function in LibreOffice can be leveraged by an attacker to exfiltrate sensitive data from the exported CSV file. The HYPERLINK function is used to insert an external link in the spreadsheet.
1. The attacker sets a malicious username(=HYPERLINK(malicious link)) in his profile. When the victim exports user-data.csv and open it with LibreOffice, the attacker’s username gets executed as a formula and shows an option of a link. The malicious CSV file looks like this.
2. The malicious CSV file looks like this in LibreOffice. As you can see the highlighted part in the image, it says that there has been an error which is just a misleading text with an external malicious link.
3. However unlikely, still if the victim clicks on the above link, this happens!
In reality, the attacker would be displaying, say a ‘404 Not Found’ message on the web page. The highlighted URL shows the contents of other users being exfiltrated. (I have used localhost to demonstrate this. In reality, an attacker would be using one of his domains).
4. But how would the attacker get this data? Logs! Yes, the web server logs would clearly show the exfiltrated data.
The above examples just demonstrate how it can be done. What can be done totally depends upon the attacker?
Sanitise user input. There would not be a problem in the first place if the application were sanitising user input. Characters such as ‘=’ should not be allowed in fields such as usernames. If these characters are to be allowed, a recommended fix is to append a single quote (‘) to the list of formula triggers ( =, +, -) before saving it in the database. LibreOffice or Excel will ignore the single quote and just show the malicious formula as a string i.e. it won’t be interpreted as a formula.
So, the next time you encounter a CSV file, make sure you check its contents in a text editor before opening it with a spreadsheet software.