|
7 | 7 |
|
8 | 8 | import { assert } from "chai"; |
9 | 9 |
|
10 | | -import { serializeContent, urlJoin } from "../../../src/GraphRequestUtil"; |
| 10 | +import { serializeContent, urlJoin, isGraphURL, isCustomHost } from "../../../src/GraphRequestUtil"; |
11 | 11 |
|
12 | 12 | describe("GraphRequestUtil.ts", () => { |
13 | 13 | describe("urlJoin", () => { |
@@ -77,4 +77,49 @@ describe("GraphRequestUtil.ts", () => { |
77 | 77 | assert.equal(serializeContent(val), "null"); |
78 | 78 | }); |
79 | 79 | }); |
| 80 | + |
| 81 | + describe("isGraphURL - host confusion regression", () => { |
| 82 | + it("Should accept valid Graph URLs", () => { |
| 83 | + assert.isTrue(isGraphURL("https://graph.microsoft.com/v1.0/me")); |
| 84 | + assert.isTrue(isGraphURL("https://graph.microsoft.com:443/v1.0/me")); |
| 85 | + assert.isTrue(isGraphURL("https://graph.microsoft.us/v1.0/me")); |
| 86 | + assert.isTrue(isGraphURL("https://dod-graph.microsoft.us/v1.0/me")); |
| 87 | + assert.isTrue(isGraphURL("https://graph.microsoft.de/v1.0/me")); |
| 88 | + assert.isTrue(isGraphURL("https://microsoftgraph.chinacloudapi.cn/v1.0/me")); |
| 89 | + assert.isTrue(isGraphURL("https://canary.graph.microsoft.com/v1.0/me")); |
| 90 | + }); |
| 91 | + |
| 92 | + it("Should reject URLs with userinfo (host confusion attack)", () => { |
| 93 | + assert.isFalse(isGraphURL("https://graph.microsoft.com:443@attacker.example/v1.0/me")); |
| 94 | + assert.isFalse(isGraphURL("https://graph.microsoft.com:8080@attacker.example/v1.0/me")); |
| 95 | + assert.isFalse(isGraphURL("https://graph.microsoft.com@attacker.example/v1.0/me")); |
| 96 | + assert.isFalse(isGraphURL("https://user:pass@graph.microsoft.com/v1.0/me")); |
| 97 | + }); |
| 98 | + |
| 99 | + it("Should reject non-Graph hosts", () => { |
| 100 | + assert.isFalse(isGraphURL("https://attacker.example/v1.0/me")); |
| 101 | + assert.isFalse(isGraphURL("https://graph.microsoft.com.evil.example/v1.0/me")); |
| 102 | + }); |
| 103 | + |
| 104 | + it("Should reject non-HTTPS URLs", () => { |
| 105 | + assert.isFalse(isGraphURL("http://graph.microsoft.com/v1.0/me")); |
| 106 | + }); |
| 107 | + |
| 108 | + it("Should reject malformed URLs", () => { |
| 109 | + assert.isFalse(isGraphURL("not-a-url")); |
| 110 | + assert.isFalse(isGraphURL("")); |
| 111 | + }); |
| 112 | + }); |
| 113 | + |
| 114 | + describe("isCustomHost - host confusion regression", () => { |
| 115 | + const customHosts = new Set<string>(["api.example.com"]); |
| 116 | + |
| 117 | + it("Should accept valid custom host URLs", () => { |
| 118 | + assert.isTrue(isCustomHost("https://api.example.com/v1.0/data", customHosts)); |
| 119 | + }); |
| 120 | + |
| 121 | + it("Should reject URLs with userinfo targeting custom hosts", () => { |
| 122 | + assert.isFalse(isCustomHost("https://api.example.com:443@attacker.example/v1.0/data", customHosts)); |
| 123 | + }); |
| 124 | + }); |
80 | 125 | }); |
0 commit comments