package matching import ( "strings" "testing" "github.com/missionworkforce/missionmatch/internal/platform/database/dbgen" ) // TestSlateCSVHeadersAreFormulaSafe. The slate export is emailed to a government customer, so a cell that // a spreadsheet treats as a formula executes on their machine when they open it. // // The data rows were already wrapped in csvsafe and the two HEADER lines were not, which left the attack // fully open on the one field an attacker names directly: a slate title. The payloads below contain no // comma, so the RFC 4180 quoting that was there passed them through untouched. func TestSlateCSVHeadersAreFormulaSafe(t *testing.T) { for _, payload := range []string{ `=cmd|'/c calc.exe'!A1`, `+cmd|'/c calc.exe'!A1`, `-2+3+cmd|'/c calc.exe'!A1`, `@SUM(1+9)*cmd|'/c calc.exe'!A1`, } { out := renderSlateCSV(dbgen.Slate{Name: payload}, payload, nil) for _, line := range strings.Split(out, "\n") { if !strings.HasPrefix(line, "Slate,") && !strings.HasPrefix(line, "Requirement,") { continue } // The value after the label must not begin with a formula trigger. val := strings.TrimPrefix(strings.TrimPrefix(line, "Slate,"), "Requirement,") val = strings.TrimPrefix(val, `"`) if strings.ContainsAny(val[:1], "=+-@\t\r") { t.Errorf("header cell still starts with a formula trigger: %q", line) } } } } // TestSlateCSVKeepsNegativeNumbers. The escape must not corrupt legitimate data: a negative number is not // a formula, and quoting it would turn a currency column into text in the customer's spreadsheet. func TestSlateCSVKeepsNegativeNumbers(t *testing.T) { out := renderSlateCSV(dbgen.Slate{Name: "-1250.50"}, "-3", nil) if !strings.Contains(out, "Slate,-1250.50") { t.Errorf("a negative number was escaped and is no longer numeric:\n%s", out) } }