NPE in ApiServlet.skip2FAcheckForUser on SAML login when 2FA is disabled (4.22.0.0)
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 78/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- java
- Lĩnh vực
- api, authentication, backend
Hướng nghiên cứu
Bắt đầu trong ApiServlet.java ở dòng 512 và kiểm tra cách skip2FAcheckForUser đọc thuộc tính phiên 2FAuthenticated. Sau đó lần theo SAML2LoginAPIAuthenticatorCmd để so sánh việc thiết lập phiên với luồng đăng nhập cục bộ. Tái hiện với SAML2 được bật và cả hai cài đặt 2FA đều bị tắt; hoàn tất khi yêu cầu API tiếp theo thành công mà không có NullPointerException và người dùng truy cập được dashboard.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
problem
COMPONENT NAME
API, SAML
SUMMARY
Every API request issued after a successful samlSso callback throws a NullPointerException in ApiServlet.skip2FAcheckForUser, because session.getAttribute("2FAuthenticated") returns null and is unboxed directly to boolean. The SAML login flow does not set this session attribute, and the 2FA-disabled global settings are not consulted before the unboxing.
Local username/password login is unaffected — only the SAML path triggers the NPE.
STEPS TO REPRODUCE
- Enable SAML2 plugin and configure an IdP (Keycloak in our case).
- Ensure
enable.user.2fa=falseandmandate.user.2fa=false. - Authorize a CloudStack user for SAML via
authorizeSamlSso. - Click "Login with SSO" → authenticate at IdP → redirected back to
/client/api?command=samlSso. - Browser immediately fires follow-up API call (e.g.
listIdps,login, etc.).
EXPECTED RESULTS
The follow-up API request completes; user lands on the dashboard. A null value for the 2FAuthenticated session attribute should be treated as "2FA not required / not completed" rather than dereferenced as a boolean.
ACTUAL RESULTS
Use cannot login via SAML:
2026-05-17 10:22:39,650 ERROR [c.c.a.ApiServlet] (qtp1047478056-364:[ctx-50e47dca]) (logid:59e6408b) unknown exception writing api response java.lang.NullPointerException: Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "javax.servlet.http.HttpSession.getAttribute(String)" is null
at com.cloud.api.ApiServlet.skip2FAcheckForUser(ApiServlet.java:512)
at com.cloud.api.ApiServlet.processRequestInContext(ApiServlet.java:361)
at com.cloud.api.ApiServlet$1.run(ApiServlet.java:193)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext$1.call(DefaultManagedContext.java:56)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext.callWithContext(DefaultManagedContext.java:103)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext.runWithContext(DefaultManagedContext.java:53)
at com.cloud.api.ApiServlet.processRequest(ApiServlet.java:190)
at com.cloud.api.ApiServlet.doPost(ApiServlet.java:149)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
... (Jetty frames truncated)
Client receives the auth failure / error response, lands back on the login screen.
This is my first ticket here, so be gentle please!
versions
4.22.0 on Debian 13.4 via shapeblue
i cloudstack-common 4.22.0.0-shapeblue0 all A common package which contains files which are shared by several CloudStack packages
ii cloudstack-management 4.22.0.0-shapeblue0 all CloudStack server library
ii cloudstack-usage 4.22.0.0-shapeblue0 all CloudStack usage monitor
And just auto installed java 21 (I know the docs says 17, but I haven't been able to downgrade).
ii default-jdk-headless 2:1.21-76 amd64 Standard Java or Java compatible Development Kit (headless)
ii openjdk-21-jdk-headless:amd64 21.0.11+10-1deb13u2 amd64 OpenJDK Development Kit (JDK) (headless)deb13u2 amd64 OpenJDK Java runtime, using Hotspot JIT (headless)
ii openjdk-21-jre-headless:amd64 21.0.11+10-1
CONFIGURATION
- SAML2 plugin enabled (
saml2.enabled=true) - IdP: Keycloak 26.x, realm
lluw, SAML client with dedicateduidmapper (User Property:email) - 2FA disabled globally:
enable.user.2fa=false,mandate.user.2fa=false - Single management server, MySQL backend
The steps to reproduce the bug
- Enable SAML2 plugin and configure an IdP (Keycloak in our case).
- Ensure
enable.user.2fa=falseandmandate.user.2fa=false. - Authorize a CloudStack user for SAML via
authorizeSamlSso. - Click "Login with SSO" → authenticate at IdP → redirected back to
/client/api?command=samlSso.
5 browser response:
<loginresponse>
<errorcode>531</errorcode>
<errortext>
Your authenticated user is not authorized for SAML Single Sign-On, please contact your administrator
</errortext>
</loginresponse>
LOG response
2026-05-17 10:22:39,650 ERROR [c.c.a.ApiServlet] (qtp1047478056-364:[ctx-50e47dca]) (logid:59e6408b) unknown exception writing api response java.lang.NullPointerException: Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "javax.servlet.http.HttpSession.getAttribute(String)" is null
at com.cloud.api.ApiServlet.skip2FAcheckForUser(ApiServlet.java:512)
at com.cloud.api.ApiServlet.processRequestInContext(ApiServlet.java:361)
at com.cloud.api.ApiServlet$1.run(ApiServlet.java:193)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext$1.call(DefaultManagedContext.java:56)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext.callWithContext(DefaultManagedContext.java:103)
at org.apache.cloudstack.managed.context.impl.DefaultManagedContext.runWithContext(DefaultManagedContext.java:53)
at com.cloud.api.ApiServlet.processRequest(ApiServlet.java:190)
at com.cloud.api.ApiServlet.doPost(ApiServlet.java:149)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:665)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)
... (Jetty frames truncated)
What to do about it?
Expected result
The follow-up API request completes; user lands on the dashboard. A null value for the 2FAuthenticated session attribute should be treated as "2FA not required / not completed" rather than dereferenced as a boolean.
ApiServlet.java:512reads the2FAuthenticatedattribute and unboxes without a null check.- The SAML auth command (
SAML2LoginAPIAuthenticatorCmd) creates the session but does not set2FAuthenticated. - Suggested fix: replace direct unboxing with
Boolean.TRUE.equals(session.getAttribute("2FAuthenticated")), or short-circuit when bothenable.user.2faandmandate.user.2faare false.
- Ngôn ngữ chính
- Java
- Star
- 3.1k
- Fork
- 1.4k
- Merge trung bình
- 7 ngày 5 giờ
- Pull request đã merge (30 ngày)
- 28
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của apache/cloudstack
-
create-kubernetes-binaries-iso.sh builds the ISO without setting a volume ID on EL8 based os's Đang mởbug component:kubernetes
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
apache/cloudstack#14180 ·
-
bug component:projects component:UI
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
apache/cloudstack#14070 · 5 bình luận ·
-
component:backup
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
apache/cloudstack#14013 ·
-
KVM agent fails to connect to Ceph RBD storage pool after upgrading Ceph client to Tentacle 20.2.4 Đang mởbug component:ceph
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
apache/cloudstack#13989 · 3 bình luận ·
-
component:UI
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
apache/cloudstack#13944 · 3 bình luận ·
Tất cả issue của apache/cloudstack
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
infinispan/infinispan#18150 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
-
untriaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
opensearch-project/k-NN#3597 ·
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100