The proxy structural pattern introduces another object that your code uses instead of the actual object. This might seem pointless but there are some good reasons why you might consider this.
Most design pattern references list four reasons why you might want to use a proxy. I explain three of them and then put the fourth in a separate explanation because I think the fourth reason can lead to a security vulnerability if implemented wrong.
- The real object might be big or slow to create. Maybe this object is only used rarely in your application. Or maybe it’s always used but just not right away. If you use a proxy, then you can let the proxy create the object when it needs to.
- The real object might not exist on your local computer at all. Or if it does exist on your local computer, it might live in another process that’s isolated from your application. A proxy allows you to work with the object as if it’s readily available nearby.
- You need to do some extra work when accessing the object such as coordinating access from multiple users.
Most of the documentation that describes the proxy pattern actually mentions another common scenario to control access to an object. Maybe you want to verify if the calling code is actually allowed to use the object. Any object responsible for security needs to be protected and reliable. Now typically, a proxy runs in an application right along with the other code. If you put the proxy on some user’s computer, then it’s under that user’s full control. Now granted, most users won’t know what to do with this or how to exploit the vulnerability. But it only takes one user to figure out that all they need to do is change a little bit of code to bypass the authorization and always make the call to the real object to perform the work. If you’re going to use a proxy to control access, then you either need to duplicate that access check in the real object or make sure the proxy can’t be bypassed.
Implementing a proxy is fairly straightforward. Since it needs to be used in place of the real object, it needs to have the same interface as the real object. Ideally, the code using a proxy shouldn’t know that it’s using a proxy at all. It should think that it has direct access. You can use a factory to create either the real object or a proxy.