0

Now there is a need to add a bean to the spring container during program operation. This bean is the configuration class of spring AOP. How to make the configuration take effect.

I know that the @Component annotation needs to be configured under normal circumstances, but I need to configure it during runtime instead of scanning the configuration at startup

At first, I wrote this

    @Aspect
    public class ParamAspect {
    
        private static String result;
    
        @Pointcut("execution(public * com.example.aop.*.*(String))")
        public void doOperation() {...}
    
    
        @Before("doOperation()")
        public void before(JoinPoint joinPoint) throws Exception {...}

    
        @AfterReturning(returning = "object", pointcut = "doOperation()")
        public void doAfterReturning(Object object) {...}
    }

registry the bean

        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) beanFactoryField.get(ctx);

        BeanDefinitionRegistry beanDefReg = beanFactory;
        BeanDefinitionBuilder beanDefBuilder = BeanDefinitionBuilder.genericBeanDefinition(ParamAspect.class);
        BeanDefinition beanDef = beanDefBuilder.getBeanDefinition();
        if (!beanDefReg.containsBeanDefinition("theBean")) {
            beanDefReg.registerBeanDefinition("theBean", beanDef);
        }

But I find it doesn't work Then I try the method provided online

public class Config {
    private Advisor config(){
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution(public * com.example.aop.*.*(String))");
        return   new DefaultPointcutAdvisor(pointcut, new MyMethodInterceptor());
    }
}

public class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
    ...
    }
}

and change class

        BeanDefinitionBuilder beanDefBuilder = BeanDefinitionBuilder.genericBeanDefinition(Config.class);

It still doesn't work

I am engaged in Java security research and want to find a way to dynamically configure AOP to execute malicious code.So I want to find a way to make AOP effective after registering the beans configured by AOP.

If there is a deserialization vulnerability in the application, the hacker can trigger the function of registering AOP through a maliciously constructed object, and then execute malicious code.

4ra1n
  • 1
  • 1
  • Add `@Component` to your aspect and well that is it. Nothing more nothing less. – M. Deinum Nov 24 '21 at 10:32
  • I know that the @Component annotation needs to be configured under normal circumstances, but I need to configure it during runtime instead of scanning the configuration at startup – 4ra1n Nov 24 '21 at 10:58
  • That won't work in this case, as proxies are generated at startup. So you cannot add an aspect while the application is running and expect than suddently proxies be created for those beans. So normally it would be doable with an aspect you can add the bean but the AOP won't be applied. – M. Deinum Nov 24 '21 at 11:01
  • 1
    _"I need to configure it during runtime instead of scanning the configuration at startup"_ - please explain why. This looks like an [XY problem](https://meta.stackexchange.com/a/66378/309898) situation, because you are explaining your technical idea of **how** you think the problem should be solved rather than **what** you need and **why** you need it. – kriegaex Nov 24 '21 at 14:49
  • I am engaged in Java security research and want to find a way to dynamically configure AOP to execute malicious code.So I want to find a way to make AOP effective after registering the beans configured by AOP. – 4ra1n Nov 25 '21 at 03:22
  • If there is a deserialization vulnerability in the application, the hacker can trigger the function of registering AOP through a maliciously constructed object, and then execute malicious code – 4ra1n Nov 25 '21 at 03:31
  • This question is still listed as unanswered, even though I wrote an answer and linked to two related topics with example code. Please inspect my answer, then either accept and upvote it or comment on it if you do not understand it. Thank you. – kriegaex Dec 29 '21 at 01:37

1 Answers1

0

Your private Advisor config() should be @Bean public Advisor config(), then it would work, but only while wiring the application.

See this piece of code on GitHub for an example, which I used in update 3 of this answer. You can clone the project and experiment with it.

Another example can be found in this question. You just need to apply the correction from my answer in order to make it work.

I do not think it gets any more dynamic than that, but I am by no means a Spring expert.

kriegaex
  • 63,017
  • 15
  • 111
  • 202