HIGH formula injectionexpressbasic auth

Formula Injection in Express with Basic Auth

Formula Injection in Express with Basic Auth — how this specific combination creates or exposes the vulnerability

Formula Injection occurs when untrusted data is interpreted as a formula or expression by downstream systems such as spreadsheets, BI tools, or report generators. In an Express API that uses HTTP Basic Authentication, the combination of user-controlled input and legacy data-rendering integrations commonly creates a pathway for formula injection even when the API itself does not directly evaluate expressions.

With Basic Auth, credentials are sent in the Authorization header as a base64-encoded string of username:password. While this header is typically parsed by the server to enforce authentication, developers sometimes inadvertently propagate header or user data into downstream processing. For example, an authenticated request may include query parameters or JSON payload fields that are later exported to CSV or rendered in an Excel file. If these values begin with characters that Excel or Google Sheets interpret as formulas—such as =, +, -, or @—the application may trigger unintended execution when the file is opened.

Consider an Express endpoint that generates a downloadable CSV for authenticated users:

// Example of vulnerable behavior when combining Basic Auth and dynamic CSV generation
app.get('/api/report', (req, res) => {
  const auth = req.headers.authorization;
  const user = parseBasicAuth(auth); // returns { username, password }
  const name = req.query.name || '';
  // name is user-controlled and may be used downstream in spreadsheet software
  const csv = `Name,Email\n${name},${user.username}@example.com`;
  res.setHeader('Content-Type', 'text/csv');
  res.attachment('report.csv');
  res.send(csv);
});

If an attacker sends a request like /api/report?name=1+2+3 with valid Basic Auth credentials, the CSV will contain 1+2+3 in the Name column. When opened in Excel, the cell may be interpreted as a formula, potentially causing data exfiltration via injected expressions, evaluation of unintended calculations, or triggering references to external resources. This pattern is particularly risky when downstream tooling trusts the file origin because the authentication step established a perceived session context.

The risk is compounded when APIs accept JSON input that is later serialized into spreadsheets or documents. An authenticated POST that includes a field such as label with value =HYPERLINK("http://attacker.com") can lead to client-side formula execution without any server-side formula parsing. Because Basic Auth does not inherently validate or sanitize user-supplied data, the API may propagate attacker-controlled content into contexts where formulas are evaluated, effectively turning an authenticated endpoint into a vector for indirect injection.

Basic Auth-Specific Remediation in Express — concrete code fixes

Remediation focuses on strict input validation, output encoding, and avoiding the direct concatenation of user-controlled values into formats that interpreters may evaluate. When using Basic Auth in Express, treat all data that leaves the API boundary—especially data combined with authentication context—as potentially hostile.

1. Validate and sanitize all user-controlled fields before export

Ensure that any data used in CSV, TSV, or spreadsheet-compatible formats is escaped or encoded so that characters like =, +, -, @, and tab/newline sequences cannot be misinterpreted as formulas or executable content. For CSV generation, use a dedicated library that enforces proper quoting and escaping.

// Safe CSV generation with escaping
const escapeCsv = (value) => {
  const escaped = String(value).replace(/"/g, '""');
  if (/[,"\n=]/.test(escaped) || escaped.startsWith('+') || escaped.startsWith('=') || escaped.startsWith('-') || escaped.startsWith('@') || escaped.startsWith('\t') || escaped.startsWith('\n')) {
    return `"${escaped}"`;
  }
  return escaped;
};

app.get('/api/report', (req, res) => {
  const auth = req.headers.authorization;
  const user = parseBasicAuth(auth);
  const name = req.query.name || '';
  const safeName = escapeCsv(name);
  const csv = `Name,Email\n${safeName},${user.username}@example.com`;
  res.setHeader('Content-Type', 'text/csv');
  res.attachment('report.csv');
  res.send(csv);
});

The escapeCsv function prevents leading formula characters and encloses the field in double quotes when necessary. This approach mitigates injection into spreadsheet applications while preserving legitimate input.

2. Avoid propagating authentication-derived context into untrusted outputs

Do not embed user-controlled data into file names, Content-Disposition headers, or document metadata without strict validation. If you must include authenticated identifiers, enforce allowlists and avoid concatenation with user input that may originate from query parameters or JSON fields.

// Safer handling of authenticated exports
app.get('/api/report', (req, res) => {
  const auth = req.headers.authorization;
  const user = parseBasicAuth(auth);
  const rawName = req.query.name || '';
  // Strict allowlist: only alphanumeric characters, limited length
  if (!/^[A-Za-z0-9 _-]{1,50}$/.test(rawName)) {
    return res.status(400).send('Invalid name');
  }
  const safeName = escapeCsv(rawName);
  const filename = `report_${user.username}.csv`;
  res.setHeader('Content-Type', 'text/csv');
  res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
  res.send(`Name,Email\n${safeName},${user.username}@example.com`);
});

By combining allowlist validation with output escaping, you reduce the likelihood that authenticated requests lead to formula execution in downstream viewers. These practices align with secure handling guidance for MIME types and structured text exports, and they complement broader API security checks available in scans from tools such as middleBrick, which can detect missing input validation and data exposure risks in Basic Auth–protected endpoints.

Frequently Asked Questions

Does Basic Auth prevent formula injection if credentials are correct?
No. Successful authentication does not sanitize user-controlled data. Formula injection depends on how the application uses input, not on whether the request is authenticated.
Is encoding the Authorization header enough to stop formula injection?
No. The Authorization header is separate from data used in CSV or document generation. Focus on escaping and allowlisting any user-controlled values that may be rendered in formats interpreted as formulas.