microsoft / microsoft/multiclouddb-sdk-for-java-samples
π Deep Repository Review: 5 Critical, 7 High, 18 Medium findings
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 0
- Forks
- 2
- PR merge metrics
- No merged PRs in 30d
Description
π Deep Review: microsoft/multiclouddb-sdk-for-java-samples
Date: 2026-04-27
Repo: https://github.com/microsoft/multiclouddb-sdk-for-java-samples
Reviewer: Copilot deep-review pipeline (3 parallel agents)
π Aggregate Finding Counts
| Severity | TODO App | Risk Platform | Security | Total |
|---|---|---|---|---|
| π΄ CRITICAL | 3 | 2 | 0 | 5 |
| π HIGH | 3 | 4 | 0 | 7 |
| π‘ MEDIUM | 8 | 5 | 5 | 18 |
| π’ LOW | 7 | 3 | 5 | 15 |
| Total | 21 | 14 | 10 | 45 |
π¨ CRITICAL Findings
C1. TodoApp: No client shutdown β resource leak
File: TodoApp.java
The MulticloudDbClient is created but never closed. No shutdown hook exists. Underlying Cosmos/Dynamo/Spanner connections leak on Ctrl+C.
Fix: Add Runtime.getRuntime().addShutdownHook() that calls client.close().
C2. TodoApp: No request body size limit β DoS
File: TodoApp.java
MAPPER.readTree(exchange.getRequestBody()) reads entire stream with no size cap. Attacker can OOM the JVM.
Fix: Add body length check before parsing.
C3. TodoApp: Path traversal in static file handler
File: TodoApp.java β handleStatic()
URL path passed directly to getResourceAsStream(). Request like GET /static/../logback.xml could serve arbitrary classpath resources. getResourceAsStream does NOT normalize .. segments.
Fix: Normalize path, reject .. segments, whitelist extensions.
C4. Risk Platform: No Authentication or Authorization
File: RiskPlatformApp.java
Entire REST API is unauthenticated. Any client can read/write any tenant's data via ?tenant=<any-id>. Zero auth, zero tenant ownership checks. Developers copying this pattern into production would have a critical vulnerability.
Fix: Add prominent WARNING in code/README about missing auth.
C5. Risk Platform: XSS in Dashboard HTML
File: index.html (riskplatform)
User data rendered via template literals into innerHTML without sanitization. Portfolio name, alert message, symbol all injected raw. A portfolio named <img src=x onerror=alert(1)> executes JS.
Fix: Use textContent or sanitize helper before innerHTML insertion.
π HIGH Findings
H1. TodoApp: XSS via onclick handlers in index.html
escHtml() escapes <>&" but NOT single quotes. IDs inside single-quoted JS onclick attrs can break out. Stored XSS risk.
H2. TodoApp: CORS Access-Control-Allow-Origin: *
Wildcarding all origins on data-mutating API. Should warn this is not production-safe.
H3. TodoApp: ConfigLoader silently swallows IOException
If config file is malformed, returns empty config silently. Only treat null stream as optional.
H4. Risk Platform: deletePosition Missing portfolio Query Param
Client JS sends DELETE /api/positions/{id}?tenant=X but server requires &portfolio=Y. Every position delete returns 400.
H5. Risk Platform: deleteAlert Missing portfolio Query Param
Same bug as H4. Every alert delete returns 400.
H6. Risk Platform: N+1 Query Pattern in Portfolio Listing
For N portfolios, executes N+1 queries (1 list + N position lookups). Causes latency and RU cost at scale.
H7. Risk Platform: Dashboard Fires 5+ Serial Queries
5 serial DB queries per dashboard load. No parallelism, no caching.
π‘ MEDIUM Findings (18 total)
TODO App (8)
- M1: Duplicates
ConfigLoaderlogic instead of reusing it - M2: Spanner config has inconsistent database naming (
testdbvstodoapp) - M3:
listTodos()fetches only first page, no pagination - M4:
PortableCrudQuerySamplepagination demo is incomplete (printshasMorebut never fetches next page) - M5: Error responses leak internal exception messages and SDK categories
- M6:
pom.xmlURL points to personal fork (allenkim0129) not microsoft org - M7: Cleanup scripts reference Risk Platform databases, no TODO app cleanup exists
- M8:
HttpExchangenot always closed on error paths
Risk Platform (5)
- M9: No pagination β all queries read only first page (200 items max)
- M10: Hardcoded tenant database names in
ResourceProvisionerβ no dynamic onboarding - M11: Query parameters not URL-decoded
- M12: Cosmos emulator key in properties should have comment explaining it is well-known
- M13: CORS allows all origins
Security Cross-Cutting (5)
- M14: HTTP servers bind to
0.0.0.0(all interfaces) notlocalhost - M15: CORS
Access-Control-Allow-Origin: *on both apps - M16: No request body size limits β
readAllBytes()with no cap - M17: Error messages expose internal SDK details
- M18:
MulticloudDbExceptioncategory leaked to client responses
π’ LOW Findings (15 total, selected)
- No
Content-Security-Policyheader on HTML pages - TodoApp
server.setExecutor(null)uses single-thread executor - No input validation on document IDs (length, characters)
- No rate limiting on either HTTP server
- No authentication (expected for demo)
- Naive query parameter parsing without URL decoding
- Accessibility gaps in TODO UI (no ARIA roles, no screen reader support)
- Inconsistent system property names (
todo.configvsmulticlouddb.config) - Risk Platform main file at 32KB/600 lines (acceptable for sample)
- Dead code: unused
pad()method inRiskPlatformApp
β What's Done Well
| Area | Assessment |
|---|---|
| Credential Management | Emulator-only keys committed; cloud values gitignored with .template files |
| SDK Usage | Correct use of MulticloudDbClient, Key, ResourceAddress, QueryRequest |
| Multi-Tenant Model | Database-per-tenant via ResourceAddress β strongest isolation |
| Partition Key Design | Positions grouped by portfolio β optimal for access patterns |
| Provider Portability | Same code runs on Cosmos, DynamoDB, Spanner via config swap |
| Schema Provisioning | provisionSchema() correctly used for multi-DB setup |
| Portable Queries | Good demonstration of expression DSL with parameters |
| Capabilities API | Displayed in both TODO and Risk Platform dashboards |
| Cleanup Scripts | Named targets, preview before delete, interactive confirmation |
| Dependencies | All recent versions, no known critical CVEs |
SDK Feature Demonstration Coverage
| Feature | Demonstrated | Quality |
|---|---|---|
| CRUD (create/read/update/delete/upsert) | β Yes | Good |
| Portable query DSL with parameters | β Yes | Good |
| Native query escape hatch | β Yes | Good |
provisionSchema() |
β Yes | Good |
| Capabilities API | β Yes | Good |
ResourceAddress per-tenant routing |
β Yes | Excellent |
QueryRequest.partitionKey() scoping |
β Yes | Good |
| Provider switching via config | β Yes | Excellent |
| Pagination with continuation tokens | β No | Printed but never followed |
| Error handling (category-specific) | β οΈ Partial | Caught but not branched on |
| Retry/backoff patterns | β No | Not demonstrated |
| Batch operations | β No | Not demonstrated |
| TTL / metadata | β No | Not demonstrated |
| ORDER BY / limit | β No | Not demonstrated |
π― Top Priority Actions
| # | Action |
|---|---|
| 1 | Fix path traversal in TodoApp static handler |
| 2 | Fix XSS in both dashboards β sanitize user data |
| 3 | Add shutdown hook to close MulticloudDbClient |
| 4 | Fix broken delete buttons in Risk Platform (add &portfolio= param) |
| 5 | Add request body size limits to both servers |
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up β it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
This issue aggregates findings across TodoApp.java, RiskPlatformApp.java, riskplatform/index.html, and related configuration and client files. Start by splitting one finding into a separate issue, then inspect the named file and its relevant request or rendering path. Done should be defined per finding with a focused change and a test or reproducible check, rather than attempting all 45 items together.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- html, java, javascript
- Domain
- backend, security, web-dev
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100