From 9b71bff7d35f0297a61465b37b59b83e2653ae36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20P=C3=A9rez?= Date: Tue, 12 Nov 2024 16:10:24 +0100 Subject: [PATCH 1/2] Updated rules --- .../original/Users_onlineMeetings_v1.0.json | 4 ++-- .../sanitized/Users_onlineMeetings_v1.0.json | 8 +++----- .../Users_onlineMeetings_attendanceReport_v1.0.json | 2 +- .../Users_onlineMeetings_v1.0.json | 8 +++----- .../psoxy/rules/msft/PrebuiltSanitizerRules.java | 10 ++++++++++ .../co/worklytics/psoxy/rules/msft/TeamsTests.java | 8 ++++++-- .../psoxy/rules/msft/Teams_NoUserIds_Tests.java | 5 ++++- 7 files changed, 29 insertions(+), 16 deletions(-) diff --git a/docs/sources/microsoft-365/msft-teams/example-api-responses/original/Users_onlineMeetings_v1.0.json b/docs/sources/microsoft-365/msft-teams/example-api-responses/original/Users_onlineMeetings_v1.0.json index 6b6066420..ccf17953d 100644 --- a/docs/sources/microsoft-365/msft-teams/example-api-responses/original/Users_onlineMeetings_v1.0.json +++ b/docs/sources/microsoft-365/msft-teams/example-api-responses/original/Users_onlineMeetings_v1.0.json @@ -28,7 +28,7 @@ "displayName": "Tyler Stein" } }, - "upn": "upn-value" + "upn": "foo@some-domain.com" } ], "organizer": { @@ -57,4 +57,4 @@ }, "isEntryExitAnnounced": true, "allowedPresenters": "everyone" -} +} \ No newline at end of file diff --git a/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized/Users_onlineMeetings_v1.0.json b/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized/Users_onlineMeetings_v1.0.json index 3f1385852..983d6b2d2 100644 --- a/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized/Users_onlineMeetings_v1.0.json +++ b/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized/Users_onlineMeetings_v1.0.json @@ -26,8 +26,7 @@ "@odata.type":"#microsoft.graph.identity", "id":"112f7296-5ca-bae8-6a692b15d4b8" } - }, - "upn":"upn-value" + } } ], "organizer":{ @@ -37,8 +36,7 @@ "@odata.type":"#microsoft.graph.identity", "id":"5810cedeb-b2c1-e9bd5d53ec96" } - }, - "upn":"upn-value" + } } }, "startDateTime":"2018-05-30T00:30:00Z", @@ -52,4 +50,4 @@ }, "isEntryExitAnnounced":true, "allowedPresenters":"everyone" -} +} \ No newline at end of file diff --git a/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized_no-userIds/Users_onlineMeetings_attendanceReport_v1.0.json b/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized_no-userIds/Users_onlineMeetings_attendanceReport_v1.0.json index 794897e6b..ce0435781 100644 --- a/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized_no-userIds/Users_onlineMeetings_attendanceReport_v1.0.json +++ b/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized_no-userIds/Users_onlineMeetings_attendanceReport_v1.0.json @@ -9,7 +9,7 @@ "totalAttendanceInSeconds":1152, "role":"Presenter", "identity":{ - "id":"dc17674c-81d9-4adb-bfb2-8f6a442e4623", + "id":"{\"scope\":\"azure-ad\",\"hash\":\"MwYK48L-UYMIsFrz1EHA4xX8hwfxJQfyg_L-vtEV1Mc\"}", "tenantId":null }, "attendanceIntervals":[ diff --git a/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized_no-userIds/Users_onlineMeetings_v1.0.json b/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized_no-userIds/Users_onlineMeetings_v1.0.json index 7312202ad..31abf5c6b 100644 --- a/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized_no-userIds/Users_onlineMeetings_v1.0.json +++ b/docs/sources/microsoft-365/msft-teams/example-api-responses/sanitized_no-userIds/Users_onlineMeetings_v1.0.json @@ -21,8 +21,7 @@ "user":{ "id":"{\"scope\":\"azure-ad\",\"hash\":\"KvrBhIhPrAEMwI320CqhyGSfgVmKedObWZ5X380uX04\"}" } - }, - "upn":"upn-value" + } } ], "organizer":{ @@ -30,8 +29,7 @@ "user":{ "id":"{\"scope\":\"azure-ad\",\"hash\":\"OkGYJKhA8lYaD0IJw3YHj8cB9qiSMw6MA_70P99wa3o\"}" } - }, - "upn":"upn-value" + } } }, "startDateTime":"2018-05-30T00:30:00Z", @@ -45,4 +43,4 @@ }, "isEntryExitAnnounced":true, "allowedPresenters":"everyone" -} +} \ No newline at end of file diff --git a/java/core/src/main/java/co/worklytics/psoxy/rules/msft/PrebuiltSanitizerRules.java b/java/core/src/main/java/co/worklytics/psoxy/rules/msft/PrebuiltSanitizerRules.java index 7dfa8ac54..2096841bf 100644 --- a/java/core/src/main/java/co/worklytics/psoxy/rules/msft/PrebuiltSanitizerRules.java +++ b/java/core/src/main/java/co/worklytics/psoxy/rules/msft/PrebuiltSanitizerRules.java @@ -436,6 +436,7 @@ public class PrebuiltSanitizerRules { .jsonPath("$..joinInformation") .jsonPath("$..joinMeetingIdSettings.isPasscodeRequired") .jsonPath("$..joinMeetingIdSettings.passcode") + .jsonPath("$..upn") .build(); static final Transform.Tokenize MS_TEAMS_CALL_ID_TOKENIZATION = Transform.Tokenize.builder() @@ -650,6 +651,9 @@ public class PrebuiltSanitizerRules { .endpoint(Endpoint.builder() .pathRegex(ENTRA_ID_REGEX_USERS_BY_PSEUDO + "/onlineMeetings/[a-zA-Z0-9_-]+/attendanceReports/[a-zA-Z0-9_-]+(\\?.*)?") .transform(MS_TEAMS_TEAMS_DEFAULT_PSEUDONYMIZE) + .transform(Transform.Pseudonymize.builder() + .jsonPath("$..identity.id") + .build()) .transform(PSEUDONYMIZE_USER_ID) .transform(MS_TEAMS_USERS_ONLINE_MEETINGS_REDACT) .transform(REDACT_ODATA_CONTEXT) @@ -659,6 +663,9 @@ public class PrebuiltSanitizerRules { .endpoint(Endpoint.builder() .pathRegex(ENTRA_ID_REGEX_USERS_BY_PSEUDO + "/onlineMeetings/[a-zA-Z0-9_-]+/attendanceReports(\\?.*)?") .transform(MS_TEAMS_TEAMS_DEFAULT_PSEUDONYMIZE) + .transform(Transform.Pseudonymize.builder() + .jsonPath("$..identity.id") + .build()) .transform(PSEUDONYMIZE_USER_ID) .transform(MS_TEAMS_USERS_ONLINE_MEETINGS_REDACT) .transform(REDACT_ODATA_CONTEXT) @@ -669,6 +676,9 @@ public class PrebuiltSanitizerRules { .pathRegex(ENTRA_ID_REGEX_USERS_BY_PSEUDO + "/onlineMeetings(\\?.*)?") .transforms(Arrays.asList(PSEUDONYMIZE_USER_ID, MS_TEAMS_TEAMS_DEFAULT_PSEUDONYMIZE, + Transform.Pseudonymize.builder() + .jsonPath("$..identity.id") + .build(), TOKENIZE_ODATA_LINKS, MS_TEAMS_USERS_ONLINE_MEETINGS_REDACT .toBuilder() diff --git a/java/core/src/test/java/co/worklytics/psoxy/rules/msft/TeamsTests.java b/java/core/src/test/java/co/worklytics/psoxy/rules/msft/TeamsTests.java index bed9253b7..ef9dec589 100644 --- a/java/core/src/test/java/co/worklytics/psoxy/rules/msft/TeamsTests.java +++ b/java/core/src/test/java/co/worklytics/psoxy/rules/msft/TeamsTests.java @@ -424,6 +424,7 @@ public void users_onlineMeetings(String apiVersion) { String userId = "dc17674c-81d9-4adb-bfb2-8f6a442e4622"; String endpoint = "https://graph.microsoft.com/" + apiVersion + "/users/" + userId + "/onlineMeetings"; String jsonResponse = asJson("Users_onlineMeetings_" + apiVersion + ".json"); + assertNotSanitized(jsonResponse, "everyone", "5552478", @@ -437,7 +438,8 @@ public void users_onlineMeetings(String apiVersion) { "https://teams.microsoft.com/l/meetup-join/19%3a:meeting_NTg0NmQ3NTctZDVkZC00YzRhLThmNmEtOGQDdmZDZk@thread.v2/0?context=%7b%22Tid%22%3a%aa67bd4c-8475-432d-bd41-39f255720e0a%22%2c%22Oid%22%3a%22112f7296-5fa4-42ca-bb15d4b8%22%7d", "112f7296-5ca-bae8-6a692b15d4b8", "5810cedeb-b2c1-e9bd5d53ec96", - "joinMeetingId", "1234567890" + "joinMeetingId", + "1234567890" ); String sanitized = sanitize(endpoint, jsonResponse); @@ -451,7 +453,9 @@ public void users_onlineMeetings(String apiVersion) { "macAddress", "reflexiveIPAddress", "relayIPAddress", - "subnet" + "subnet", + "foo@some-domain.com", + "upn-value" ); assertUrlWithSubResourcesBlocked(endpoint); } diff --git a/java/core/src/test/java/co/worklytics/psoxy/rules/msft/Teams_NoUserIds_Tests.java b/java/core/src/test/java/co/worklytics/psoxy/rules/msft/Teams_NoUserIds_Tests.java index a6956288c..0cc7b1488 100644 --- a/java/core/src/test/java/co/worklytics/psoxy/rules/msft/Teams_NoUserIds_Tests.java +++ b/java/core/src/test/java/co/worklytics/psoxy/rules/msft/Teams_NoUserIds_Tests.java @@ -272,6 +272,7 @@ public void users_onlineMeetings() { String jsonResponse = asJson("Users_onlineMeetings_" + "v1.0" + ".json"); String sanitized = sanitize(endpoint, jsonResponse); + assertPseudonymized(sanitized, "112f7296-5ca-bae8-6a692b15d4b8", "5810cedeb-b2c1-e9bd5d53ec96"); assertRedacted(sanitized, "@odata.type", @@ -279,7 +280,9 @@ public void users_onlineMeetings() { "#microsoft.graph.chatInfo", "#microsoft.graph.meetingParticipants", "#microsoft.graph.identitySet", - "#microsoft.graph.identity" + "#microsoft.graph.identity", + "foo@some-domain.com", + "upn-value" ); assertUrlWithSubResourcesBlocked(endpoint); } From 235323bedf55b2519d5221714a8e619f785b2e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20P=C3=A9rez?= Date: Tue, 12 Nov 2024 16:10:30 +0100 Subject: [PATCH 2/2] Updated yamls --- .../microsoft-365/msft-teams/msft-teams.yaml | 3 +++ .../msft-teams/msft-teams_no-userIds.yaml | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/docs/sources/microsoft-365/msft-teams/msft-teams.yaml b/docs/sources/microsoft-365/msft-teams/msft-teams.yaml index 141e09a60..d2123da6d 100644 --- a/docs/sources/microsoft-365/msft-teams/msft-teams.yaml +++ b/docs/sources/microsoft-365/msft-teams/msft-teams.yaml @@ -221,6 +221,7 @@ endpoints: - "$..joinInformation" - "$..joinMeetingIdSettings.isPasscodeRequired" - "$..joinMeetingIdSettings.passcode" + - "$..upn" - pathTemplate: "/v1.0/users/{userId}/onlineMeetings/{meetingId}/attendanceReports" allowedQueryParams: - "$select" @@ -248,6 +249,7 @@ endpoints: - "$..joinInformation" - "$..joinMeetingIdSettings.isPasscodeRequired" - "$..joinMeetingIdSettings.passcode" + - "$..upn" - pathTemplate: "/v1.0/users/{userId}/onlineMeetings/{meetingId}/attendanceReports/{reportId}" allowedQueryParams: - "$select" @@ -275,6 +277,7 @@ endpoints: - "$..joinInformation" - "$..joinMeetingIdSettings.isPasscodeRequired" - "$..joinMeetingIdSettings.passcode" + - "$..upn" - pathRegex: "^/v1.0/users/?[^/]*" allowedQueryParams: - "$top" diff --git a/docs/sources/microsoft-365/msft-teams/msft-teams_no-userIds.yaml b/docs/sources/microsoft-365/msft-teams/msft-teams_no-userIds.yaml index 8f06ff8a3..06f335aac 100644 --- a/docs/sources/microsoft-365/msft-teams/msft-teams_no-userIds.yaml +++ b/docs/sources/microsoft-365/msft-teams/msft-teams_no-userIds.yaml @@ -243,6 +243,10 @@ endpoints: jsonPaths: - "$..emailAddress" encoding: "JSON" + - ! + jsonPaths: + - "$..identity.id" + encoding: "JSON" - ! jsonPaths: - "$..user.id" @@ -255,6 +259,7 @@ endpoints: - "$..joinInformation" - "$..joinMeetingIdSettings.isPasscodeRequired" - "$..joinMeetingIdSettings.passcode" + - "$..upn" - ! jsonPaths: - "$..['@odata.context']" @@ -272,6 +277,10 @@ endpoints: jsonPaths: - "$..emailAddress" encoding: "JSON" + - ! + jsonPaths: + - "$..identity.id" + encoding: "JSON" - ! jsonPaths: - "$..user.id" @@ -284,6 +293,7 @@ endpoints: - "$..joinInformation" - "$..joinMeetingIdSettings.isPasscodeRequired" - "$..joinMeetingIdSettings.passcode" + - "$..upn" - ! jsonPaths: - "$..['@odata.context']" @@ -305,6 +315,10 @@ endpoints: jsonPaths: - "$..emailAddress" encoding: "JSON" + - ! + jsonPaths: + - "$..identity.id" + encoding: "JSON" - ! jsonPaths: - "$.['@odata.nextLink', '@odata.prevLink', 'sessions@odata.nextLink']" @@ -316,6 +330,7 @@ endpoints: - "$..joinInformation" - "$..joinMeetingIdSettings.isPasscodeRequired" - "$..joinMeetingIdSettings.passcode" + - "$..upn" - "$..['@odata.context']" - "$..['@odata.type']" - pathRegex: "^/v1.0/users(/p~[a-zA-Z0-9_-]+?)?[^/]*"