Skip to content

Conversation

radkrawczyk
Copy link
Contributor

@radkrawczyk radkrawczyk commented Jul 25, 2025

User description

TT-15301
Summary Mock response seems to be not executed when calling non-base version of OAS API.
Type Bug Bug
Status In Dev
Points N/A
Labels codilime_refined

Description

Related Issue

Motivation and Context

How This Has Been Tested

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Refactoring or add test (improvements in base code or adds test coverage to functionality)

Checklist

  • I ensured that the documentation is up to date
  • I explained why this PR updates go.mod in detail with reasoning why it's required
  • I would like a code coverage CI quality gate exception and have explained why

PR Type

Bug fix


Description

  • Fixes mock response execution for non-base OAS API versions

  • Adds path handling logic for OAS APIs in version check middleware

  • Ensures correct URL path joining for OAS API sub-versions

  • Retains classic API path sanitization logic


Diagram Walkthrough

flowchart LR
  request["Incoming Request"]
  versionCheck["VersionCheck Middleware"]
  isOAS["Is OAS API?"]
  joinPath["Join ListenPath and Stripped Path"]
  sanitizePath["Sanitize Proxy Paths"]
  handler["Serve HTTP Handler"]

  request -- "to" --> versionCheck
  versionCheck -- "check API type" --> isOAS
  isOAS -- "yes" --> joinPath
  isOAS -- "no" --> sanitizePath
  joinPath -- "update URL.Path" --> handler
  sanitizePath -- "update URL.Path" --> handler
Loading

File Walkthrough

Relevant files
Bug fix
mw_version_check.go
Fix OAS API version path handling in middleware                   

gateway/mw_version_check.go

  • Adds OAS-specific path joining logic for sub-version requests
  • Applies classic path sanitization only for non-OAS APIs
  • Updates request URL path for correct handler routing
  • Improves error handling for URL join failures
+14/-3   

@buger
Copy link
Member

buger commented Jul 25, 2025

Let's make that PR title a 💯 shall we? 💪

Your PR title and story title look slightly different. Just checking in to know if it was intentional!

Story Title Mock response seems to be not executed when calling non-base version of OAS API.
PR Title OAS api versions performing fixes

Check out this guide to learn more about PR best-practices.

Copy link
Contributor

github-actions bot commented Jul 25, 2025

PR Reviewer Guide 🔍

(Review updated until commit 848b2db)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Error Handling

The new logic for joining URL paths using url.JoinPath returns an error if the join fails. Ensure that all possible error cases are handled and that the error message provides enough context for debugging.

new_path, err := url.JoinPath(target_api.Proxy.ListenPath, stripped_path)
if err != nil {
	log.Errorf("Url Join Error, err: %s", err)
	return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
}
Path Manipulation Logic

