Skip to content

Dynamic mock [INS-478] [INS-1977]#190

Open
yaoweiprc wants to merge 24 commits intomasterfrom
feat/dynamic-mock
Open

Dynamic mock [INS-478] [INS-1977]#190
yaoweiprc wants to merge 24 commits intomasterfrom
feat/dynamic-mock

Conversation

@yaoweiprc
Copy link
Copy Markdown
Contributor

@yaoweiprc yaoweiprc commented Jun 11, 2025

Since the master branch contains code that has not yet been deployed to production, it is recommended to review the changes by comparing feat/dynamic-mock against the v2.0.12 tag rather than against master.

The cloud mock currently uses an image built from the v2.0.12 codebase. This PR merges the latest updates from the master and self-hosted branches and resolves all conflicts.

Once this PR is merged into master, this repository will only maintain the master branch going forward. The self-hosted branch and its corresponding Docker image will be removed. Both the cloud mock and self-hosted mock will share a single image, published at https://github.com/Kong/insomnia-mockbin/pkgs/container/insomnia-mockbin.

Dynamic Mock INS-478 INS-1977

New Features

Dynamic Mock with Liquid templating

  • Bin routes now support method + path based routing. The compoundId is now composed of {method}{uuid}{path}, allowing different bins to be matched per HTTP method and sub-path.
  • Response bodies support Liquid template rendering, enabling dynamic responses using variables from the incoming request (req.headers, req.queryParams, req.pathSegments, req.body).
  • Integrated @faker-js/faker to generate random dynamic values in templates (e.g. {{ faker.randomEmail }}, {{ faker.guid }}).
  • Added PUT /bin/upsert/:uuid* endpoint to create or update a bin.

Backward compatibility

  • When a bin is not found by the new compoundId, the server automatically retries with the legacy compoundId (without method prefix), ensuring existing bins created before this change continue to work.

Cloud mock mode (MOCKBIN_IS_CLOUD_MOCK)

  • When running in cloud mode, utility endpoints (/ip, /echo, /har, /request, /headers, etc.) and bin management UI routes (/bin/create, /bin/view, /bin/sample) are disabled. Only the core bin run/log/upsert/delete endpoints are exposed.
  • Sensitive request headers can be masked in templates via MOCKBIN_CLOUD_RESTRICTED_HEADERS (comma-separated list).

Security & Bug Fixes

  • Removed sensitive data from request logs — query string parameters are stripped before storing log entries.
  • Removed X-Powered-By header from responses to avoid exposing server technology.
  • Fixed uncaught errors in async Redis callbacks — errors are now properly caught and forwarded to next(e) to prevent service crashes.
  • Liquid engine is configured with strict security settings: prototype pollution protection, resource limits (parse/render/memory), and a whitelist of allowed tags and filters.

Infrastructure

  • Switched base Docker image to node:22-alpine to address high severity vulnerabilities in node:22-bullseye-slim.
  • Updated GitHub Actions release workflow.
  • Added schemas.js for HAR response validation.
  • Added E2E test instructions pointing to the separate test repository.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jun 11, 2025

CLA assistant check
All committers have signed the CLA.

@yaoweiprc yaoweiprc changed the title Add dynamic mock Add dynamic mock [INS-478] Jun 11, 2025
@yaoweiprc yaoweiprc changed the title Add dynamic mock [INS-478] Add dynamic mock [INS-5485] Jun 11, 2025
);
// TODO: add switch in client
// TODO: add it to create
mock._dynamicMockInBody = true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice job so far, how do you propose to determine this value in the client?
Why do we need to know this, is it an early optimisation? does the library waste resource if given a string without tags? If not it could be avoided, and we can just let the library optimise itself.

Comment on lines +9 to +13
const ajv = new Ajv({
allErrors: true, // Reports all errors found
strict: false, // Used for setting the custom property (`violationMessage`) in mockSchema.
useDefaults: true, // This will fill in default values within the schema. Resolves backward compatibility issues when changing schemas.
});

Check warning

Code scanning / Semgrep OSS

Semgrep Finding: javascript.ajv.security.audit.ajv-allerrors-true.ajv-allerrors-true Warning

By setting allErrors: true in Ajv library, all error objects will be allocated without limit. This allows the attacker to produce a huge number of errors which can lead to denial of service. Do not use allErrors: true in production.
@yaoweiprc yaoweiprc changed the title Add dynamic mock [INS-5485] Dynamic mock [INS-5485] Mar 30, 2026
@yaoweiprc yaoweiprc changed the title Dynamic mock [INS-5485] Dynamic mock [INS-478] [INS-1977] Mar 31, 2026
Rename image name
Remove self-hosted image
@yaoweiprc yaoweiprc force-pushed the feat/dynamic-mock branch from d67da70 to be72b39 Compare April 1, 2026 09:46
@yaoweiprc yaoweiprc mentioned this pull request Apr 8, 2026
@yaoweiprc yaoweiprc force-pushed the feat/dynamic-mock branch from bcab10a to 266aa24 Compare April 9, 2026 10:36
@yaoweiprc yaoweiprc force-pushed the feat/dynamic-mock branch from 266aa24 to f310f12 Compare April 9, 2026 10:43
@yaoweiprc yaoweiprc marked this pull request as ready for review April 9, 2026 11:05
Comment on lines +47 to +57
minimum: -1,
default: -1,
errorMessage:
"The 'headersSize' property must be >= 0 and of type integer.",
},
bodySize: {
type: "integer",
minimum: -1,
default: -1,
errorMessage:
"The 'bodySize' property must be >= 0 and of type integer.",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'headersSize' rule allows -1, but its error message says values must be >= 0; this contradicts the actual validation behavior.

Show fix
Suggested change
minimum: -1,
default: -1,
errorMessage:
"The 'headersSize' property must be >= 0 and of type integer.",
},
bodySize: {
type: "integer",
minimum: -1,
default: -1,
errorMessage:
"The 'bodySize' property must be >= 0 and of type integer.",
minimum: -1,
"The 'headersSize' property must be >= -1 and of type integer.",
},
bodySize: {
type: "integer",
minimum: -1,
default: -1,
errorMessage:
"The 'bodySize' property must be >= -1 and of type integer.",
Details

✨ AI Reasoning
​The validation rule for one numeric size field allows -1, but the error text claims values must be greater than or equal to 0. This creates contradictory behavior: accepted values conflict with the documented constraint, producing misleading validation semantics.

Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

Comment on lines +50 to +57
"The 'headersSize' property must be >= 0 and of type integer.",
},
bodySize: {
type: "integer",
minimum: -1,
default: -1,
errorMessage:
"The 'bodySize' property must be >= 0 and of type integer.",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'bodySize' rule allows -1, but its error message says values must be >= 0; validation logic and message are inconsistent.

Show fix
Suggested change
"The 'headersSize' property must be >= 0 and of type integer.",
},
bodySize: {
type: "integer",
minimum: -1,
default: -1,
errorMessage:
"The 'bodySize' property must be >= 0 and of type integer.",
"The 'headersSize' property must be >= -1 and of type integer.",
},
bodySize: {
type: "integer",
minimum: -1,
default: -1,
errorMessage:
"The 'bodySize' property must be >= -1 and of type integer.",
Details

✨ AI Reasoning
​Another numeric size field has the same contradiction between allowed range and stated requirement. The validator accepts -1, yet the message describes a stricter lower bound. This mismatch can lead to incorrect assumptions about what inputs are valid.

Reply @AikidoSec feedback: [FEEDBACK] to get better review comments in the future.
Reply @AikidoSec ignore: [REASON] to ignore this issue.
More info

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants