elunez/eladmin · error · BadRequestException
非法的 Bean,请重新输入!
Error message
非法的 Bean,请重新输入!
What it means
QuartzJobController.checkBean rejects a quartz job whose beanName is not present in SpringBeanHolder.getAllServiceBeanName() — i.e. not a Spring bean defined with @Service. This is a deliberate security hardening (comments in the code explain it): arbitrary bean names previously allowed invoking beans like jdbcTemplate via reflection and executing arbitrary SQL. Only beans in the service-bean whitelist can be scheduled.
Source
Thrown at eladmin-system/src/main/java/me/zhengjie/modules/quartz/rest/QuartzJobController.java:138
public ResponseEntity<Object> executionQuartzJob(@PathVariable Long id){
quartzJobService.execution(quartzJobService.findById(id));
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
@Log("删除定时任务")
@ApiOperation("删除定时任务")
@DeleteMapping
@PreAuthorize("@el.check('timing:del')")
public ResponseEntity<Object> deleteQuartzJob(@RequestBody Set<Long> ids){
quartzJobService.delete(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
private void checkBean(String beanName){
// 避免调用攻击者可以从SpringContextHolder获得控制jdbcTemplate类
// 并使用getDeclaredMethod调用jdbcTemplate的queryForMap函数,执行任意sql命令。
if(!SpringBeanHolder.getAllServiceBeanName().contains(beanName)){
throw new BadRequestException("非法的 Bean,请重新输入!");
}
}
}
View on GitHub (pinned to 55fbf70595)
Solutions
- Ensure the target class is annotated @Service (not @Component/@Configuration) so it lands in the service-bean name list.
- Use the exact bean name (default: class simple name with lowercase first letter, e.g. 'visitorTask') in the job form.
- Confirm the class's package is under the @SpringBootApplication scan path or explicitly scanned.
Example fix
// before
@Component("myTask")
public class MyTask { public void run(){...} }
// after
@Service("myTask")
public class MyTask { public void run(){...} } Defensive patterns
Strategy: validation
Validate before calling
// before submitting, confirm the bean is a registered service bean
Set<String> names = SpringBeanHolder.getAllServiceBeanName();
if (!names.contains(job.getBeanName())) {
throw new IllegalArgumentException("beanName 必须是 @Service bean: " + job.getBeanName());
} Type guard
boolean isServiceBean(String name) {
return name != null && SpringBeanHolder.getAllServiceBeanName().contains(name);
} Prevention
- Annotate every schedulable task class with @Service and reference it by that exact bean name.
- Offer the valid bean names in the job form dropdown (from /api/quartz/getServiceBeanName-like endpoint) instead of free text.
- Never relax this check — it blocks RCE via beans like jdbcTemplate.
When it happens
Trigger: Creating or updating a quartz job with a beanName that is not a registered @Service bean: typo in the name, a bean annotated @Component instead of @Service, a bean in a package not scanned, or an attempted attack using bean names like 'jdbcTemplate'.
Common situations: Writing a custom scheduled task class and forgetting @Service; renaming the bean class without updating the job config; plugin/task classes in a module excluded from component scanning; penetration-test payloads targeting the old unvalidated behavior.
Related errors
- 非法的应用名称,请勿包含[; | &]等特殊字符
- A new quartzJob cannot already have an ID
- cron表达式格式错误
- 子任务中不能添加当前任务ID
- 文件超出规定大小:{maxSize}MB
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/47c529df4815537e.
Report an issue: GitHub.