Bug: Dependency Trees overflows the call stack on cyclic SBOM dependency graphs
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 68/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- spring-boot, typescript
- Lĩnh vực
- frontend
Hướng nghiên cứu
Start with spring-boot-admin-server-ui/src/main/frontend/views/instances/sbomdependencytrees/sbomUtils.ts, especially getChildren() and retrieveChildren(), then inspect tree.spec.ts for the existing normalization and rendering tests. Reproduce the minimal cyclic input and add coverage for cycles, self-references, acyclic chains, and shared dependencies. Done means finite cycle-marked output, preserved repeated shared nodes, and working filtering and rerendering without a stack overflow.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Spring Boot Admin Server information
- Version: 4.1.3
- Spring Boot version: 4.1.1
Client information
- Spring Boot versions: 3.5.10
- SBOM format: CycloneDX JSON
Description
The SBOM Dependency Trees normalizer recursively expands dependency references without tracking ancestors. When the input graph contains a reachable cycle, expansion never terminates normally and throws RangeError: Maximum call stack size exceeded.
This was reproduced in isolation against the executable normalization logic from 4.1.3 and master inspected on 2026-10-03. A self-reference also reproduces the failure. A full SBA browser integration test was not run for this report.
Regardless of how a producer generated a cyclic graph, the viewer should handle it without exhausting the JavaScript call stack. Removing BOM/POM components from the input should not be necessary to prevent the viewer from failing.
Minimal input
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"metadata": {
"component": { "type": "application", "bom-ref": "app", "name": "demo-app", "version": "1.0.0" }
},
"components": [
{ "type": "library", "bom-ref": "a", "name": "library-a", "version": "1.0.0" },
{ "type": "library", "bom-ref": "b", "name": "library-b", "version": "1.0.0" }
],
"dependencies": [
{ "ref": "app", "dependsOn": ["a"] },
{ "ref": "a", "dependsOn": ["b"] },
{ "ref": "b", "dependsOn": ["a"] }
]
}
Reproduction and actual behavior
Pass this document's dependencies to normalizeData() in sbomUtils.ts. It throws Maximum call stack size exceeded while expanding app -> a -> b -> a -> ....
For UI reproduction, serve the document through the monitored application's SBOM endpoint, or mock instance.fetchSbom() in tree.spec.ts, and open Dependency Trees. Normalization fails before a finite tree can be passed to the D3 renderer.
Expected behavior
Render a finite representation of the reachable graph. For example, show a terminal node/reference marked as a cycle when a dependency points back to an ancestor:
app
└── a
└── b
└── a [cycle; not expanded again]
An explicit controlled diagnostic would also be preferable to a stack overflow, but retaining the rest of the graph would make the view more useful.
Cause and proposed fix
getChildren() and retrieveChildren() in 4.1.3 call each other without an ancestor/recursion-path guard.
- Index dependency records by their exact
ref. - Track references on the current traversal path, including the root.
- If the next reference is already on that path, create a terminal cycle/reference node rather than expanding it again.
- Use full references for identity; normalized labels can collide.
- Do not use a global visited set to suppress all repeated nodes. A shared dependency in two independent branches is not a cycle and should remain visible under both parents.
- Keep the resulting object structure acyclic for D3, and preserve the original SBOM graph.
- Consider an explicit stack or controlled expansion limits for very deep graphs / large numbers of repeated paths; cycle detection alone does not bound all work.
Regression cases should include a two-node cycle, self-reference, an edge back to the application root, an ordinary acyclic chain, and a diamond (app -> a,b, a -> c, b -> c) where c is shown in both branches. Filtering and rerendering should still work with cycle markers.
Related reports
There is a separate root-selection defect where dependencies[0] is treated as the root. Correcting it can make previously hidden cycles reachable. [#5745]
#5157 fixes an alert displayed during SBOM loading; it does not add cycle detection to dependency traversal.
I would be happy to contribute a PR targeting master, covering both root selection and cycle-safe traversal if preferred.
- Ngôn ngữ chính
- Java
- Star
- 12.9k
- Fork
- 3.2k
- Merge trung bình
- 23 giờ 31 phút
- Pull request đã merge (30 ngày)
- 72
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của codecentric/spring-boot-admin
-
Bug: Dependency Trees uses dependencies[0] as root instead of metadata.component.bom-refCó thể đã có người làm @faystmax đã nhận 5 ngày trước. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 68/100
codecentric/spring-boot-admin#5745 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
codecentric/spring-boot-admin#5743 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Bug: Filtering rules are not synchronized between SBA nodesCó thể đã có người làm @SteKoe đã nhận 7 ngày trước. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 45/100
codecentric/spring-boot-admin#5721 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Bug: Multiple notifications from multiple instancesCó thể đã có người làm @YadavKshitiz đã nhận 9 ngày trước. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
codecentric/spring-boot-admin#5716 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 52/100
codecentric/spring-boot-admin#5597 · 6 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của codecentric/spring-boot-admin
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
-
C21 publishes `reactivemongo/core/SSL` as Java 23 bytecode — TLS connections fail on any JDK < 23Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
ReactiveMongo/ReactiveMongo#1520 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
liquid-java/liquidjava#373 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
ga4gh/phenopacket-schema#465 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
NationalSecurityAgency/ghidra#9748 ·
Maintainer thường phản hồi trong vòng 1 ngày