Summary
Rule: pwpolicy_special_character_enforce is giving false positive if you enforce more than 1 special character.
So if you push a password policy requiring 2 or more special characters a failure will be audited.
So to reproduce sent a Configuration Profile with com.apple.mobiledevice.passwordpolicy minComplexChars 2,3 or 4 will fail
Operating System version
15.2 Beta (24C5079e), it is a small oversight in the script, so will impact all macOS Versions and all architectures.
Intel or Apple Silicon
tested on Silicon but will be the case for all.
What is the current bug behavior?
We are enforcing more than 1 special character so the line that is being checked is slightly different as the check script is looking for but still should qualify as compliant according to the documentation. It is looking for:
'\''(.*[^a-zA-Z0-9].*){1,}'\''")])'
but it will find
'\''(.*[^a-zA-Z0-9].*){3,}'\''")])'.
It than flags pwpolicy_special_character_enforce as failed.
What is the expected correct behavior?
pwpolicy_special_character_enforce should pass if a value above 0 is given
Possible fixes
#####----- Rule: pwpolicy_special_character_enforce -----#####
## Addresses the following NIST 800-53 controls:
# * IA-5(1)
rule_arch=""
if [[ "$arch" == "$rule_arch" ]] || [[ -z "$rule_arch" ]]; then
special_chars=$(/usr/bin/pwpolicy -getaccountpolicies 2> /dev/null | \
/usr/bin/tail +2 | \
/usr/bin/xmllint --xpath '//*[contains(text(),"policyAttributePassword matches")]/text()' - | \
grep -oE "\(.*\[\^a-zA-Z0-9\].*\)\{[0-9]+," | \
grep -oE '\{[0-9]+,' | \
tr -d '{,')
if [[ $special_chars -ge 1 ]]; then
result_value="true"
else
result_value="false"
fi
# expected result {'string': 'true'}
# check to see if rule is exempt
unset exempt
unset exempt_reason
exempt=$(/usr/bin/osascript -l JavaScript << EOS 2>/dev/null
ObjC.unwrap($.NSUserDefaults.alloc.initWithSuiteName('org.cis_lvl2.audit').objectForKey('pwpolicy_special_character_enforce'))["exempt"]
EOS
)
exempt_reason=$(/usr/bin/osascript -l JavaScript << EOS 2>/dev/null
ObjC.unwrap($.NSUserDefaults.alloc.initWithSuiteName('org.cis_lvl2.audit').objectForKey('pwpolicy_special_character_enforce'))["exempt_reason"]
EOS
)
customref="$(echo "pwpolicy_special_character_enforce" | rev | cut -d ' ' -f 2- | rev)"
customref="$(echo "$customref" | tr " " ",")"
if [[ $result_value == "true" ]]; then
logmessage "pwpolicy_special_character_enforce passed (Result: $result_value, Expected: \"{'string': 'true'}\")"
/usr/bin/defaults write "$audit_plist" pwpolicy_special_character_enforce -dict-add finding -bool NO
if [[ ! "$customref" == "pwpolicy_special_character_enforce" ]]; then
/usr/bin/defaults write "$audit_plist" pwpolicy_special_character_enforce -dict-add reference -string "$customref"
fi
/usr/bin/logger "mSCP: cis_lvl2 - pwpolicy_special_character_enforce passed (Result: $result_value, Expected: "{'string': 'true'}")"
else
if [[ ! $exempt == "1" ]] || [[ -z $exempt ]];then
logmessage "pwpolicy_special_character_enforce failed (Result: $result_value, Expected: \"{'string': 'true'}\")"
/usr/bin/defaults write "$audit_plist" pwpolicy_special_character_enforce -dict-add finding -bool YES
if [[ ! "$customref" == "pwpolicy_special_character_enforce" ]]; then
/usr/bin/defaults write "$audit_plist" pwpolicy_special_character_enforce -dict-add reference -string "$customref"
fi
/usr/bin/logger "mSCP: cis_lvl2 - pwpolicy_special_character_enforce failed (Result: $result_value, Expected: "{'string': 'true'}")"
else
logmessage "pwpolicy_special_character_enforce failed (Result: $result_value, Expected: \"{'string': 'true'}\") - Exemption Allowed (Reason: \"$exempt_reason\")"
/usr/bin/defaults write "$audit_plist" pwpolicy_special_character_enforce -dict-add finding -bool YES
if [[ ! "$customref" == "pwpolicy_special_character_enforce" ]]; then
/usr/bin/defaults write "$audit_plist" pwpolicy_special_character_enforce -dict-add reference -string "$customref"
fi
/usr/bin/logger "mSCP: cis_lvl2 - pwpolicy_special_character_enforce failed (Result: $result_value, Expected: "{'string': 'true'}") - Exemption Allowed (Reason: "$exempt_reason")"
/bin/sleep 1
fi
fi
else
logmessage "pwpolicy_special_character_enforce does not apply to this architecture"
/usr/bin/defaults write "$audit_plist" pwpolicy_special_character_enforce -dict-add finding -bool NO
fi
Summary
Rule: pwpolicy_special_character_enforce is giving false positive if you enforce more than 1 special character.
So if you push a password policy requiring 2 or more special characters a failure will be audited.
So to reproduce sent a Configuration Profile with com.apple.mobiledevice.passwordpolicy minComplexChars 2,3 or 4 will fail
Operating System version
15.2 Beta (24C5079e), it is a small oversight in the script, so will impact all macOS Versions and all architectures.
Intel or Apple Silicon
tested on Silicon but will be the case for all.
What is the current bug behavior?
We are enforcing more than 1 special character so the line that is being checked is slightly different as the check script is looking for but still should qualify as compliant according to the documentation. It is looking for:
'\''(.*[^a-zA-Z0-9].*){1,}'\''")])'but it will find
'\''(.*[^a-zA-Z0-9].*){3,}'\''")])'.It than flags pwpolicy_special_character_enforce as failed.
What is the expected correct behavior?
pwpolicy_special_character_enforce should pass if a value above 0 is given
Possible fixes