← Attack Surface Lab

Call Chains

Endpoint URLs assembled across multiple function calls — from 3-level return chains to 5-level mixed patterns using callbacks, global variables, and cross-script boundaries. The complete URL never appears as a string literal.

01

3-level return-value chain

Three functions, each returning a URL segment. getApiBase()getInventoryPath()getCheckEndpoint(). The analyzer must follow return values through 3 levels.

Client-side JavaScript inventoryChain.js
const getApiBase = () => '/api';
const getInventoryPath = () => getApiBase() + '/inventory';
const getCheckEndpoint = () => getInventoryPath() + '/check';

const checkInventory = (itemId) => {
  fetch(getCheckEndpoint() + '?item=' + itemId);
};
SolidPoint discovered
SolidPoint UI showing discovered GET /api/inventory/check endpoint
02

3-level callback chain

URL parts passed through callback function parameters across 3 levels. A different data-flow pattern — callbacks instead of return values.

Client-side JavaScript messageCallback.js
const withApiPrefix = (callback) => {
  callback('/api');
};

const withResource = (callback) => {
  withApiPrefix((prefix) => {
    callback(prefix + '/messages');
  });
};

const sendMessage = (text) => {
  withResource((resource) => {
    fetch(resource + '/send', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ text })
    });
  });
};
SolidPoint discovered
SolidPoint UI showing discovered POST /api/messages/send endpoint
03

4-level sequential chain

Four functions, each appending one path segment. One level deeper than the typical 3-level call chain.

Client-side JavaScript settingsDeepChain.js
const apiPrefix = () => '/api';
const settingsBase = () => apiPrefix() + '/settings';
const appearancePath = () => settingsBase() + '/appearance';
const updateAppearanceUrl = () => appearancePath() + '/update';

const saveAppearance = (theme, fontSize) => {
  fetch(updateAppearanceUrl(), {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ theme, fontSize })
  });
};
SolidPoint discovered
SolidPoint UI showing discovered PUT /api/settings/appearance/update endpoint
04

Shared global written by multiple functions

Two functions write to the same global variable trackingUrl in sequence. The analyzer must track all writes to determine the final value before fetch().

Client-side JavaScript sharedGlobalWriter.js
var trackingUrl = '';

function setTrackingBase() {
  trackingUrl = '/api/tracking';
}

function appendTrackingAction() {
  trackingUrl = trackingUrl + '/event';
}

function configureTracking() {
  setTrackingBase();
  appendTrackingAction();
}

function sendTrackingEvent(eventData) {
  configureTracking();
  fetch(trackingUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(eventData)
  });
}
SolidPoint discovered
SolidPoint UI showing discovered POST /api/tracking/event endpoint
05

5-level linear chain — deepest return-value pattern

Five functions, each appending one URL segment via return values. The complete path /api/admin/org/members/invite never appears as a string literal anywhere in the code.

Client-side JavaScript deepInviteChain.js
const root = () => '/api';
const adminRoot = () => root() + '/admin';
const orgPath = () => adminRoot() + '/org';
const membersPath = () => orgPath() + '/members';
const inviteUrl = () => membersPath() + '/invite';

const inviteMember = (email, role) => {
  fetch(inviteUrl(), {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, role })
  });
};
SolidPoint discovered
SolidPoint UI showing discovered POST /api/admin/org/members/invite endpoint
06

5-level mixed chain — callbacks, globals, and concatenation

The most complex pattern tested. Five functions using return values, callback parameters, and shared global variable writes to construct the URL. Three different data-flow mechanisms in one chain.

Client-side JavaScript storagePurgeComplex.js
var archivePath = '';

function getStorageRoot() {
  return '/api/storage';
}

function buildBucketPath(callback) {
  var bucketPath = getStorageRoot() + '/buckets';
  callback(bucketPath);
}

function setArchivePath(base) {
  archivePath = base + '/archive';
}

function getPurgeUrl() {
  buildBucketPath(function(bp) {
    setArchivePath(bp);
  });
  return archivePath + '/purge';
}

function purgeArchive(bucketId) {
  fetch(getPurgeUrl(), {
    method: 'DELETE',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ bucketId })
  });
}
SolidPoint discovered
SolidPoint UI showing discovered DELETE /api/storage/buckets/archive/purge endpoint
07

Variable in HTML, used in external JS

API_ROOT is defined in an inline <script> tag on the HTML page. An external JavaScript module reads it via window.API_ROOT and appends a path segment. The analyzer must perform whole-page analysis across script boundaries.

Client-side JavaScript configSync.js + index.html
// index.html (inline script)
var API_ROOT = '/api/config';

// configSync.ts (external module)
const getSyncUrl = () => window.API_ROOT + '/sync';

const performConfigSync = (settings) => {
  fetch(getSyncUrl(), {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(settings)
  });
};
SolidPoint discovered
SolidPoint UI showing discovered POST /api/config/sync endpoint

Start boosting your App Security testing today with us today

Try for free Get a demo