aspnetmvc-405210-security-considerations-prevent-csv-injection.md
DevExpress Card View, Grid View, Pivot Grid, and Vertical Grid extensions allow you to export data in CSV format. The exported file may contain content that spreadsheet software (such as Microsoft Excel) interprets as a formula. These formulas can execute shell commands when a user opens the file. For example, the following formula runs the Windows Calculator:
=cmd|' /C calc'!'!A1'
DevExpress Grid-like extensions do not auto-encode executable content for the following reasons:
DevExpress ASP.NET MVC extensions include a built-in mechanism to encode executable content. During CSV export operations, this mechanism encloses values that start with “=”, “-“, “+”, “@“, or “” in quote characters. You should enable executable content encoding to protect your application against CSV injection attacks such as CWE-74.
To encode at the application level, set the EncodeCsvExecutableContent property to True in the Global.asax file:
void Application_Start(object sender, EventArgs e) {
DevExpress.Export.ExportSettings.EncodeCsvExecutableContent = DevExpress.Utils.DefaultBoolean.True;
}
The BeforeExport property allows you to access export settings when you execute our built-in Export to CSV command or call the client-side ExportTo method. To encode content, enable the EncodeExecutableContent export setting:
@Html.DevExpress().GridView(settings => {
settings.Name = "gvExport";
settings.CallbackRouteValues = new { Controller = "Exporting", Action = "ExportPartial" };
settings.Columns.Add("CompanyName");
settings.Columns.Add("City");
settings.Columns.Add("Country");
settings.Columns.Add("UnitPrice");
settings.Columns.Add("Quantity");
settings.Toolbars.Add(t => {
t.Items.Add(GridViewToolbarCommand.ExportToCsv);
});
settings.SettingsExport.EnableClientSideExportAPI = true;
settings.SettingsExport.ExcelExportMode = DevExpress.Export.ExportType.DataAware;
settings.SettingsExport.BeforeExport = (s, e) => {
(e.ExportOptions as DevExpress.XtraPrinting.CsvExportOptionsEx).EncodeExecutableContent = DefaultBoolean.True;
};
}).Bind(Model).GetHtml()
DevExpress Grid-like extensions include server-side methods designed to export data to CSV. These methods accept a CsvExportOptions or CsvExportOptionsEx object that stores export settings. Enable this object’s EncodeExecutableContent setting to encode executable content:
using System.Linq;
using System.Web.Mvc;
using DevExpress.Web.Mvc;
namespace MyProject.Controllers {
public class HomeController : Controller {
public ActionResult Index() {
ViewBag.GridSettings = GetGridSettings();
return View();
}
MyProject.Models.northwindEntities db = new MyProject.Models.northwindEntities();
// Handles GridView callbacks
[ValidateInput(false)]
public ActionResult GridViewPartial() {
ViewBag.GridSettings = GetGridSettings();
var model = db.Products;
return PartialView("_GridViewPartial", model.ToList());
}
// Sends a CSV document with the exported Grid as a response
public ActionResult ExportTo() {
var model = db.Products;
var options = new CsvExportOptionsEx();
options.EncodeExecutableContent = DefaultBoolean.True;
return GridViewExtension.ExportToCsv(GetGridSettings(), model.ToList(), options);
}
// Returns exported GridView settings
private GridViewSettings GetGridSettings() {
var settings = new GridViewSettings();
settings.Name = "GridView";
settings.CallbackRouteValues = new { Controller = "Home", Action = "GridViewPartial" };
settings.SettingsExport.FileName = "Report.csv";
settings.KeyFieldName = "ProductID";
settings.Columns.Add("ProductName");
settings.Columns.Add("UnitPrice");
settings.Columns.Add("QuantityPerUnit");
settings.Columns.Add("Discontinued", MVCxGridViewColumnType.CheckBox);
return settings;
}
}
}
@Html.Action("GridViewPartial")
@* When a user clicks this button, the button sends a callback to the "ExportTo" action and the server
sends the resulting export file as a response *@
@Html.DevExpress().Button(settings => {
settings.Name = "Button";
settings.UseSubmitBehavior = false;
settings.Text = "Export to CSV";
settings.RouteValues = new { Controller = "Home", Action = "ExportTo" };
}).GetHtml()
@{
var grid = Html.DevExpress().GridView(ViewBag.GridSettings);
}
@grid.Bind(Model).GetHtml()