Safeguarding Redirects in Vue.js Applications: Preventing Open Redirect Attacks

Mustafa Dalga
heybooster
Published in
3 min readJul 18, 2023

In web applications, it’s quite common to redirect users to different pages based on their actions or status. For instance, if a user attempts to access a protected route but is not logged in, the app might redirect them to a login page, and then back to the originally requested page once they’ve successfully logged in. This is often implemented by including the target URL as a parameter in the login URL, like so: http://example.com/login?redirect=/my-insights.

While this is a very useful feature, it can potentially be exploited by malicious actors to perform what are known as open redirect attacks. In an open redirect attack, an attacker crafts a URL that causes your site to redirect the user to an arbitrary website. For example, http://example.com/auth/login?redirect=https://malicious-website.com.

In this post, we’ll discuss how we encountered this issue in a Vue.js application and how we mitigated it.

The Problem

In our Vue.js application, we stored the redirect URL in the local storage when a user was not logged in and tried to access a protected route. The issue was that a user, or a malicious actor, could potentially manipulate this redirect URL to point to an external, potentially harmful, website.

The Solution

Our goal was to prevent the storage of external URLs as redirect URLs. The key to achieving this was to validate the redirect URL before storing it. We wrote a function called isRedirectPathValid to check if the URL is internal or external.

The logic of isRedirectPathValid is simple: it parses the provided path as a URL and compares its origin with the origin of the current location. If they match, it means the path is internal and the function returns true. If they don't match, or if the path cannot be parsed as a URL, the function returns false.

Here is the TypeScript code for the isRedirectPathValid function:

function isRedirectPathValid(path: string): boolean {
let status: boolean = false;
try {
const url = new URL(path, window.location.origin);
status = url.origin == window.location.origin;
} catch (e) {
status = false;
}

return status;
}

Then, in our setRedirectUrl function, we used isRedirectPathValid to decide whether to store the redirect URL. If the path was valid, we stored it as usual. If the path was not valid, we removed any existing redirect URL from the store.

function setRedirectUrl(path: string): void {
if (isRedirectPathValid(path)) {
//store valid path code
}
}

Conclusion

This solution effectively prevents open redirect attacks in our Vue.js application by ensuring that only internal URLs can be stored as redirect URLs. It’s a robust and maintainable solution that correctly handles a variety of edge cases and is resilient against changes in URL format.

Remember, security should always be a priority when developing web applications. Even seemingly minor features, like redirecting users, can be exploited if not implemented carefully. Always validate and sanitize user inputs, even when they come from URLs!

--

--

Mustafa Dalga
heybooster

Software Developer | Nature and Animal Photographer