mirror of
https://github.com/usnistgov/macos_security.git
synced 2026-02-03 14:03:24 +00:00
pwpolicy_special_character_enforce: enforce more than 1 special character. #70
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @DavidRvrsR3 on GitHub.
Originally assigned to: @robertgendler on GitHub.
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
@brodjieski commented on GitHub:
Sure thing!
It looks like the check is actually out of sync with what CIS has in their benchmark. We can look to update the check itself to match what CIS has, which looks to be similar to what you are suggesting.
We do have plans to update this, and all of the password policy rules to better reflect guidance from NIST. Hopefully we can include that in the next release. I'll keep this issue opened to track these updates. Look for a commit with changes that can be tested in the coming days.
Thanks again!
@brodjieski commented on GitHub:
Hello!
This rule has an organization defined value (ODV), which has a recommended value of 1 (same for CIS level 2). If you tailor this ODV value to 2, or 3, or whatever you prefer, then regenerate the documents and scripts, it should be updated to reflect that value.
However, if you run the compliance scripts without tailoring the ODV, but then deploy a configuration that contains a different value than expected, the script will produce a finding.
@DavidRvrsR3 commented on GitHub:
Thanks for explaining the ODV system and how it's meant to be tailored at the organization level. I get that it’s flexible by design, but I think there’s a good opportunity here to make things easier for everyone.
Right now, the script flags stricter policies like {2,} or {3,} as non-compliant, even though they meet or exceed the standards. If we tweak the script to recognize any value greater than 0, it would save a lot of time and hassle—both during audits and in day-to-day compliance checks.
This way, admins wouldn’t need to manually adjust the script with every update or deal with false positives, and the system would still be just as flexible for those who want to customize it. I’m happy to help with testing or tweaking the logic if needed. Let me know what you think!
@DavidRvrsR3 commented on GitHub:
result_value=$( [[ $(/usr/bin/pwpolicy -getaccountpolicies 2>/dev/null | /usr/bin/tail +2 | /usr/bin/xmllint --xpath '//*[contains(text(),"policyAttributePassword matches")]/text()' - 2>/dev/null | grep -oE '\{[0-9]+,' | tr -d '{,' | tr -d '\n') -gt 0 ]] && echo "true" || echo "false" )if you require a single line solution
@robertgendler commented on GitHub:
/usr/bin/pwpolicy -getaccountpolicies 2>/dev/null | /usr/bin/tail -n +2 | /usr/bin/xmllint --xpath "//string[contains(text(), \"policyAttributePassword matches '(.*[^a-zA-Z0-9].*){\")]" - 2>/dev/null | /usr/bin/awk -F"{|}" '{if ($2 >= $ODV) {print "true"} else {print "false"}}'1 Line. You'll need to directly replace ODV with the value you want to test due to the replacement in Awk. You can't just do ODV=1 in a shell.
@robertgendler commented on GitHub:
Closing cause this is completed.