From be1169ffcb7fee0c8f4fa7d70c10ed4f98f488e5 Mon Sep 17 00:00:00 2001 From: Pete Markowsky Date: Mon, 11 Sep 2023 14:28:23 -0400 Subject: [PATCH] Make Transitive Allowlisting Work with Signing ID rules (#1177) * Make transitive allowlisting work with Signing ID rules * Update rules.md to include SIGNINGID rules for transitive allowlisting. --- Source/santad/SNTExecutionControllerTest.mm | 57 +++++++++++++++++++++ Source/santad/SNTPolicyProcessor.m | 10 ++++ docs/concepts/rules.md | 5 +- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/Source/santad/SNTExecutionControllerTest.mm b/Source/santad/SNTExecutionControllerTest.mm index 354b12ca6..4a960051e 100644 --- a/Source/santad/SNTExecutionControllerTest.mm +++ b/Source/santad/SNTExecutionControllerTest.mm @@ -464,6 +464,63 @@ - (void)testBinaryAllowTransitiveRuleDisabled { [self checkMetricCounters:kAllowTransitive expected:@0]; } +- (void)testSigningIDAllowCompilerRule { + OCMStub([self.mockFileInfo isMachO]).andReturn(YES); + OCMStub([self.mockFileInfo SHA256]).andReturn(@"a"); + + OCMStub([self.mockConfigurator enableTransitiveRules]).andReturn(YES); + + NSString *signingID = [NSString stringWithFormat:@"%s:%s", kExampleTeamID, kExampleSigningID]; + + SNTRule *rule = [[SNTRule alloc] init]; + rule.state = SNTRuleStateAllowCompiler; + rule.type = SNTRuleTypeSigningID; + + OCMStub([self.mockRuleDatabase ruleForBinarySHA256:@"a" + signingID:signingID + certificateSHA256:nil + teamID:@(kExampleTeamID)]) + .andReturn(rule); + + [self validateExecEvent:SNTActionRespondAllowCompiler + messageSetup:^(es_message_t *msg) { + msg->event.exec.target->team_id = MakeESStringToken(kExampleTeamID); + msg->event.exec.target->signing_id = MakeESStringToken(kExampleSigningID); + }]; + + [self checkMetricCounters:kAllowCompiler expected:@1]; +} + +- (void)testSigningIDAllowTransitiveRuleDisabled { + OCMStub([self.mockFileInfo isMachO]).andReturn(YES); + OCMStub([self.mockFileInfo SHA256]).andReturn(@"a"); + OCMStub([self.mockConfigurator clientMode]).andReturn(SNTClientModeLockdown); + OCMStub([self.mockConfigurator enableTransitiveRules]).andReturn(NO); + + SNTRule *rule = [[SNTRule alloc] init]; + rule.state = SNTRuleStateAllowTransitive; + rule.type = SNTRuleTypeSigningID; + + NSString *signingID = [NSString stringWithFormat:@"%s:%s", kExampleTeamID, kExampleSigningID]; + + OCMStub([self.mockRuleDatabase ruleForBinarySHA256:@"a" + signingID:signingID + certificateSHA256:nil + teamID:nil]) + .andReturn(rule); + + OCMExpect([self.mockEventDatabase addStoredEvent:OCMOCK_ANY]); + + [self validateExecEvent:SNTActionRespondDeny + messageSetup:^(es_message_t *msg) { + msg->event.exec.target->signing_id = MakeESStringToken("com.google.santa.test"); + }]; + + OCMVerifyAllWithDelay(self.mockEventDatabase, 1); + [self checkMetricCounters:kAllowSigningID expected:@0]; + [self checkMetricCounters:kAllowTransitive expected:@0]; +} + - (void)testThatPlatformBinaryCachedDecisionsSetModeCorrectly { OCMStub([self.mockFileInfo isMachO]).andReturn(YES); OCMStub([self.mockFileInfo SHA256]).andReturn(@"a"); diff --git a/Source/santad/SNTPolicyProcessor.m b/Source/santad/SNTPolicyProcessor.m index 845286e60..aa46eac65 100644 --- a/Source/santad/SNTPolicyProcessor.m +++ b/Source/santad/SNTPolicyProcessor.m @@ -140,6 +140,16 @@ - (nonnull SNTCachedDecision *)decisionForFileInfo:(nonnull SNTFileInfo *)fileIn case SNTRuleTypeSigningID: switch (rule.state) { case SNTRuleStateAllow: cd.decision = SNTEventStateAllowSigningID; return cd; + case SNTRuleStateAllowCompiler: + // If transitive rules are enabled, then SNTRuleStateAllowListCompiler rules + // become SNTEventStateAllowCompiler decisions. Otherwise we treat the rule as if + // it were SNTRuleStateAllowSigningID. + if ([self.configurator enableTransitiveRules]) { + cd.decision = SNTEventStateAllowCompiler; + } else { + cd.decision = SNTEventStateAllowSigningID; + } + return cd; case SNTRuleStateSilentBlock: cd.silentBlock = YES; // intentional fallthrough diff --git a/docs/concepts/rules.md b/docs/concepts/rules.md index 83c98ccdb..9a726deb9 100644 --- a/docs/concepts/rules.md +++ b/docs/concepts/rules.md @@ -89,10 +89,7 @@ powerful rule with broader reach than individual certificate rules. The transitive allowlist capability of Santa can automatically allowlist any files that are created by a set of specified binaries. A typical use-case is allowing any binaries compiled with XCode on developer machines to execute, as it would be slow and impractical to use other rule types to permit these. -To begin using transitive allowlisting, `EnableTransitiveRules` should be set to true and Compiler rules (rules with the policy `ALLOWLIST_COMPILER`) should be added to indicate the binaries which will be writing the new files to be allowlisted. Only rules of type 'BINARY' are allowed for compiler rules. Santa will create and manage Transitive rules in its database automatically, they cannot be created directly. - - - +To begin using transitive allowlisting, `EnableTransitiveRules` should be set to true and Compiler rules (rules with the policy `ALLOWLIST_COMPILER`) should be added to indicate the binaries which will be writing the new files to be allowlisted. Only rules of type `BINARY` and `SIGNINGID` are allowed for compiler rules. Santa will create and manage Transitive rules in its database automatically, they cannot be created directly. ## Rule Evaluation