The logic for constructing the new path for OAS APIs may introduce subtle routing bugs if target_api.Proxy.ListenPath or stripped_path contain unexpected values (e.g., missing or extra slashes). This should be validated with comprehensive test cases.

	stripped_path := v.Spec.StripListenPath(r.URL.Path)
	new_path, err := url.JoinPath(target_api.Proxy.ListenPath, stripped_path)
	if err != nil {
		log.Errorf("Url Join Error, err: %s", err)
		return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
	}
	r.URL.Path = new_path
} else {

Copy link
Contributor

github-actions bot commented Jul 25, 2025

PR Code Suggestions ✨

Latest suggestions up to 848b2db
Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Add nil check for API lookup

Add a nil check for target_api before accessing its fields to prevent a possible nil
pointer dereference if subVersionID is not found in apisByID.

gateway/mw_version_check.go [92-103]

 if v.Spec.IsOAS {
 	target_api := v.Gw.apisByID[subVersionID]
+	if target_api == nil {
+		log.Errorf("No API found for subVersionID: %s", subVersionID)
+		return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
+	}
 	stripped_path := v.Spec.StripListenPath(r.URL.Path)
 	new_path, err := url.JoinPath(target_api.Proxy.ListenPath, stripped_path)
 	if err != nil {
 		log.Errorf("Url Join Error, err: %s", err)
 		return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
 	}
 	r.URL.Path = new_path
 } else {
 	v.Spec.SanitizeProxyPaths(r)
 }
Suggestion importance[1-10]: 8

__

Why: This suggestion adds a nil check for target_api before accessing its fields, which prevents a potential nil pointer dereference and runtime panic if subVersionID is not found in apisByID. This is an important error handling improvement that increases the robustness of the code.

Medium

Previous suggestions

Suggestions up to commit 7c76968
CategorySuggestion                                                                                                                                    Impact
Possible issue
Prevent possible panic from empty string

The code assumes that v.Spec.Proxy.ListenPath has at least one character, which may
cause a runtime panic if the string is empty. Add a check to ensure the string is
not empty before slicing.

gateway/mw_version_check.go [92-93]

+if len(v.Spec.Proxy.ListenPath) == 0 {
+    log.Errorf("Proxy.ListenPath is empty")
+    return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
+}
 new_listen_path := v.Spec.Proxy.ListenPath[:len(v.Spec.Proxy.ListenPath)-1] + "-" + targetVersion
 r.URL.Path = new_listen_path + v.Spec.StripListenPath(r.URL.Path)
Suggestion importance[1-10]: 8

__

Why: This suggestion adds a necessary runtime check to prevent a potential panic when slicing an empty string, which would otherwise crash the application. It is accurate, directly addresses a real risk in the PR code, and improves robustness.

Medium
General
Ensure correct URL path concatenation

Concatenating paths without ensuring proper slashes may result in malformed URLs.
Ensure that new_listen_path ends with a single slash before joining with the
stripped path.

gateway/mw_version_check.go [92-93]

 new_listen_path := v.Spec.Proxy.ListenPath[:len(v.Spec.Proxy.ListenPath)-1] + "-" + targetVersion
-r.URL.Path = new_listen_path + v.Spec.StripListenPath(r.URL.Path)
+if !strings.HasSuffix(new_listen_path, "/") {
+    new_listen_path += "/"
+}
+r.URL.Path = new_listen_path + strings.TrimPrefix(v.Spec.StripListenPath(r.URL.Path), "/")
Suggestion importance[1-10]: 7

__

Why: This suggestion improves URL path handling by ensuring proper slash placement, which prevents malformed URLs. While not critical, it enhances correctness and reliability in path construction.

Medium

Copy link
Contributor

github-actions bot commented Jul 25, 2025

API Changes

no api changes detected

Copy link
Contributor

PR Review: OAS API Versions Path Handling Fix

Overview

This PR addresses a bug where mock responses were not being executed when calling non-base versions of OAS APIs. The issue was in the path handling logic for versioned APIs.

Technical Analysis

The change modifies how request paths are handled for non-base OAS API versions:

-v.Spec.SanitizeProxyPaths(r)
+new_listen_path := v.Spec.Proxy.ListenPath[:len(v.Spec.Proxy.ListenPath)-1] + "-" + targetVersion
+r.URL.Path = new_listen_path + v.Spec.StripListenPath(r.URL.Path)

What the fix does:

  1. Removes proxy path sanitization - The previous approach using SanitizeProxyPaths() wasn't correctly handling versioned paths for OAS APIs
  2. Creates a version-specific listen path - Constructs a new path by appending the version identifier to the base path
  3. Updates the request URL - Sets the URL path to use this new listen path plus the stripped original path

How this resolves the issue:

When a request is made to a non-base version of an OAS API, the handler now receives the correct path with proper version information, allowing it to correctly execute mock responses and other version-specific functionality.

Potential Concerns

  1. Empty ListenPath handling: The code assumes v.Spec.Proxy.ListenPath has at least one character. If empty, this could cause a panic when slicing with [:len(v.Spec.Proxy.ListenPath)-1].

  2. Path concatenation edge cases: There might be issues with path concatenation if the paths don't have the right slashes, potentially leading to malformed URLs.

Recommendation

The fix correctly addresses the issue with mock responses not executing for non-base OAS API versions. However, I recommend adding validation to prevent potential panics with empty paths and ensuring proper slash handling in path concatenation.


Tip: Mention me again using /connectivity <request>.
Powered by Probe AI
Connectivity Issues Reviewer Prompt for Tyk Gateway

Copy link
Contributor

Security Review: OAS API Versions Path Handling Fix

Overview

This PR fixes an issue where mock responses were not being executed when calling non-base versions of OAS API. The change modifies how request paths are handled for versioned APIs to ensure proper routing.

Key Changes

The PR makes a targeted change to gateway/mw_version_check.go:

  • Removes v.Spec.SanitizeProxyPaths(r) call
  • Adds code to construct a proper listen path with version suffix
  • Sets the URL path correctly to ensure proper handler invocation
- v.Spec.SanitizeProxyPaths(r)
+ new_listen_path := v.Spec.Proxy.ListenPath[:len(v.Spec.Proxy.ListenPath)-1] + "-" + targetVersion
+ r.URL.Path = new_listen_path + v.Spec.StripListenPath(r.URL.Path)

Security Analysis

Potential Issues

  1. Path Manipulation: The code assumes v.Spec.Proxy.ListenPath is non-empty and has at least one character. If it's empty, this could cause a panic due to the slice operation.

  2. URL Path Construction: The concatenation of paths without proper slash handling could potentially lead to malformed URLs in some edge cases.

Mitigating Factors

  • The code operates in a controlled environment where ListenPath is typically set
  • The PR doesn't introduce new user input handling that could be exploited
  • The change is focused on internal path handling rather than security boundaries

Recommendations

  1. Add Empty Path Check: Consider adding validation to ensure v.Spec.Proxy.ListenPath is not empty before performing the substring operation.

  2. Ensure Proper Path Joining: Consider normalizing slash handling when joining paths to prevent potential path issues.

Conclusion

This PR appears to be a functional fix with minimal security implications. The changes are focused on ensuring correct internal routing for versioned APIs, particularly for mock responses. The potential issues identified are edge cases rather than security vulnerabilities.

While there are some minor improvements that could be made for robustness, the PR as implemented should resolve the reported issue without introducing significant security concerns.


Tip: Mention me again using /security <request>.
Powered by Probe AI
Security Impact Reviewer Prompt

Copy link
Contributor

Dependency Impact Analysis: OAS API Versions Mock Response Fix

Issue Overview

The PR addresses a bug where mock responses were not being executed when calling non-base versions of OAS APIs. This was happening because the path handling for versioned APIs was incorrect, preventing the proper invocation of mock response handlers.

Code Changes Analysis

The fix makes two critical changes to the ProcessRequest method in mw_version_check.go:

  1. Removes incorrect path sanitization:

    // Old code
    v.Spec.SanitizeProxyPaths(r)

    This method was incorrectly modifying the request path for versioned APIs, causing mock response handlers to not be triggered.

  2. Adds proper versioned path construction:

    // New code
    new_listen_path := v.Spec.Proxy.ListenPath[:len(v.Spec.Proxy.ListenPath)-1] + "-" + targetVersion
    r.URL.Path = new_listen_path + v.Spec.StripListenPath(r.URL.Path)

    This creates a properly formatted path that includes the version suffix, ensuring the correct handler is invoked.

Dependency Impact

Direct Dependencies

  • StripListenPath: The fix now relies on this method to correctly strip the listen path from the request URL path.
  • Handler Invocation: The change affects how internal API handlers are invoked for versioned endpoints.

Potential Risks

  1. Empty ListenPath: The code assumes v.Spec.Proxy.ListenPath has at least one character, which could cause a runtime panic if empty.
  2. Path Concatenation: There's no explicit handling to ensure proper slash placement when joining paths, which could potentially lead to malformed URLs in edge cases.

Affected Functionality

  • Mock Response Execution: This fix directly impacts the execution of mock responses for non-base OAS API versions.
  • Path Routing: Changes how request paths are constructed and routed for versioned APIs.

Conclusion

The change is focused and addresses the specific issue of mock responses not executing for non-base OAS API versions. The implementation correctly modifies the request path to include the version suffix and uses the appropriate internal handler.

While there are some potential edge cases around empty paths and slash handling, the fix is generally sound and should resolve the reported issue without introducing significant new risks. The PR successfully ensures that mock responses work consistently across all API versions.


Tip: Mention me again using /dependency <request>.
Powered by Probe AI
Tyk Gateway Dependency Impact Reviewer

Copy link
Contributor

PR Review: Fix for Mock Response Execution in Non-Base OAS API Versions

Issue Summary

The PR addresses a bug where mock responses were not being executed when calling non-base versions of OAS APIs. This occurred because the path handling for versioned APIs was not correctly managing the listen path, which prevented the proper handler from being invoked for mock responses.

Root Cause Analysis

When a request is made to a non-base version of an OAS API, the VersionCheck middleware is responsible for routing the request to the correct API version handler. The issue was in the path handling logic:

  1. Previously, the code used v.Spec.SanitizeProxyPaths(r) which would strip the listen path from the URL but didn't properly account for the version suffix in the path.

  2. This caused the request to be forwarded to the handler with an incorrect path, resulting in mock responses not being executed for non-base API versions.

Solution Implemented

The PR replaces the previous path handling with a more explicit approach:

// Old code
v.Spec.SanitizeProxyPaths(r)

// New code
new_listen_path := v.Spec.Proxy.ListenPath[:len(v.Spec.Proxy.ListenPath)-1] + "-" + targetVersion
r.URL.Path = new_listen_path + v.Spec.StripListenPath(r.URL.Path)

This change:

  1. Creates a new listen path by appending the version suffix to the base listen path
  2. Strips the original listen path from the URL
  3. Prepends the new versioned listen path to the stripped URL path

This ensures that the request is forwarded to the correct handler with the proper path structure, allowing mock responses to be correctly executed for non-base API versions.

Technical Assessment

Strengths

  • The fix is minimal and focused on the specific issue
  • It maintains the existing API behavior while fixing the bug
  • The solution aligns with the existing architecture of path handling in Tyk

Potential Concerns

  1. Edge Case Handling: The code assumes that v.Spec.Proxy.ListenPath is not empty and ends with a slash. If either condition is not met, it could lead to runtime errors.

  2. Path Concatenation: The solution directly concatenates paths without ensuring proper slash handling, which could potentially lead to malformed URLs in some edge cases.

Testing Considerations

The PR should be tested with:

  1. OAS APIs with multiple versions
  2. Mock responses configured on non-base versions
  3. Various path configurations to ensure robustness
  4. Edge cases like empty listen paths or paths without trailing slashes

Conclusion

This PR effectively fixes the issue with mock responses not executing for non-base OAS API versions by correctly handling the path transformation for versioned APIs. The implementation is straightforward and aligns with the existing codebase architecture, though some additional validation could be added to handle edge cases more robustly.


Tip: Mention me again using /performance <request>.
Powered by Probe AI
Performance Impact Reviewer Prompt

Copy link
Contributor

📦 Impact Review Snapshot

Effort Downstream Updates Compatibility Docs TL;DR
Low 🟢 📖 Path handling fix for OAS API versions that doesn't affect external interfaces
## Impact Assessment

This PR fixes a bug where mock responses weren't executing for non-base versions of OAS APIs by modifying the internal path handling logic. The change is isolated to the gateway's internal request processing and doesn't alter any API schemas, protocols, or interfaces. The fix properly constructs versioned paths for OAS APIs by appending the version suffix to the listen path, rather than using the generic path sanitization method that was causing the issue.

## Required Updates

No updates are required in downstream repositories:

  • tyk-operator: No impact as the change doesn't modify API definitions schema or OAS structures
  • tyk-charts: No configuration changes needed as this is an internal path handling fix
  • portal: No impact as the API definition structure remains unchanged
  • tyk-sink (MDCB): No impact as the fix doesn't affect RPC protocols or data synchronization
## Compatibility Concerns

The change is backward compatible and doesn't introduce any breaking changes:

  • Existing API definitions will continue to work as before
  • Non-OAS APIs are explicitly handled with the original code path
  • The fix only affects how internal request paths are constructed for versioned OAS APIs
  • No changes to external interfaces, protocols, or data structures
## Summary & Recommendations
  • This is a focused bug fix that addresses path handling for versioned OAS APIs without affecting external interfaces
  • The implementation is straightforward and maintains compatibility with existing behavior
  • No downstream repository updates are required as the change is isolated to internal request processing
  • No suggestions to provide – change LGTM.

Tip: Mention me again using /dependency <request>.
Powered by Probe AI
Tyk Gateway Dependency Impact Reviewer

Copy link
Contributor

Performance Impact Analysis of OAS API Versioning Fix

🚀 Performance Snapshot

Effort Perf Risk Hot Paths Benchmarks TL;DR
Low 🟢 Path handling change for OAS API versions with minimal performance impact
## Performance Impact Analysis

The PR addresses a bug where mock responses weren't executing for non-base versions of OAS APIs by modifying path handling in the VersionCheck middleware. The change replaces a call to SanitizeProxyPaths() with custom path construction for OAS APIs.

From a performance perspective, this change is minimal and focused on a specific code path that only executes when handling versioned OAS APIs. The new code performs simple string operations (substring, concatenation) which are efficient and have predictable performance characteristics.

The change doesn't introduce any new loops, database calls, or expensive operations that would significantly impact request processing time.

## Critical Areas

The modified code is in the request processing path, which is performance-sensitive, but the changes are lightweight:

  1. String Operations: The new code performs a substring operation and string concatenation, which are O(n) operations but with very small input sizes.

  2. Path Handling: The change affects how request paths are constructed for versioned OAS APIs, which is fundamental to routing but not computationally expensive.

  3. No Additional I/O: The fix doesn't introduce any new I/O operations or external service calls.

## Optimization Recommendations

While the current implementation is efficient for most cases, there are a few potential improvements:

  1. Empty Path Check: Add validation to ensure v.Spec.Proxy.ListenPath is not empty before performing the substring operation to prevent potential panics.

  2. Path Normalization: Consider normalizing slash handling when joining paths to prevent potential path issues in edge cases.

  3. Caching: For high-traffic APIs with many versioned endpoints, consider caching the constructed listen paths to avoid repeated string operations.

## Summary
  • The PR makes a targeted change to path handling for OAS API versions with minimal performance impact
  • The string operations introduced are lightweight and occur only on the specific path for versioned OAS APIs
  • The fix doesn't introduce any new expensive operations or potential bottlenecks
  • No suggestions to provide – change LGTM.

Tip: Mention me again using /performance <request>.
Powered by Probe AI
Performance Impact Reviewer Prompt

Copy link
Contributor

🛡️ Security Snapshot

Effort Risk Level Tests Compliance TL;DR
Low 🟡 ⚠️ ✔️ Fix for mock responses in non-base OAS API versions with potential edge cases
## Security Impact Analysis

The PR addresses a bug where mock responses weren't executing for non-base versions of OAS APIs. The fix modifies the path handling logic in mw_version_check.go to properly construct version-specific paths for OAS APIs. This change is focused on functionality rather than security, but does involve URL path manipulation which warrants security consideration.

The new code creates a version-specific listen path by removing the trailing slash from the base path and appending the version identifier. This approach is more direct than the previous method using SanitizeProxyPaths() and correctly ensures that mock responses work for versioned APIs by allowing the findOperation() function to correctly match the request to the appropriate operation.

## Identified Vulnerabilities

Medium Risk:

  • Potential Panic Condition: The code assumes v.Spec.Proxy.ListenPath has at least one character when it performs [:len(v.Spec.Proxy.ListenPath)-1]. If the listen path is empty, this will cause a runtime panic.

Low Risk:

  • Path Manipulation Edge Cases: The concatenation of paths without proper slash handling could potentially lead to malformed URLs in some edge cases, though this is unlikely to be exploitable.
  • Inconsistent Path Handling: Different path handling logic for OAS vs. non-OAS APIs could potentially lead to inconsistent behavior in mixed environments.
## Security Recommendations
  1. Add Empty Path Check: Add validation to ensure v.Spec.Proxy.ListenPath is not empty before performing the substring operation:

    if len(v.Spec.Proxy.ListenPath) == 0 {
        log.Error("Empty listen path encountered")
        return errors.New("internal server error"), http.StatusInternalServerError
    }
  2. Normalize Path Joining: Consider using a more robust path joining approach to ensure proper slash handling:

    if !strings.HasSuffix(new_listen_path, "/") {
        new_listen_path += "/"
    }
    r.URL.Path = new_listen_path + strings.TrimPrefix(v.Spec.StripListenPath(r.URL.Path), "/")
  3. Add Unit Tests: Create specific tests for this path handling logic with various edge cases to ensure robustness.

## OWASP Compliance

This change doesn't directly impact OWASP Top 10 categories, but relates to:

  • A05:2021 - Security Misconfiguration: Proper path handling is important for ensuring requests are routed correctly. The fix improves this aspect but could be more robust.

  • A06:2021 - Vulnerable and Outdated Components: The fix ensures that all API versions work correctly with mock responses, improving the overall reliability of the system.

## Summary
  • The PR correctly fixes the issue with mock responses not executing for non-base OAS API versions
  • The implementation has a potential panic condition if the listen path is empty
  • Path concatenation could be improved to handle edge cases more robustly
  • Overall, the security impact is minimal, but the identified issues should be addressed

Tip: Mention me again using /security <request>.
Powered by Probe AI
Security Impact Reviewer Prompt

Copy link
Contributor

🚦 Connectivity Review Snapshot

Effort Tests Security Perf TL;DR
Low ⚠️ 🔒 none 🟢 Fixed mock response execution for non-base OAS API versions by correctly handling versioned paths
## Connectivity Assessment
  • Redis Connections: No changes to Redis connectivity in this PR.
  • RPC Connections: No changes to RPC connectivity or MDCB mode in this PR.
  • Synchronization Mechanisms: The PR fixes path handling for versioned OAS APIs, ensuring that the correct internal handler is invoked with properly formatted paths, which indirectly affects how mock responses are synchronized with client requests.
## Test Coverage Validation
  • Redis Tests: Not applicable as this PR doesn't modify Redis functionality.
  • RPC Tests: Not applicable as this PR doesn't modify RPC functionality.
  • Failure Scenario Tests: No specific tests were added to verify the fix. It would be beneficial to add tests that confirm mock responses work correctly for non-base versions of OAS APIs.
## Security & Performance Impact
  • Authentication Changes: No authentication changes in this PR.
  • Performance Considerations: The fix adds minimal overhead (string manipulation) during path processing for versioned OAS APIs, which is negligible.
  • Error Handling: The PR maintains existing error handling for missing API handlers, with no new error paths introduced.
## Summary & Recommendations
  • The PR correctly addresses the issue by modifying how paths are handled for non-base versions of OAS APIs, ensuring that mock responses are properly executed.
  • The implementation is straightforward and focused on the specific issue, with minimal impact on other functionality.
  • Consider adding validation to prevent potential panics if v.Spec.Proxy.ListenPath is empty, as the substring operation could cause a runtime error.
  • Consider adding tests that specifically verify mock responses work for non-base versions of OAS APIs.

Tip: Mention me again using /connectivity <request>.
Powered by Probe AI
Connectivity Issues Reviewer Prompt for Tyk Gateway

Copy link
Contributor

Analysis of PR #7254: OAS API Versions Path Handling Fix

Issue Overview

This PR addresses a bug where mock responses were not being executed when calling non-base versions of OAS APIs. The issue was in the path handling logic for versioned APIs, which prevented the correct operation from being found in the OAS definition.

Technical Analysis

Root Cause

When a request is made to a non-base version of an OAS API, the VersionCheck middleware is responsible for routing the request to the correct API version handler. The issue was that for OAS APIs, the code was using v.Spec.SanitizeProxyPaths(r) which wasn't correctly handling the versioned paths, causing the findOperation method to fail to find the correct operation in the OAS definition.

Solution

The PR modifies the path handling logic for versioned OAS APIs:

// Before
v.Spec.SanitizeProxyPaths(r)

// After
target_api := v.Gw.apisByID[subVersionID]
stripped_path := v.Spec.StripListenPath(r.URL.Path)
new_path, err := url.JoinPath(target_api.Proxy.ListenPath, stripped_path)
if err != nil {
    log.Errorf("Url Join Error, err: %s", err)
    return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
}
r.URL.Path = new_path

This change ensures that:

  1. The listen path is correctly stripped from the original URL
  2. The target API's listen path is properly joined with the stripped path
  3. The request URL is updated with the new path

By fixing the path handling, the findOperation method can now correctly find the operation in the OAS definition, allowing mock responses to be executed for non-base versions of OAS APIs.

Impact on Downstream Repositories

This PR has no impact on downstream repositories:

  1. tyk-operator: No changes to API definition schemas or OAS structures
  2. tyk-charts: No configuration changes or environment variable modifications
  3. portal: No changes to how API definitions are stored or retrieved
  4. tyk-sink (MDCB): No modifications to RPC protocols or data synchronization

Potential Concerns

  1. Empty Path Handling: The PR doesn't explicitly check if target_api.Proxy.ListenPath is empty before using it in url.JoinPath(). However, this is handled by the url.JoinPath() function which can handle empty paths.

  2. Path Concatenation: The PR uses url.JoinPath() which properly handles slash concatenation, addressing potential issues with malformed URLs.

Conclusion

This PR is a focused bug fix that addresses a specific issue with path handling for versioned OAS APIs. It ensures that mock responses work correctly for non-base versions of OAS APIs without affecting external interfaces or downstream repositories. The implementation is straightforward and uses standard Go libraries for path handling, making it a safe and effective solution.


Tip: Mention me again using /dependency <request>.
Powered by Probe AI
Tyk Gateway Dependency Impact Reviewer

Copy link
Contributor

Analysis of PR #7254: OAS API Versions Path Handling Fix

This PR addresses a bug where mock responses were not being executed when calling non-base versions of OAS APIs. The issue was in the path handling logic for versioned APIs.

Core Changes

The main fix is in gateway/mw_version_check.go where the code now handles path routing differently for OAS API versions:

// Before
v.Spec.SanitizeProxyPaths(r)

// After
if v.Spec.IsOAS {
    target_api := v.Gw.apisByID[subVersionID]
    stripped_path := v.Spec.StripListenPath(r.URL.Path)
    new_path, err := url.JoinPath(target_api.Proxy.ListenPath, stripped_path)
    if err != nil {
        log.Errorf("Url Join Error, err: %s", err)
        return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
    }
    r.URL.Path = new_path
} else {
    v.Spec.SanitizeProxyPaths(r)
}

How This Fixes the Issue

The problem was that for non-base versions of OAS APIs, the request path wasn't being properly constructed to include the version information. This caused the mock response handlers to not be triggered correctly.

The fix:

  1. Identifies when we're dealing with an OAS API
  2. Gets the target API using the version ID
  3. Strips the listen path from the request URL
  4. Joins the target API's listen path with the stripped path
  5. Sets the new path on the request

This ensures that the request is properly routed to the correct handler for the versioned API, allowing mock responses to be executed correctly.

Potential Concerns

  1. The code assumes v.Spec.Proxy.ListenPath is not empty. If it's empty, this could potentially cause issues.
  2. Path concatenation could have edge cases with slash handling, though the use of url.JoinPath should mitigate most of these.

Overall, this is a focused fix that addresses the specific issue without introducing significant new complexity.


Tip: Mention me again using /performance <request>.
Powered by Probe AI
Performance Impact Reviewer Prompt

Copy link
Contributor

Analysis of OAS API Versions Mock Response Fix

Issue Summary

The PR addresses a bug where mock responses were not being executed when calling non-base versions of OAS APIs. This occurred because the path handling for versioned APIs wasn't correctly managing the listen path, which prevented the proper handler from being invoked for mock responses.

Root Cause

When a request is made to a non-base version of an OAS API, the VersionCheck middleware is responsible for routing the request to the correct API version handler. The issue was in the path handling logic:

  1. Previously, the code used v.Spec.SanitizeProxyPaths(r) for all APIs, which didn't properly account for OAS APIs with version suffixes in the path.

  2. This caused the request to be forwarded with an incorrect path structure, preventing the findOperation() method from matching the request to the appropriate OAS operation, resulting in mock responses not being executed.

Solution

The PR implements a conditional approach to path handling based on API type:

if v.Spec.IsOAS {
    target_api := v.Gw.apisByID[subVersionID]
    stripped_path := v.Spec.StripListenPath(r.URL.Path)
    new_path, err := url.JoinPath(target_api.Proxy.ListenPath, stripped_path)
    if err != nil {
        log.Errorf("Url Join Error, err: %s", err)
        return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
    }
    r.URL.Path = new_path
} else {
    v.Spec.SanitizeProxyPaths(r)
}

This change:

  1. For OAS APIs, it properly constructs the path by:

    • Getting the target API definition
    • Stripping the listen path from the request URL
    • Joining the target API's listen path with the stripped path
    • Setting the request URL path to this new path
  2. For non-OAS APIs, it continues to use the existing SanitizeProxyPaths method.

Technical Impact

The fix ensures that when a request is made to a non-base version of an OAS API:

  1. The path is correctly constructed to include the version information
  2. The findOperation() method can properly match the request to the corresponding OAS operation
  3. The mock response middleware can correctly identify and execute the appropriate mock response

This is a targeted fix that addresses a specific issue without introducing new functionality or changing existing behavior. It simply ensures that the existing functionality works correctly for all API versions.


Tip: Mention me again using /security <request>.
Powered by Probe AI
Security Impact Reviewer Prompt

Copy link
Contributor

Understanding the OAS API Versioning Fix

The Issue

The PR addresses a bug where mock responses weren't being executed when calling non-base versions of OAS APIs. This occurred because of how path handling was implemented for versioned APIs in the VersionCheck middleware.

Root Cause Analysis

When a request is made to a non-base version of an OAS API, the following sequence occurs:

  1. The VersionCheck middleware identifies that the request is for a non-base version
  2. It finds the appropriate handler for that version
  3. It modifies the request path before passing it to the handler
  4. The mockResponseMiddleware tries to find the appropriate operation to serve a mock response

The issue was in step 3. Previously, all APIs (both classic and OAS) used v.Spec.SanitizeProxyPaths(r) to modify the request path. For OAS APIs, this approach didn't correctly handle the path for versioned APIs, causing the findOperation() method to fail to match the request to the correct operation.

Looking at the mockResponse method:

func (m *mockResponseMiddleware) mockResponse(r *http.Request) (*http.Response, error) {
    // if response is nil we go further
    operation := m.Spec.findOperation(r)
    
    if operation == nil {
        return nil, nil
    }
    
    mockResponse := operation.MockResponse
    if mockResponse == nil || !mockResponse.Enabled {
        return nil, nil
    }
    
    // ... serve mock response
}

The key issue is that findOperation() was returning nil because the path handling for versioned OAS APIs was incorrect, preventing the mock response from being served.

The Fix

The PR modifies the VersionCheck middleware to handle path construction differently for OAS APIs:

if v.Spec.IsOAS {
    target_api := v.Gw.apisByID[subVersionID]
    stripped_path := v.Spec.StripListenPath(r.URL.Path)
    new_path, err := url.JoinPath(target_api.Proxy.ListenPath, stripped_path)
    if err != nil {
        log.Errorf("Url Join Error, err: %s", err)
        return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
    }
    r.URL.Path = new_path
} else {
    v.Spec.SanitizeProxyPaths(r)
}

This change:

  1. For OAS APIs:
    • Gets the target API using the version ID
    • Strips the listen path from the original request URL
    • Joins the target API's listen path with the stripped path
    • Updates the request URL path with this new path
  2. For classic APIs, continues to use the existing SanitizeProxyPaths method

Why This Fixes the Issue

The fix works because:

  1. It ensures the request path is correctly formatted for the target API version
  2. This allows the findOperation() method to correctly match the request to the appropriate operation in the OAS definition
  3. When the operation is correctly identified, the mockResponseMiddleware can find and use the mock response configuration

The key insight is that OAS APIs need special path handling for versioned endpoints to ensure the correct operation is found, which is essential for features like mock responses to work properly.

Technical Details

The findOperation method in model_apispec.go is critical to this process:

func (a *APISpec) findOperation(r *http.Request) *Operation {
    middleware := a.OAS.GetTykMiddleware()
    if middleware == nil {
        return nil
    }

    if a.oasRouter == nil {
        log.Warningf("OAS router not initialized properly. Unable to find route for %s %v", r.Method, r.URL)
        return nil
    }

    rClone := *r
    rClone.URL = ctxGetInternalRedirectTarget(r)

    route, pathParams, err := a.oasRouter.FindRoute(&rClone)
    
    if err != nil {
        // Log and return nil
        return nil
    }

    operation, ok := middleware.Operations[route.Operation.OperationID]
    if !ok {
        log.Warningf("No operation found for ID: %s", route.Operation.OperationID)
        return nil
    }

    return &Operation{
        Operation:  operation,
        route:      route,
        pathParams: pathParams,
    }
}

With the corrected path handling, this function can now successfully find the operation for versioned APIs, allowing mock responses to be executed correctly.


Tip: Mention me again using /connectivity <request>.
Powered by Probe AI
Connectivity Issues Reviewer Prompt for Tyk Gateway

@radkrawczyk radkrawczyk force-pushed the TT-15301-Mock-response-seems-to-be-not-executed-when-calling-non-base-version-of-OAS-API branch from 9b36cfa to 848b2db Compare July 30, 2025 10:30
Copy link
Contributor

🚀 Performance Snapshot

Effort Perf Risk Hot Paths Benchmarks TL;DR
Low 🟢 Path handling fix for OAS API versions with minimal performance impact
## Performance Impact Analysis

The PR modifies how request paths are handled for non-base versions of OAS APIs. The change replaces a simple string manipulation approach with a more robust path handling implementation using url.JoinPath(). This occurs in the request processing path but involves only lightweight string operations with negligible performance overhead. The modification is isolated to versioned OAS API requests and doesn't affect other request types.

## Critical Areas

The changes touch the request processing middleware which is in the hot path, but the modifications are lightweight:

  1. API Lookup: The new code adds a map lookup (v.Gw.apisByID[subVersionID]) which is an O(1) operation.

  2. Path Manipulation: The previous approach used string slicing and concatenation, while the new approach uses StripListenPath() and url.JoinPath(). Both approaches have similar performance characteristics for typical path lengths.

  3. Error Handling: The addition of error handling for url.JoinPath() adds minimal overhead but improves robustness.

## Optimization Recommendations

The implementation is already well-optimized for the specific use case:

  1. Proper Path Joining: Using url.JoinPath() is a good choice as it correctly handles slash placement, avoiding potential issues with malformed URLs that could occur with simple string concatenation.

  2. Error Handling: The added error handling is appropriate and provides useful logging information.

  3. Conditional Logic: The separation of OAS and non-OAS API handling ensures that each type is processed optimally.

## Summary
  • The PR fixes a specific issue with mock responses not executing for non-base OAS API versions
  • The changes involve simple string operations with negligible performance impact
  • The fix properly uses standard library functions for URL path handling, improving correctness
  • The code path is only executed for versioned OAS APIs, limiting any performance impact to those specific requests
  • No suggestions to provide – change LGTM.

Tip: Mention me again using /performance <request>.
Powered by Probe AI
Performance Impact Reviewer Prompt

Copy link
Contributor

Analysis of PR #7254: OAS API Versions Path Handling Fix

Issue Overview

This PR addresses a bug (TT-15301) where mock responses were not being executed when calling non-base versions of OAS APIs. The issue was in the path handling logic for versioned APIs, which prevented the correct operation from being found in the OAS definition.

Root Cause Analysis

When a request is made to a non-base version of an OAS API, the VersionCheck middleware is responsible for routing the request to the correct API version handler. The issue was in the path handling logic:

Previously, the code was using a simplistic approach to construct the versioned path:

new_listen_path := v.Spec.Proxy.ListenPath[:len(v.Spec.Proxy.ListenPath)-1] + "-" + targetVersion
r.URL.Path = new_listen_path + v.Spec.StripListenPath(r.URL.Path)

This approach didn't correctly handle the path for OAS APIs with version suffixes, causing the findOperation() method to fail to match the request to the appropriate operation in the OAS definition, resulting in mock responses not being executed.

Solution Implementation

The PR implements a more robust approach to path handling for OAS APIs:

if v.Spec.IsOAS {
    target_api := v.Gw.apisByID[subVersionID]
    stripped_path := v.Spec.StripListenPath(r.URL.Path)
    new_path, err := url.JoinPath(target_api.Proxy.ListenPath, stripped_path)
    if err != nil {
        log.Errorf("Url Join Error, err: %s", err)
        return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
    }
    r.URL.Path = new_path
} else {
    v.Spec.SanitizeProxyPaths(r)
}

This change:

  1. Differentiates between OAS and non-OAS APIs
  2. For OAS APIs:
    • Gets the target API definition using the version ID
    • Strips the listen path from the request URL
    • Properly joins the target API's listen path with the stripped path using url.JoinPath()
    • Updates the request URL path with this new path
  3. For non-OAS APIs, continues to use the existing SanitizeProxyPaths method

Benefits of the Fix

  1. Ensures that mock responses work correctly for all versions of OAS APIs
  2. Uses the standard url.JoinPath() function which properly handles path joining with correct slash handling
  3. Provides better error handling for path construction failures
  4. Maintains backward compatibility with non-OAS APIs

The fix is minimal and focused on the specific issue without introducing new functionality or changing existing behavior. It simply ensures that the existing functionality works correctly for all API versions.


Tip: Mention me again using /dependency <request>.
Powered by Probe AI
Tyk Gateway Dependency Impact Reviewer

Copy link
Contributor

🛡️ Security Snapshot

Effort Risk Level Tests Compliance TL;DR
Low 🟢 ✔️ Path handling fix for OAS API versions with minimal security impact
## Security Impact Analysis

This PR fixes a bug where mock responses weren't being executed when calling non-base versions of OAS APIs. The issue was in the path handling logic in the VersionCheck middleware, which didn't correctly construct the path for versioned OAS APIs. The fix properly handles path construction by using url.JoinPath() to ensure correct path formatting, which is a more robust approach than the previous string concatenation method.

## Identified Vulnerabilities

No significant vulnerabilities were introduced by this change. The PR actually improves security by:

  1. Using the standard url.JoinPath() function which properly handles path joining with appropriate slashes
  2. Adding proper error handling for the path joining operation
  3. Ensuring that the correct handler is invoked for versioned APIs
## Security Recommendations

The implementation is secure as it uses standard library functions for path manipulation and includes proper error handling. No additional security measures are needed for this specific change.

## OWASP Compliance

This change doesn't directly impact OWASP Top 10 categories. It's a functional fix for internal path handling that doesn't affect authentication, authorization, or input validation mechanisms. The use of url.JoinPath() is a good practice that helps prevent potential path manipulation issues.

## Summary
  • The PR fixes a specific issue with path handling for versioned OAS APIs
  • The implementation uses secure methods for path manipulation with proper error handling
  • The change is minimal and focused on the specific issue without introducing new security concerns
  • No security issues identified – change LGTM.

Tip: Mention me again using /security <request>.
Powered by Probe AI
Security Impact Reviewer Prompt

Copy link
Contributor

Understanding the OAS API Versioning Mock Response Fix

The Issue

The PR addresses a bug where mock responses were not being executed when calling non-base versions of OAS APIs. This occurred because of how path handling was implemented in the VersionCheck middleware for versioned APIs.

Root Cause Analysis

When a request is made to a non-base version of an OAS API, the following sequence occurs:

  1. The VersionCheck middleware identifies that the request is for a non-base version
  2. It finds the appropriate handler for that version using subVersionID
  3. It modifies the request path before passing it to the handler
  4. The mockResponseMiddleware tries to find the appropriate operation to serve a mock response

The issue was in step 3. Before the fix, the code was using a generic approach for all API types:

new_listen_path := v.Spec.Proxy.ListenPath[:len(v.Spec.Proxy.ListenPath)-1] + "-" + targetVersion
r.URL.Path = new_listen_path + v.Spec.StripListenPath(r.URL.Path)

This approach didn't work correctly for OAS APIs because:

  1. It constructed a path that didn't match the expected format for the OAS router
  2. When the findOperation method was called in the mock response middleware, it couldn't find the correct operation because the path didn't match any route in the OAS definition
  3. As a result, no mock response was served for non-base versions of OAS APIs

The Fix

The PR introduces a conditional path handling approach based on whether the API is an OAS API or not:

if v.Spec.IsOAS {
    target_api := v.Gw.apisByID[subVersionID]
    stripped_path := v.Spec.StripListenPath(r.URL.Path)
    new_path, err := url.JoinPath(target_api.Proxy.ListenPath, stripped_path)
    if err != nil {
        log.Errorf("Url Join Error, err: %s", err)
        return errors.New(http.StatusText(http.StatusInternalServerError)), http.StatusInternalServerError
    }
    r.URL.Path = new_path
} else {
    v.Spec.SanitizeProxyPaths(r)
}

This fix:

  1. For OAS APIs:

    • Gets the target API definition using the version ID
    • Strips the listen path from the original request URL
    • Properly joins the target API's listen path with the stripped path using url.JoinPath
    • Updates the request URL path with this new path
  2. For non-OAS APIs:

    • Continues to use the existing SanitizeProxyPaths method

The key improvement is that for OAS APIs, the path is now constructed in a way that the OAS router can correctly match it to an operation in the OAS definition. This allows the findOperation method in the mock response middleware to find the correct operation and serve the mock response.

Why This Works

The fix works because:

  1. It ensures the request path is correctly formatted for the target API version
  2. This allows the findOperation method to correctly match the request to the appropriate operation in the OAS definition
  3. When the operation is correctly identified, the mockResponseMiddleware can find and use the mock response configuration

The use of url.JoinPath also ensures proper path joining with correct handling of slashes, which prevents potential issues with malformed URLs.

Technical Impact

This change only affects the internal path handling for versioned OAS APIs and doesn't modify any external interfaces or behaviors. It's a targeted fix that ensures existing functionality (mock responses) works correctly for all API versions.


Tip: Mention me again using /connectivity <request>.
Powered by Probe AI
Connectivity Issues Reviewer Prompt for Tyk Gateway

Copy link
Contributor

Persistent review updated to latest commit 848b2db

Copy link
Contributor

github-actions bot commented Aug 4, 2025

🚀 Performance Snapshot

Effort Perf Risk Hot Paths Benchmarks TL;DR
Low 🟢 Path handling fix for OAS API versions with minimal performance impact
## Performance Impact Analysis

The PR fixes a bug where mock responses weren't executing for non-base versions of OAS APIs by modifying path handling in the VersionCheck middleware. The change introduces a conditional path to handle OAS APIs differently from classic APIs. For OAS APIs, it retrieves the target API, strips the listen path, joins it with the target API's listen path using url.JoinPath(), and updates the request URL. This occurs in the request processing path but involves only lightweight string operations with negligible performance overhead.

## Critical Areas

The changes touch the request processing middleware which is in the hot path, but the modifications are lightweight:

  1. API Lookup: The code adds a map lookup (v.Gw.apisByID[subVersionID]) which is an O(1) operation.

  2. Path Manipulation: The new approach uses StripListenPath() and url.JoinPath() which are efficient string operations with similar performance characteristics to the previous implementation.

  3. Conditional Logic: The added if v.Spec.IsOAS check introduces minimal branching overhead but improves correctness for OAS APIs.

## Optimization Recommendations

The implementation is already well-optimized for the specific use case:

  1. Proper Path Joining: Using url.JoinPath() is a good choice as it correctly handles slash placement, avoiding potential issues with malformed URLs that could occur with simple string concatenation.

  2. Error Handling: The added error handling for url.JoinPath() is appropriate and provides useful context for debugging.

  3. API Type Check: The conditional logic that separates OAS and non-OAS API handling ensures each type is processed optimally.

## Summary
  • The PR fixes a specific issue with mock responses not executing for non-base OAS API versions
  • The changes involve simple string operations with negligible performance impact
  • The fix properly uses standard library functions for URL path handling, improving correctness
  • The code path is only executed for versioned OAS APIs, limiting any performance impact to those specific requests
  • No suggestions to provide – change LGTM.

Tip: Mention me again using /performance <request>.
Powered by Probe AI
Performance Impact Reviewer Prompt

Copy link
Contributor

github-actions bot commented Aug 4, 2025

📦 Impact Review Snapshot

Effort Downstream Updates Compatibility Docs TL;DR
Low 🟢 📖 Path handling fix for OAS API versions that doesn't affect external interfaces
Impact Assessment

This PR fixes a bug where mock responses weren't executing for non-base versions of OAS APIs by modifying the internal path handling logic. The change is isolated to the gateway's internal request processing and doesn't alter any API schemas, protocols, or interfaces. The fix properly constructs versioned paths for OAS APIs by appending the version suffix to the listen path, rather than using the generic path sanitization method that was causing the issue.

Required Updates

No updates are required in downstream repositories:

  • tyk-operator: No impact as the change doesn't modify API definitions schema or OAS structures
  • tyk-charts: No configuration changes needed as this is an internal path handling fix
  • portal: No impact as the API definition structure remains unchanged
  • tyk-sink (MDCB): No impact as the fix doesn't affect RPC protocols or data synchronization
Compatibility Concerns

The change is backward compatible and doesn't introduce any breaking changes:

  • Existing API definitions will continue to work as before
  • Non-OAS APIs are explicitly handled with the original code path
  • The fix only affects how internal request paths are constructed for versioned OAS APIs
  • No changes to external interfaces, protocols, or data structures
Summary & Recommendations
  • This is a focused bug fix that addresses path handling for versioned OAS APIs without affecting external interfaces
  • The implementation is straightforward and maintains compatibility with existing behavior
  • No downstream repository updates are required as the change is isolated to internal request processing
  • No suggestions to provide – change LGTM.

Tip: Mention me again using /dependency <request>.
Powered by Probe AI
Tyk Gateway Dependency Impact Reviewer

Copy link
Contributor

github-actions bot commented Aug 4, 2025

🚀 Performance Snapshot

Effort Perf Risk Hot Paths Benchmarks TL;DR
Low 🟢 Path handling fix for OAS API versions with minimal performance impact
## Performance Impact Analysis

This PR fixes a bug where mock responses weren't executing for non-base versions of OAS APIs by modifying path handling in the VersionCheck middleware. The change adds conditional logic to handle OAS APIs differently from classic APIs, using url.JoinPath() to properly construct request paths. This occurs in the request processing path but involves only lightweight string operations with negligible performance overhead.

## Critical Areas

The changes touch the request processing middleware which is in the hot path, but the modifications are lightweight:

  1. API Lookup: The new code adds a map lookup (v.Gw.apisByID[subVersionID]) which is an O(1) operation.

  2. Path Manipulation: The code uses StripListenPath() and url.JoinPath() which are efficient string operations for typical path lengths.

  3. Error Handling: The addition of error handling for url.JoinPath() adds minimal overhead but improves robustness.

## Optimization Recommendations

The implementation is already well-optimized for the specific use case:

  1. Proper Path Joining: Using url.JoinPath() is a good choice as it correctly handles slash placement, avoiding potential issues with malformed URLs that could occur with simple string concatenation.

  2. Error Handling: The added error handling is appropriate and provides useful context for debugging.

  3. Conditional Logic: The separation of OAS and non-OAS API handling ensures that each type is processed optimally.

## Summary
  • The PR fixes a specific issue with mock responses not executing for non-base OAS API versions
  • The changes involve simple string operations with negligible performance impact
  • The fix properly uses standard library functions for URL path handling, improving correctness
  • The code path is only executed for versioned OAS APIs, limiting any performance impact to those specific requests
  • No suggestions to provide – change LGTM.

Tip: Mention me again using /performance <request>.
Powered by Probe AI
Performance Impact Reviewer Prompt

Copy link
Contributor

github-actions bot commented Aug 4, 2025

Analysis of PR #7254: OAS API Versions Path Handling Fix

Issue Overview

This PR addresses a bug where mock responses were not being executed when calling non-base versions of OAS APIs. The issue was in the path handling logic in the VersionCheck middleware, which didn't correctly construct the path for versioned OAS APIs.

Root Cause Analysis

When a request is made to a non-base version of an API, the VersionCheck middleware is responsible for routing the request to the correct API version handler. For OAS APIs, the mock response functionality relies on the findOperation method to match the request path to an operation in the OAS definition.

The problem was that the middleware was using the same path handling logic for both OAS and non-OAS APIs:

v.Spec.SanitizeProxyPaths(r)

This approach worked fine for classic APIs but didn't correctly handle the path for OAS APIs with version suffixes, causing the findOperation method to fail to find the correct operation, which resulted in mock responses not being executed.

The Fix

The PR adds a conditional check to handle OAS APIs differently:

if v.Spec.IsOAS {
    targetApi, ok := v.Gw.apisByID[subVersionID]

    if !ok {
        return errors.New(string(VersionDoesNotExist)), http.StatusNotFound
    }

    strippedPath := v.Spec.StripListenPath(r.URL.Path)
    newPath, err := url.JoinPath(targetApi.Proxy.ListenPath, strippedPath)
    if err != nil {
        return err, http.StatusInternalServerError
    }
    r.URL.Path = newPath
} else {
    v.Spec.SanitizeProxyPaths(r)
}

This change:

  1. For OAS APIs:
    • Gets the target API definition using the version ID
    • Strips the listen path from the request URL
    • Properly joins the target API's listen path with the stripped path using url.JoinPath()
    • Updates the request URL path with this new path
  2. For non-OAS APIs, continues to use the existing SanitizeProxyPaths method

Why This Fixes the Issue

The fix works because:

  1. It ensures the request path is correctly formatted for the target API version
  2. This allows the findOperation method to correctly match the request to the appropriate operation in the OAS definition
  3. When the operation is correctly identified, the mock response middleware can find and use the mock response configuration

The use of url.JoinPath() is particularly important as it properly handles path joining with correct slash handling, preventing potential issues with malformed URLs.

Technical Impact

This change only affects the internal path handling for versioned OAS APIs and doesn't modify any external interfaces or behaviors. It's a targeted fix that ensures existing functionality (mock responses) works correctly for all API versions.

The implementation is robust, handling error cases and maintaining backward compatibility with non-OAS APIs.


Tip: Mention me again using /connectivity <request>.
Powered by Probe AI
Connectivity Issues Reviewer Prompt for Tyk Gateway

Copy link
Contributor

github-actions bot commented Aug 4, 2025

🛡️ Security Snapshot

Effort Risk Level Tests Compliance TL;DR
Low 🟢 ⚠️ ✔️ Path handling fix for OAS API versions with minimal security impact
## Security Impact Analysis

This PR addresses a bug where mock responses weren't executing for non-base versions of OAS APIs. The issue was in the path handling logic in the VersionCheck middleware, which wasn't correctly constructing the path for versioned OAS APIs. This prevented the findOperation method from matching the request to the appropriate operation in the OAS definition, resulting in mock responses not being executed.

The fix modifies the VersionCheck middleware to handle OAS APIs differently from non-OAS APIs:

  • For OAS APIs: It gets the target API, strips the listen path from the request URL, joins it with the target API's listen path using url.JoinPath(), and updates the request URL path.
  • For non-OAS APIs: It continues to use v.Spec.SanitizeProxyPaths(r).

This change is focused on functionality rather than security, but it does involve URL path manipulation which warrants security consideration.

## Identified Vulnerabilities

No significant vulnerabilities were introduced by this change. The PR actually improves security by:

  1. Using the standard url.JoinPath() function which properly handles path joining with appropriate slashes, preventing potential path traversal issues that could arise from simple string concatenation.

  2. Adding proper error handling for the path joining operation, ensuring that any errors are logged and appropriate HTTP status codes are returned.

  3. Ensuring that the correct handler is invoked for versioned APIs, which prevents potential routing issues.

The code includes appropriate error checking for cases where:

  • The target API isn't found in v.Gw.apisByID[subVersionID]
  • The URL join operation fails with url.JoinPath()
## Security Recommendations

The implementation is secure as it uses standard library functions for path manipulation and includes proper error handling. The use of url.JoinPath() is a good practice as it correctly handles path normalization and prevents path traversal issues.

No additional security measures are needed for this specific change.

## OWASP Compliance

This change doesn't directly impact OWASP Top 10 categories. It's a functional fix for internal path handling that doesn't affect authentication, authorization, or input validation mechanisms.

The use of url.JoinPath() is aligned with OWASP best practices for safe URL handling, as it helps prevent path traversal vulnerabilities (related to A05:2021 - Security Misconfiguration).

## Summary
  • The PR fixes a specific issue with path handling for versioned OAS APIs
  • The implementation uses secure methods for path manipulation with proper error handling
  • The change is minimal and focused on the specific issue without introducing new security concerns
  • No security issues identified – change LGTM.

Tip: Mention me again using /security <request>.
Powered by Probe AI
Security Impact Reviewer Prompt

Copy link
Contributor

github-actions bot commented Aug 4, 2025

Security Analysis of OAS API Versions Path Handling Fix

🛡️ Security Snapshot

Effort Risk Level Tests Compliance TL;DR
Low 🟢 ✔️ Path handling fix for OAS API versions with minimal security impact
## Security Impact Analysis

This PR fixes a bug where mock responses weren't being executed when calling non-base versions of OAS APIs. The issue was in the path handling logic in the VersionCheck middleware, which didn't correctly construct the path for versioned OAS APIs. The fix properly handles path construction by using url.JoinPath() to ensure correct path formatting, which is a more robust approach than the previous string concatenation method.

## Identified Vulnerabilities

No significant vulnerabilities were introduced by this change. The PR actually improves security by:

  1. Using the standard url.JoinPath() function which properly handles path joining with appropriate slashes
  2. Adding proper error handling for the path joining operation
  3. Ensuring that the correct handler is invoked for versioned APIs
## Security Recommendations

The implementation is secure as it uses standard library functions for path manipulation and includes proper error handling. No additional security measures are needed for this specific change.

## OWASP Compliance

This change doesn't directly impact OWASP Top 10 categories. It's a functional fix for internal path handling that doesn't affect authentication, authorization, or input validation mechanisms. The use of url.JoinPath() is a good practice that helps prevent potential path manipulation issues.

## Summary
  • The PR fixes a specific issue with path handling for versioned OAS APIs
  • The implementation uses secure methods for path manipulation with proper error handling
  • The change is minimal and focused on the specific issue without introducing new security concerns
  • No security issues identified – change LGTM.

Tip: Mention me again using /security <request>.
Powered by Probe AI
Security Impact Reviewer Prompt

Copy link
Contributor

github-actions bot commented Aug 4, 2025

Analysis of OAS API Versioning Path Handling Fix

Issue Summary

This PR addresses a bug where mock responses weren't being executed when calling non-base versions of OAS APIs. The issue was in the path handling logic in the VersionCheck middleware.

Root Cause Analysis

The problem occurred in the ProcessRequest method of the VersionCheck middleware. When handling a non-base version of an API, it was using v.Spec.SanitizeProxyPaths(r) to modify the request path. This approach works fine for classic APIs but fails for OAS APIs because:

  1. The OAS router relies on properly formatted paths to find operations
  2. SanitizeProxyPaths doesn't correctly handle the path for versioned OAS APIs
  3. As a result, findOperation() couldn't match the request to the correct operation, causing mock responses to not be executed

Solution Implementation

The PR introduces a conditional approach to path handling based on API type:

if v.Spec.IsOAS {
    targetApi, ok := v.Gw.apisByID[subVersionID]
    if !ok {
        return errors.New(string(VersionDoesNotExist)), http.StatusNotFound
    }
    
    strippedPath := v.Spec.StripListenPath(r.URL.Path)
    newPath, err := url.JoinPath(targetApi.Proxy.ListenPath, strippedPath)
    if err != nil {
        return err, http.StatusInternalServerError
    }
    r.URL.Path = newPath
} else {
    v.Spec.SanitizeProxyPaths(r)
}

This solution:

  1. For OAS APIs:

    • Gets the target API definition using the version ID
    • Strips the listen path from the request URL
    • Properly joins the target API's listen path with the stripped path using url.JoinPath()
    • Sets the request URL path to this new path
  2. For non-OAS APIs:

    • Continues to use the existing SanitizeProxyPaths method

Technical Impact

The fix ensures that when a request is made to a non-base version of an OAS API:

  1. The path is correctly constructed in a format that the OAS router can understand
  2. The findOperation() method can properly match the request to the corresponding operation
  3. The mock response middleware can correctly identify and execute the appropriate mock response

The use of url.JoinPath() is a good choice as it properly handles path joining with correct slash handling, preventing potential issues with malformed URLs that could occur with simple string concatenation.

Conclusion

This is a focused fix that addresses a specific issue with path handling for versioned OAS APIs. The implementation is straightforward and uses standard Go libraries for path handling, making it a safe and effective solution. The change only affects internal path handling and doesn't modify any external interfaces or behaviors, ensuring backward compatibility.


Tip: Mention me again using /connectivity <request>.
Powered by Probe AI
Connectivity Issues Reviewer Prompt for Tyk Gateway

Copy link
Contributor

github-actions bot commented Aug 4, 2025

Analysis of PR #7254: OAS API Versions Path Handling Fix

Issue Overview

This PR addresses a bug where mock responses were not being executed when calling non-base versions of OAS APIs. The issue was in the path handling logic in the VersionCheck middleware.

Root Cause Analysis

When a request is made to a non-base version of an OAS API:

  1. The VersionCheck middleware identifies the version and finds the appropriate handler
  2. Previously, it used v.Spec.SanitizeProxyPaths(r) to modify the request path for all APIs
  3. For OAS APIs, this approach didn't correctly construct the path, causing the FindOperation() method to fail to match the request to the appropriate operation
  4. As a result, mock responses weren't being executed for non-base versions of OAS APIs

The issue occurs because the OAS router needs a properly formatted path to find the correct operation. The mockResponseMiddleware calls m.Spec.findOperation(r), which in turn calls a.OAS.FindOperation(r) for OAS APIs. This method uses the router to find the operation based on the request URL path. If the path is incorrectly formatted, the router can't find the operation, and the mock response isn't executed.

Solution Implementation

The PR modifies the ProcessRequest method in the VersionCheck middleware to handle path construction differently for OAS vs. non-OAS APIs:

if v.Spec.IsOAS {
    targetApi, ok := v.Gw.apisByID[subVersionID]
    if !ok {
        return errors.New(string(VersionDoesNotExist)), http.StatusNotFound
    }
    
    strippedPath := v.Spec.StripListenPath(r.URL.Path)
    newPath, err := url.JoinPath(targetApi.Proxy.ListenPath, strippedPath)
    if err != nil {
        return err, http.StatusInternalServerError
    }
    r.URL.Path = newPath
} else {
    v.Spec.SanitizeProxyPaths(r)
}

This change:

  1. For OAS APIs, it gets the target API definition, strips the listen path from the request URL, and joins it with the target API's listen path using url.JoinPath()
  2. For non-OAS APIs, it continues to use the existing SanitizeProxyPaths method

By correctly formatting the path for OAS APIs, the router can now find the appropriate operation, allowing the mock response middleware to work correctly for non-base versions of OAS APIs.

Technical Impact

This change is focused solely on internal path handling and doesn't affect any external interfaces or behaviors. It doesn't require changes to any downstream repositories (tyk-operator, tyk-charts, portal, tyk-sink) as it doesn't modify any API schemas, protocols, or configurations.

The fix ensures that all OAS API features, particularly mock responses, work correctly for all API versions, improving the consistency and reliability of the API gateway.


Tip: Mention me again using /dependency <request>.
Powered by Probe AI
Tyk Gateway Dependency Impact Reviewer

Copy link

sonarqubecloud bot commented Aug 4, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
20.0% Coverage on New Code (required ≥ 80%)
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@radkrawczyk radkrawczyk changed the title OAS api versions performing fixes Mock response seems to be not executed when calling non-base version of OAS API Aug 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants