-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Merging to release-5.10: [TT-14814] fix bundle loading issue (#7436) #7452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merging to release-5.10: [TT-14814] fix bundle loading issue (#7436) #7452
Conversation
🔍 Code Analysis ResultsThis PR addresses a security vulnerability where the Tyk gateway could load custom middleware bundles from the disk without re-verifying their manifest or signature. The core of the change is a refactoring of the bundle loading mechanism to use an abstracted filesystem ( Files Changed Analysis
Architecture & Impact AssessmentWhat this PR accomplishesThis PR resolves the security vulnerability described in ticket TT-14814 by ensuring that all custom middleware bundles are signature-checked before being loaded by the gateway. This check now applies universally, whether the bundle is being freshly downloaded or is already present on the local filesystem. It also improves the overall code quality by decoupling the bundle loading logic from the physical filesystem, enhancing its testability. Key technical changes introduced
Affected system componentsThe primary component affected is the Gateway's Custom Middleware Bundle Loader. This change directly impacts the loading and validation process for any API that utilizes custom middleware bundles (e.g., Python, gRPC plugins). The change is triggered during the gateway's startup and on API reloads. Component Interaction DiagramThe following diagram illustrates how the flowchart LR
subgraph API Loading
direction LR
loadBundle(spec) -- "calls with os.Fs" --> loadBundleWithFs(spec, fs)
end
subgraph Bundle Operations
direction LR
loadBundleWithFs -- "injects" --> FS["afero.Fs"]
loadBundleWithFs -- "uses" --> FetchBundle
loadBundleWithFs -- "uses" --> saveBundle
loadBundleWithFs -- "uses" --> loadBundleManifest
end
subgraph Filesystem Interactions
direction LR
FetchBundle -- "reads from" --> FS
saveBundle -- "writes to" --> FS
loadBundleManifest -- "reads from" --> FS
loadBundleManifest -- "calls" --> Verify
Verify -- "reads from" --> FS
end
Scope Discovery & Context ExpansionThe changes are well-contained within the The architectural shift to an abstracted filesystem is a significant improvement that not only fixes the immediate security issue but also enhances the long-term maintainability and security posture of this critical component by making it easier to write comprehensive tests. Metadata
Powered by Visor from Probelabs Last updated: 2025-10-14T15:49:53.353Z | Triggered by: synchronize | Commit: 7ef0378 |
🔍 Code Analysis Results✅ Security Check PassedNo security issues found – changes LGTM. Performance Issues (1)
Quality Issues (2)
✅ Style Check PassedNo style issues found – changes LGTM. ✅ Dependency Check PassedNo dependency issues found – changes LGTM. ✅ Connectivity Check PassedNo connectivity issues found – changes LGTM. Powered by Visor from Probelabs Last updated: 2025-10-14T15:49:54.993Z | Triggered by: synchronize | Commit: 7ef0378 |
<details open> <summary><a href="https://tyktech.atlassian.net/browse/TT-14814" title="TT-14814" target="_blank">TT-14814</a></summary> <br /> <table> <tr> <th>Summary</th> <td>[Security] Gateway Uses Bundles with Invalid/non-existent Manifests</td> </tr> <tr> <th>Type</th> <td> <img alt="Bug" src="https://tyktech.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10303?size=medium" /> Bug </td> </tr> <tr> <th>Status</th> <td>In Dev</td> </tr> <tr> <th>Points</th> <td>N/A</td> </tr> <tr> <th>Labels</th> <td><a href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%202025_r5_candidate%20ORDER%20BY%20created%20DESC" title="2025_r5_candidate">2025_r5_candidate</a>, <a href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20AI-Complexity-High%20ORDER%20BY%20created%20DESC" title="AI-Complexity-High">AI-Complexity-High</a>, <a href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20AI-Priority-High%20ORDER%20BY%20created%20DESC" title="AI-Priority-High">AI-Priority-High</a>, <a href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20customer_bug%20ORDER%20BY%20created%20DESC" title="customer_bug">customer_bug</a>, <a href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20jira_escalated%20ORDER%20BY%20created%20DESC" title="jira_escalated">jira_escalated</a>, <a href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20security%20ORDER%20BY%20created%20DESC" title="security">security</a>, <a href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20stability_theme_security%20ORDER%20BY%20created%20DESC" title="stability_theme_security">stability_theme_security</a></td> </tr> </table> </details> <!-- do not remove this marker as it will break jira-lint's functionality. added_by_jira_lint --> --- This PR fixes an issue while loading bundles. ___ Bug fix, Tests ___ - Switch bundle I/O to afero filesystem - Enforce manifest verification on existing bundles - Add in-memory FS tests for manifest checks - Refactor loading to injectable FS ___ ```mermaid flowchart LR GW["Gateway.loadBundleWithFs"] -- "fetch via" --> Fetch["FetchBundle(afero.Fs)"] GW -- "save via" --> Save["saveBundle(afero.Fs)"] GW -- "validate via" --> Manifest["loadBundleManifest(afero.Fs)"] Manifest -- "if signed" --> Verify["Bundle.Verify(afero.Fs)"] Save -- "ZipBundleSaver uses" --> FS["afero.Fs"] Fetch -- "file:// getter uses" --> FS ``` <details> <summary><h3> File Walkthrough</h3></summary> <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table> <tr> <td> <details> <summary><strong>coprocess_bundle.go</strong><dd><code>Bundle I/O refactor with FS injection and stricter verification</code></dd></summary> <hr> gateway/coprocess_bundle.go <ul><li>Inject afero.Fs across bundle operations<br> <li> Verify manifest even for existing bundles<br> <li> Add loadBundleWithFs and refactor helpers<br> <li> Update ZipBundleSaver and FileBundleGetter to use FS</ul> </details> </td> <td><a href="https://github.com/TykTechnologies/tyk/pull/7436/files#diff-72df0cbfd3765a5d0bff62196c11008596608a21a53dbb9c65bfc6f008dbfa29">+48/-31</a> </td> </tr> </table></td></tr><tr><td><strong>Tests</strong></td><td><table> <tr> <td> <details> <summary><strong>coprocess_bundle_test.go</strong><dd><code>Tests for FS-backed loading and manifest validation</code> </dd></summary> <hr> gateway/coprocess_bundle_test.go <ul><li>Add tests using in-memory afero FS<br> <li> Factor PEM creation helper<br> <li> Test mandatory manifest verification<br> <li> Update Verify calls to pass FS</ul> </details> </td> <td><a href="https://github.com/TykTechnologies/tyk/pull/7436/files#diff-7fded1570c90f7be73d562f3ebcbb32fe4d50548dc5e959d8ecadddef13941fa">+101/-25</a></td> </tr> </table></td></tr></tr></tbody></table> </details> ___ (cherry picked from commit a990971)
6873728
to
6b4dc10
Compare
PR Code Suggestions ✨Explore these optional code suggestions:
|
API Changes --- prev.txt 2025-10-14 15:29:11.868302923 +0000
+++ current.txt 2025-10-14 15:29:02.334233274 +0000
@@ -9432,8 +9432,8 @@
func (b *Bundle) AddToSpec()
AddToSpec attaches the custom middleware settings to an API definition.
-func (b *Bundle) Verify() error
- Verify performs a signature verification on the bundle file.
+func (b *Bundle) Verify(bundleFs afero.Fs) error
+ Verify performs signature verification on the bundle file.
type BundleGetter interface {
Get() ([]byte, error)
@@ -9843,6 +9843,7 @@
func (k *ExternalOAuthMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Request, _ interface{}) (error, int)
type FileBundleGetter struct {
+ Fs afero.Fs
URL string
InsecureSkipVerify bool
}
@@ -9952,7 +9953,7 @@
EventHandlerByName is a convenience function to get event handler instances
from an API Definition
-func (gw *Gateway) FetchBundle(spec *APISpec) (Bundle, error)
+func (gw *Gateway) FetchBundle(bundleFs afero.Fs, spec *APISpec) (Bundle, error)
FetchBundle will fetch a given bundle, using the right BundleGetter.
The first argument is the bundle name, the base bundle URL will be used as
prefix.
@@ -12257,10 +12258,12 @@
func (e *XPathExtractor) ExtractAndCheck(r *http.Request) (SessionID string, returnOverrides ReturnOverrides)
-type ZipBundleSaver struct{}
+type ZipBundleSaver struct {
+ Fs afero.Fs
+}
ZipBundleSaver is a BundleSaver for ZIP files.
-func (ZipBundleSaver) Save(bundle *Bundle, bundlePath string, spec *APISpec) error
+func (z *ZipBundleSaver) Save(bundle *Bundle, bundlePath string, _ *APISpec) error
Save implements the main method of the BundleSaver interface. It makes use
of archive/zip.
|
…0ddc7512e3c26b081f3d4d6
|
User description
TT-14814 fix bundle loading issue (#7436)
User description
TT-14814
This PR fixes an issue while loading bundles.
PR Type
Bug fix, Tests
Description
Switch bundle I/O to afero filesystem
Enforce manifest verification on existing bundles
Add in-memory FS tests for manifest checks
Refactor loading to injectable FS
Diagram Walkthrough
File Walkthrough
coprocess_bundle.go
Bundle I/O refactor with FS injection and stricter verification
gateway/coprocess_bundle.go
coprocess_bundle_test.go
Tests for FS-backed loading and manifest validation
gateway/coprocess_bundle_test.go
PR Type
Bug fix, Tests
Description
Inject afero.Fs for bundle I/O
Enforce manifest verification always
Refactor saver/getter to FS-backed
Add in-memory FS verification tests
Diagram Walkthrough
File Walkthrough
coprocess_bundle.go
FS-backed bundle I/O and stricter verification
gateway/coprocess_bundle.go
coprocess_bundle_test.go
Tests for FS-backed loading and validation
gateway/coprocess_bundle_test.go