Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fileignoreconfig:
ignore_detectors:
- filecontent
- filename: package-lock.json
checksum: 424e5c45fa8043c95e0da5b215279c41cbe85230f75262ec7ac9ba01520e8821
checksum: a81864e0ab4cb3027a8ce8980c0b867b50cb3785d36a640bcc315f4689837618
- filename: .husky/pre-commit
checksum: 52a664f536cf5d1be0bea19cb6031ca6e8107b45b6314fe7d47b7fad7d800632
- filename: test/sanity-check/api/user-test.js
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [v1.27.1](https://github.com/contentstack/contentstack-management-javascript/tree/v1.27.1) (2026-01-5)
- Fix
- Resolve qs dependency version

## [v1.27.0](https://github.com/contentstack/contentstack-management-javascript/tree/v1.27.0) (2025-12-15)
- Enhancement
- Refactored region endpoint resolution to use centralized `@contentstack/utils` package
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2012-2025 Contentstack
Copyright (c) 2012-2026 Contentstack

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
23 changes: 20 additions & 3 deletions lib/core/concurrency-queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ const defaultConfig = {

/**
* Creates a concurrency queue manager for Axios requests with retry logic and rate limiting.
* SECURITY NOTICE - SSRF Prevention (CWE-918):
* This module implements comprehensive Server-Side Request Forgery (SSRF) protection.
* All axios requests are validated using validateAndSanitizeConfig() which:
* - Restricts requests to approved Contentstack domains only
* - Blocks private IP addresses and internal network access
* - Enforces HTTP/HTTPS protocols only (blocks file://, ftp://, etc.)
* - Validates both URL and baseURL configurations
* - Prevents URL injection attacks through proper sanitization
* @param {Object} options - Configuration options.
* @param {Object} options.axios - Axios instance to manage.
* @param {Object=} options.config - Queue configuration options.
Expand Down Expand Up @@ -158,11 +166,14 @@ export function ConcurrencyQueue ({ axios, config }) {
setTimeout(() => {
// Keep the request in running queue to maintain maxRequests constraint
// Set retry flags to ensure proper queue handling
// SECURITY: Validate and sanitize request config to prevent SSRF (CWE-918)
// This ensures no malicious URLs from user input can be used
const sanitizedConfig = validateAndSanitizeConfig(updateRequestConfig(error, `Network retry ${attempt}`, delay))
sanitizedConfig.retryCount = sanitizedConfig.retryCount || 0

// Use axios directly but ensure the running queue is properly managed
// The request interceptor will handle this retry appropriately
// SECURITY: Using sanitizedConfig that has been validated against SSRF attacks
axios(sanitizedConfig)
.then((response) => {
// On successful retry, call the original onComplete to properly clean up
Expand Down Expand Up @@ -315,8 +326,10 @@ export function ConcurrencyQueue ({ axios, config }) {

// Retry the requests that were pending due to token expiration
this.running.forEach(({ request, resolve, reject }) => {
// Retry the request with sanitized configuration to prevent SSRF
// SECURITY: Validate and sanitize request config to prevent SSRF (CWE-918)
// This ensures no malicious URLs from user input can be used
const sanitizedConfig = validateAndSanitizeConfig(request)
// SECURITY: Using sanitizedConfig that has been validated against SSRF attacks
axios(sanitizedConfig).then(resolve).catch(reject)
})
this.running = [] // Clear the running queue after retrying requests
Expand Down Expand Up @@ -445,8 +458,10 @@ export function ConcurrencyQueue ({ axios, config }) {
// Cool down the running requests
delay(wait, response.status === 401)
error.config.retryCount = networkError
// SSRF Prevention: Validate URL before making request
// SECURITY: Validate and sanitize request config to prevent SSRF (CWE-918)
// This ensures no malicious URLs from user input can be used
const sanitizedConfig = validateAndSanitizeConfig(updateRequestConfig(error, retryErrorType, wait))
// SECURITY: Using sanitizedConfig that has been validated against SSRF attacks
return axios(sanitizedConfig)
}
if (this.config.retryCondition && this.config.retryCondition(error)) {
Expand Down Expand Up @@ -477,8 +492,10 @@ export function ConcurrencyQueue ({ axios, config }) {
error.config.retryCount = retryCount
return new Promise(function (resolve) {
return setTimeout(function () {
// SSRF Prevention: Validate URL before making request
// SECURITY: Validate and sanitize request config to prevent SSRF (CWE-918)
// This ensures no malicious URLs from user input can be used
const sanitizedConfig = validateAndSanitizeConfig(updateRequestConfig(error, retryErrorType, delaytime))
// SECURITY: Using sanitizedConfig that has been validated against SSRF attacks
return resolve(axios(sanitizedConfig))
}, delaytime)
})
Expand Down
Loading
Loading