Vulnerability Analysis
Some sensitive endpoints in AiragModelController are missing @RequiresPermissions authorization annotations. A normal authenticated user can access the model configuration export endpoint /airag/airagModel/exportXls and may export the credential field in the AiragModel entity. This field is used to store credentials for AI providers, such as API keys for OpenAI, DeepSeek, and others.
In addition, the /airag/airagModel/test endpoint is also missing permission protection. An attacker can craft a model configuration request body to trigger server-side calls to LLM, embedding, or image model APIs, causing unauthorized usage of model capabilities and quota consumption. It can also be used to verify whether a leaked API key is valid.
File: AiragModelController.java
@Tag(name = "AiRag model configuration")
@RestController
@RequestMapping("/airag/airagModel")
@Slf4j
public class AiragModelController extends JeecgController<AiragModel, IAiragModelService> {
@Autowired
private IAiragModelService airagModelService;
@Autowired
AIChatHandler aiChatHandler;
The controller base path is:
Key Source 1: Protected add/edit endpoints for comparison
In the same controller, the add and edit endpoints do have permission annotations:
@PostMapping(value = "/add")
@RequiresPermissions("airag:model:add")
public Result<String> add(@RequestBody AiragModel airagModel) {
AssertUtils.assertNotEmpty("模型名称不能为空", airagModel.getName());
AssertUtils.assertNotEmpty("模型类型不能为空", airagModel.getModelType());
AssertUtils.assertNotEmpty("基础模型不能为空", airagModel.getModelName());
if(oConvertUtils.isObjectEmpty(airagModel.getActivateFlag())){
airagModel.setActivateFlag(0);
}
airagModelService.save(airagModel);
return Result.OK("添加成功!");
}
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
@RequiresPermissions("airag:model:edit")
public Result<String> edit(@RequestBody AiragModel airagModel) {
airagModelService.updateById(airagModel);
return Result.OK("编辑成功!");
}
This shows that the developer already treats model configuration as an administrative function that should be access-controlled. However, the later list, queryById, exportXls, and test endpoints are missing the same level of permission protection, creating an access control gap.
Key Source 2: Unauthorized export of model configuration
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, AiragModel airagModel) {
return super.exportXls(request, airagModel, AiragModel.class, "AiRag模型配置");
}
Reproduction
After obtaining a low-privilege user token, you can directly use the included poc.py to export the API key.
You can also test it with Burp:
The exported table looks like this:
The API key can be obtained.
Recommended Fixes
- Add permission annotations to sensitive endpoints:
@RequiresPermissions("airag:model:list")
@GetMapping(value = "/list")
@RequiresPermissions("airag:model:queryById")
@GetMapping(value = "/queryById")
@RequiresPermissions("airag:model:exportXls")
@RequestMapping(value = "/exportXls")
@RequiresPermissions("airag:model:test")
@PostMapping(value = "/test")
- Prevent the
credential field from appearing in normal responses and export files:
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String credential;
or:
@JsonIgnore private String credential;
- Use a dedicated VO for Excel export instead of exporting the entity class
AiragModel.class directly.
Vulnerability Analysis
Some sensitive endpoints in
AiragModelControllerare missing@RequiresPermissionsauthorization annotations. A normal authenticated user can access the model configuration export endpoint/airag/airagModel/exportXlsand may export thecredentialfield in theAiragModelentity. This field is used to store credentials for AI providers, such as API keys forOpenAI,DeepSeek, and others.In addition, the
/airag/airagModel/testendpoint is also missing permission protection. An attacker can craft a model configuration request body to trigger server-side calls to LLM, embedding, or image model APIs, causing unauthorized usage of model capabilities and quota consumption. It can also be used to verify whether a leaked API key is valid.File: AiragModelController.java
The controller base path is:
Key Source 1: Protected add/edit endpoints for comparison
In the same controller, the add and edit endpoints do have permission annotations:
This shows that the developer already treats model configuration as an administrative function that should be access-controlled. However, the later
list,queryById,exportXls, andtestendpoints are missing the same level of permission protection, creating an access control gap.Key Source 2: Unauthorized export of model configuration
Reproduction
After obtaining a low-privilege user token, you can directly use the included
poc.pyto export the API key.You can also test it with Burp:
The exported table looks like this:
The API key can be obtained.
Recommended Fixes
credentialfield from appearing in normal responses and export files:or:
AiragModel.classdirectly.