Skip to content

JavaScript parser misses Express.js anonymous route handler callbacks #21

@joshbouncesecurity

Description

@joshbouncesecurity

Problem

The JavaScript/TypeScript parser pipeline (typescript_analyzer.jsunit_generator.js) does not extract anonymous arrow function callbacks used as Express.js route handlers. This means the majority of application code in a typical Express app is invisible to analysis.

Example

Given a standard Express route definition:

router.post('/orders', authenticateToken, async (req, res) => {
  const { productId, quantity } = req.body;
  // ... route handler logic ...
});

The parser extracts authenticateToken (a named function) but not the anonymous async (req, res) => { ... } callback that contains the actual business logic and potential vulnerabilities.

Impact

In a test codebase with 9 JS files, ~20 route handlers, and 7 known security vulnerabilities:

  • typescript_analyzer found only 8 functions (5 named functions + 3 route_handlers)
  • unit_generator produced 8 units
  • reachability_filter reduced to 2 units (only authenticateToken and authenticateApiKey matched req.headers input patterns)
  • All 7 vulnerabilities live in the anonymous route handler callbacks that were never extracted

The 2 surviving units are middleware functions — none of the actual route handler code was analyzed.

Pipeline output

STAGE: typescript_analyzer — 8 functions (function: 5, route_handler: 3)
STAGE: unit_generator — 8 units, call graph: 7 edges
STAGE: reachability_filter — Entry points: 2, Units: 8 → 2 (75% reduction)

Expected behavior

The parser should recognize Express route handler patterns and extract the callback functions as units, ideally with:

  • The HTTP method and path as metadata (e.g., POST /orders)
  • is_entry_point: true since they directly receive HTTP request data (req.body, req.params, req.query)
  • Correct call graph edges to middleware functions used in the same route

Workaround

Refactoring route handlers to use named functions works:

async function createOrder(req, res) { ... }
router.post('/orders', authenticateToken, createOrder);

But this shouldn't be necessary — the anonymous callback pattern is idiomatic Express.js.

Environment

  • OpenAnt CLI (Windows)
  • JavaScript parser pipeline
  • Express.js 4.x codebase with CommonJS modules

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions