Skip to content

Commit

Permalink
Add policy group 5 in Classroom baseline stating that only verified t…
Browse files Browse the repository at this point in the history
…eachers can create classes (#325)

* Added Policy Group 19

* Added Class Creation Policy

* Added Class Creation Policy

* Added drift rules

* Apply suggestions from code review

Co-authored-by: Alden Hilton <106177711+adhilto@users.noreply.github.com>

* Revert gmail baseline

* Reverse gmail drift rules

* Fixed issue

* Fixed Issues

* Updated TOC

* Update baselines/Google Classroom Minimum Viable Secure Configuration Baseline v0.2.md

Co-authored-by: Alden Hilton <106177711+adhilto@users.noreply.github.com>

* Implemented 5.1 in rego

* Update drift-rules/GWS Drift Monitoring Rules - Classroom.csv

Co-authored-by: Alden Hilton <106177711+adhilto@users.noreply.github.com>

* Added TTP Mappings

---------

Co-authored-by: Alden Hilton <106177711+adhilto@users.noreply.github.com>
Co-authored-by: Alden Hilton <adhilto@sandia.gov>
  • Loading branch information
3 people committed Jul 3, 2024
1 parent ac2f940 commit 29a3dae
Show file tree
Hide file tree
Showing 4 changed files with 294 additions and 1 deletion.
188 changes: 188 additions & 0 deletions Testing/RegoTests/classroom/classroom05_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package classroom
import future.keywords

#
# GWS.CLASSROOM.5.1v0.2
#--

test_ClassroomCreation_Correct_V1 if {
# Test only teachers can unenroll students when there's only one event
PolicyId := "GWS.CLASSROOM.5.1v0.2"
Output := tests with input as {
"classroom_logs": {"items": [
{
"id": {"time": "2022-12-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name":"SETTING_NAME",
"value": "TeacherPermissionsSettingProto who_can_create_class"},
{"name": "NEW_VALUE", "value": "3"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups."
}

test_ClassroomCreation_Correct_V2 if {
# Test when there's multiple events, with the chronological latest
# correct but not last in json list
PolicyId := "GWS.CLASSROOM.5.1v0.2"
Output := tests with input as {
"classroom_logs": {"items": [
{
"id": {"time": "2022-12-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name":"SETTING_NAME",
"value": "TeacherPermissionsSettingProto who_can_create_class"},
{"name": "NEW_VALUE", "value": "3"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
]
}]
},
{
"id": {"time": "2021-12-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name":"SETTING_NAME",
"value": "TeacherPermissionsSettingProto who_can_create_class"},
{"name": "NEW_VALUE", "value": "2"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups."
}

# No tests for multiple OUs, inheritance, groups, etc as this setting can't be controlled at the OU or group level

test_ClassroomCreation_Incorrect_V1 if {
# Test when there's only one event and it's wrong
PolicyId := "GWS.CLASSROOM.5.1v0.2"
Output := tests with input as {
"classroom_logs": {"items": [
{
"id": {"time": "2022-12-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name":"SETTING_NAME",
"value": "TeacherPermissionsSettingProto who_can_create_class"},
{"name": "NEW_VALUE", "value": "1"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
not RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == concat("", [
"The following OUs are non-compliant:<ul><li>Test Top-Level OU: ",
"Who can create classes is set to anyone in this domain</li></ul>"
])
}

test_ClassroomCreation_Incorrect_V2 if {
# Test when there's multiple events, with the chronological latest
# incorrect but not last in json list
PolicyId := "GWS.CLASSROOM.5.1v0.2"
Output := tests with input as {
"classroom_logs": {"items": [
{
"id": {"time": "2022-12-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name":"SETTING_NAME",
"value": "TeacherPermissionsSettingProto who_can_create_class"},
{"name": "NEW_VALUE", "value": "2"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
]
}]
},
{
"id": {"time": "2021-12-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name":"SETTING_NAME",
"value": "TeacherPermissionsSettingProto who_can_create_class"},
{"name": "NEW_VALUE", "value": "3"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
not RuleOutput[0].RequirementMet
not RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == concat("", [
"The following OUs are non-compliant:<ul><li>Test Top-Level OU: ",
"Who can create classes is set to all pending and verified teachers</li></ul>"
])
}


test_ClassroomCreation_Incorrect_V3 if {
# Test when there no applicable event
PolicyId := "GWS.CLASSROOM.5.1v0.2"
Output := tests with input as {
"classroom_logs": {"items": [
{
"id": {"time": "2022-12-20T00:02:28.672Z"},
"events": [{
"parameters": [
{"name":"SETTING_NAME",
"value": "something else"},
{"name": "NEW_VALUE", "value": "false"},
{"name": "ORG_UNIT_NAME", "value": "Test Top-Level OU"},
]
}]
}
]},
"tenant_info": {
"topLevelOU": "Test Top-Level OU"
}
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
count(RuleOutput) == 1
not RuleOutput[0].RequirementMet
RuleOutput[0].NoSuchEvent
RuleOutput[0].ReportDetails == concat("", [
"No relevant event in the current logs for the top-level OU, Test Top-Level OU. ",
"While we are unable to determine the state from the logs, the default setting ",
"is non-compliant; manual check recommended."
])
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This baseline is based on Google documentation available at [Google Workspace Ad
- [Classroom API](#2-classroom-api)
- [Roster Import](#3-roster-import)
- [Student Unenrollment](#4-student-unenrollment)
- [Class Creation](#5-class-creation)

Settings can be assigned to certain users within Google Workspace through organizational units, configuration groups, or individually. Before changing a setting, the user can select the organizational unit, configuration group, or individual users to which they want to apply changes.

Expand Down Expand Up @@ -181,3 +182,42 @@ To configure the settings for Student Unenrollment:
3. Select **Student unenrollment**.
4. Select **Teachers Only**.
5. Select **Save**.

## 5. Class Creation

The first time users sign in to Classroom, they self-identify as either a student or teacher. Users who identify as teachers will be marked as a pending teacher until an administrator verifies them. Google Classroom allows administrators to restrict class creation to only verified teachers.

### Policy

#### GWS.CLASSROOM.5.1v0.2
Class creation SHALL be restricted to verified teachers only.

- _Rationale:_ Allowing pending teachers to create classes potentially allows students to impersonate teachers and exploit the trusted relationship between teacher and student, e.g., to phish sensitive information from the students. Restricting class creation to verified teachers reduces this risk.
- _Last modified:_ June 21, 2024

- MITRE ATT&CK TTP Mapping
- [T1656: Impersonation](https://attack.mitre.org/techniques/T1656/)
- [T534: Internal Spearphishing](https://attack.mitre.org/techniques/T1534/)
- [T1598: Phishing for Information](https://attack.mitre.org/techniques/T1598/)
- [T1598:002: Phishing for Information: Spearphishing Attachment](https://attack.mitre.org/techniques/T1598/002/)
- [T1598:003: Phishing for Information: Spearphishing Link](https://attack.mitre.org/techniques/T1598/003/)
- [T1598:004: Phishing for Information: Spearphishing Voice](https://attack.mitre.org/techniques/T1598/004/)

### Resources

- [Verify teachers and set permissions](https://support.google.com/edu/classroom/answer/6071551?hl=en)

### Prerequisites

- None

### Implementation
To configure the settings for Class Creation:

#### GWS.CLASSROOM.5.1v0.2 Instructions
1. Sign in to the [Google Admin Console](https://admin.google.com).
2. Select **Apps** -\> **Additional Google Service** -\> **Classroom**.
3. Select **General Settings**.
4. Select **Teacher permissions**.
5. Select **Verified teachers only** for **Who can create classes?**
5. Select **Save**.
3 changes: 2 additions & 1 deletion drift-rules/GWS Drift Monitoring Rules - Classroom.csv
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ GWS.CLASSROOM.1.1v0.2,Who can join classes in your domain SHALL be set to Users
GWS.CLASSROOM.1.2v0.2,Which classes can users in your domain join SHALL be set to Classes in your domain only,Admin Log Events,Change Application Setting,ClassMembershipSettingProto which_classes_can_users_join,1,rules/00gjdgxs0hj2dit,JK 10-20-23 @ 13:23
GWS.CLASSROOM.2.1v0.2,Classroom API SHALL be disabled for users,Admin Log Events,Change Application Setting,ApiDataAccessSettingProto api_access_enabled,false,rules/00gjdgxs3aafl8p,JK 10-20-23 @ 13:31
GWS.CLASSROOM.3.1v0.2,Roster import with Clever SHOULD be turned off,Admin Log Events,Change Application Setting,RosterImportSettingsProto sis_integrator,SIS_INTEGRATOR_NONE,rules/00gjdgxs25t0l8g,JK 10-20-23 @ 13:42
GWS.CLASSROOM.4.1v0.2,Who can unenroll students from classes SHALL be set to Teachers Only,Admin Log Events,Change Application Setting,StudentUnenrollmentSettingsProto who_can_unenroll_students,ONLY_TEACHERS_CAN_UNENROLL_STUDENTS,rules/00gjdgxs44rgreu,JK 10-20-23 @ 13:50
GWS.CLASSROOM.4.1v0.2,Who can unenroll students from classes SHALL be set to Teachers Only,Admin Log Events,Change Application Setting,StudentUnenrollmentSettingsProto who_can_unenroll_students,ONLY_TEACHERS_CAN_UNENROLL_STUDENTS,rules/00gjdgxs44rgreu,JK 10-20-23 @ 13:50
GWS.CLASSROOM.5.1v0.2,Class creation SHALL be restricted to verified teachers only.,Admin Log Events,Change Application Setting,TeacherPermissionsSettingProto who_can_create_class,rules/00gjdgxs4cfwumr,JK 06-21-24 @ 11:58
64 changes: 64 additions & 0 deletions rego/Classroom.rego
Original file line number Diff line number Diff line change
Expand Up @@ -311,3 +311,67 @@ if {
Status := count(NonCompliantOUs4_1) == 0
}
#--


###################
# GWS.CLASSROOM.5 #
###################

#
# Baseline GWS.CLASSROOM.5.1v0.2
#--
GetFriendlyValue5_1(Value) := "anyone in this domain" if {
Value == "1"
} else := "all pending and verified teachers" if {
Value == "2"
} else := Value

NonCompliantOUs5_1 contains {
"Name": OU,
"Value": concat(" ", [
"Who can create classes is set to",
GetFriendlyValue5_1(LastEvent.NewValue)
])
} if {
some OU in utils.OUsWithEvents
Events := utils.FilterEventsOU(LogEvents, "TeacherPermissionsSettingProto who_can_create_class", OU)
# Ignore OUs without any events. We're already asserting that the
# top-level OU has at least one event; for all other OUs we assume
# they inherit from a parent OU if they have no events.
count(Events) > 0
LastEvent := utils.GetLastEvent(Events)
LastEvent.NewValue != "3"
LastEvent.NewValue != "DELETE_APPLICATION_SETTING"
}

tests contains {
"PolicyId": "GWS.CLASSROOM.5.1v0.2",
"Criticality": "Shall",
"ReportDetails": utils.NoSuchEventDetails(DefaultSafe, utils.TopLevelOU),
"ActualValue": "No relevant event in the current logs",
"RequirementMet": DefaultSafe,
"NoSuchEvent": true
}
if {
DefaultSafe := false
SettingName := "TeacherPermissionsSettingProto who_can_create_class"
Events := utils.FilterEventsOU(LogEvents, SettingName, utils.TopLevelOU)
count(Events) == 0
}

tests contains {
"PolicyId": "GWS.CLASSROOM.5.1v0.2",
"Criticality": "Shall",
"ReportDetails": utils.ReportDetails(NonCompliantOUs5_1, []),
"ActualValue": {"NonCompliantOUs": NonCompliantOUs5_1},
"RequirementMet": Status,
"NoSuchEvent": false
}
if {
SettingName := "TeacherPermissionsSettingProto who_can_create_class"
Events := utils.FilterEventsOU(LogEvents, SettingName, utils.TopLevelOU)
count(Events) > 0
Status := count(NonCompliantOUs5_1) == 0
}
#--

0 comments on commit 29a3dae

Please sign in to comment.