From 800cfa71d063734e7b8ad7e9eae1fc5dabe0e928 Mon Sep 17 00:00:00 2001 From: Felipe Zipitria Date: Tue, 13 Oct 2026 09:19:08 -0300 Subject: [PATCH] fix: accept SSN area numbers up to 899 in @verifySSN The operator rejected any area number of 740 or above. Since the Social Security Administration randomised assignment in June 2011 every area number except 000, 666 and 900-999 is in use, so valid numbers in the 740-899 range were never detected. The check is now area == 0, area == 666 or area >= 900. Same change as the 3.x one in owasp-modsecurity/ModSecurity#3669. Fixes #2970 Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0181jBv5JdNQviwDzfnkf1Gy --- apache2/re_operators.c | 5 +- tests/regression/misc/50-verifyssn.t | 70 ++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 tests/regression/misc/50-verifyssn.t diff --git a/apache2/re_operators.c b/apache2/re_operators.c index d496a8a12..8f612355c 100644 --- a/apache2/re_operators.c +++ b/apache2/re_operators.c @@ -3621,8 +3621,9 @@ static int ssn_verify(modsec_rec *msr, const char *ssnumber, int len) { if (area == 0 || serial == 0 || grp == 0) goto invalid; - /* More tests */ - if (area >= 740 || area == 666) + /* Since the 2011 randomisation every area number is assigned except + * 000, 666 and 900-999 (#2970). */ + if (area == 666 || area >= 900) goto invalid; return 1; diff --git a/tests/regression/misc/50-verifyssn.t b/tests/regression/misc/50-verifyssn.t new file mode 100644 index 000000000..32ebed0d4 --- /dev/null +++ b/tests/regression/misc/50-verifyssn.t @@ -0,0 +1,70 @@ +### @verifySSN area number ranges (#2970) + +{ + type => "misc", + comment => '@verifySSN area 574 (pre-2011 range)', + conf => q( + SecRuleEngine On + SecRule ARGS "@verifySSN \\d{3}-?\\d{2}-?\\d{4}" "id:500970,phase:1,deny,status:403,capture" + ), + match_log => { + error => [ qr/Access denied with code 403 \(phase 1\)/, 1 ], + }, + match_response => { + status => qr/^403$/, + }, + request => new HTTP::Request( + GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?ssn=574-57-8065", + ), +}, +{ + type => "misc", + comment => '@verifySSN area 800 is valid since the 2011 randomisation', + conf => q( + SecRuleEngine On + SecRule ARGS "@verifySSN \\d{3}-?\\d{2}-?\\d{4}" "id:500970,phase:1,deny,status:403,capture" + ), + match_log => { + error => [ qr/Access denied with code 403 \(phase 1\)/, 1 ], + }, + match_response => { + status => qr/^403$/, + }, + request => new HTTP::Request( + GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?ssn=800-57-8065", + ), +}, +{ + type => "misc", + comment => '@verifySSN area 900 is never assigned', + conf => q( + SecRuleEngine On + SecRule ARGS "@verifySSN \\d{3}-?\\d{2}-?\\d{4}" "id:500970,phase:1,deny,status:403,capture" + ), + match_log => { + -error => [ qr/Access denied/, 1 ], + }, + match_response => { + status => qr/^200$/, + }, + request => new HTTP::Request( + GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?ssn=900-57-8065", + ), +}, +{ + type => "misc", + comment => '@verifySSN area 666 is never assigned', + conf => q( + SecRuleEngine On + SecRule ARGS "@verifySSN \\d{3}-?\\d{2}-?\\d{4}" "id:500970,phase:1,deny,status:403,capture" + ), + match_log => { + -error => [ qr/Access denied/, 1 ], + }, + match_response => { + status => qr/^200$/, + }, + request => new HTTP::Request( + GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?ssn=666-57-8065", + ), +},