Reject inactive SAML users before ACS group updates (#2677)

* Harden path traversal checks for Windows root-relative escapes.

Reject POSIX/Windows absolute paths in is_path_traversal and require post-join containment at icon, network-config, and archive extraction sinks.

Co-authored-by: Cursor <[email protected]>

* Restrict network security config names to a basename.

CodeQL flagged the manifest-derived join; reduce the resource name first so path construction cannot escape xml_dir.

Co-authored-by: Cursor <[email protected]>

* Use os.path.basename for CodeQL-recognized path sanitization.

Path.name did not clear py/path-injection taint; basename plus existing containment checks keep the network-config read inside xml_dir.

Co-authored-by: Cursor <[email protected]>

* Drop CodeQL-appeasement basename sanitization from network config reads.

is_safe_path after join already rejects traversal, absolute, and Windows root-relative names; CodeQL py/path-injection is a false positive.

Co-authored-by: Cursor <[email protected]>

* Bound androguard ZIP member decompression

Use the configured per-file ZIP limit for apkinspector reads and cap
actual raw-DEFLATE output. Keep decompression-limit failures out of the
tampered-entry fallback so malicious compressed data cannot be treated
as stored bytes.

Co-authored-by: Cursor <[email protected]>

* Reject inactive SAML users before ACS group updates.

Existing accounts mapped from a valid IdP assertion should not have groups replaced or be passed to login() when is_active is False.

Co-authored-by: Cursor <[email protected]>

* Return the ACS error page for inactive users instead of raising Exception.

Co-authored-by: Cursor <[email protected]>

---------

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Ajin Abraham
2026-09-20 16:34:04 -07:00
committed by GitHub
co-authored by Cursor
parent a04a42e768
commit 70ecabcafb
+7
View File
@@ -183,6 +183,13 @@ def saml_acs(request):
role = get_user_role(attributes['role'])
if User.objects.filter(username=email).exists():
user = User.objects.get(username=email)
# Reject before group mutation or login(), matching
# AuthenticationForm / ModelBackend inactive handling.
if not user.is_active:
return print_n_send_error_response(
request,
'This account is inactive.',
False)
user.groups.clear()
user.groups.add(Group.objects.get(name=role))
login(request, user)