Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/modules/matching/slate_csv_test.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/modules/matching/slate_csv_test.go |
| Original SHA-256 | eefdabf447f915d891b3ac9536bb6d17d16c50da68b763367f611c0cb9ff6101 |
| Git blob SHA | f93785fdfec86dd939dbbd6df025d138cd2395eb |
| Reading-copy SHA-256 | eefdabf447f915d891b3ac9536bb6d17d16c50da68b763367f611c0cb9ff6101 |
Every recorded occurrence
These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / internal/modules/matching/slate_csv_test.go | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / internal/modules/matching/slate_csv_test.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
Recovered source transcript
Download complete source text ↓46 lines · 1.8 KB
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)
}
}