Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support blocklisting long URL domains to prevent malicious redirects #1305

Open
acelaya opened this issue Jan 6, 2022 · 7 comments
Open
Labels
feature 🥇 gold I will implement these features when I reach my sponsorship goal https://github.com/sponsors/acelaya

Comments

@acelaya
Copy link
Member

acelaya commented Jan 6, 2022

Summary

Allow to somehow check for malicious/dangerous/unwanted domains in long URLs.

It could be via an external service, a manually managed blocklisting or some combination of both.

The feature should be optional, and handled via config options or env vars.

When enabled, it should check both when creating a short URL, but also when redirecting for an existing one (or maybe periodically, allowing to mark existing URLs as blocked).

To be decided how to proceed if visiting an existing URL that has "became" blocked. Options are:

  • Display a warning and/or have its own special redirect.
  • Make it behave as a not found URL.
  • Make it configurable.

Refs #1296

@acelaya acelaya added the feature label Jan 6, 2022
@Csardelacal
Copy link

Since I am the one who brought this issue up in the first place, I would like to suggest some potential ways of handling a feature like this, all with different pros and cons:

1. Internal database

Having an internal database of potentially harmful domains and URL would be an extremely convenient and simple way of letting users configure URL that they do not wish to redirect to. Shlink would then need to expose an API endpoint to submit URLs to the blacklist to prevent users from being redirected to these URI.

This would also require to establish permissions within Shlink to determine which users / applications are allowed to interact with the blacklist and which aren't.

Finally, importing lists with malicious domains would require the user to write a script that automatically consumes the API, and updates all of Shlink's blocked domains and URL.

2. Heuristics

Alternatively, a mechanism like many Spam filters use could be used for blocking bad redirections. Filters like Spamassassin will use rulesets that allow them to determine whether an email is spam. Similarly Shlink could use a series of rules to determine whether a URL is bad.

This mechanism would probably only appeal to advanced users, and novices would probably avoid it completely. In return, it allows to combine lookups on public databases with private databases and even check for potentially harmful links or that look 'misleading' based on the contents of the URL.

For a system like this Shlink would just have to expose an interface that could look somewhat like this:

<?php

interface RedirectionFilterInterface
{
   public function block(string $url) : bool;
}

While unappealing to configure for novices, Shlink could ship with a few base rules that provide a reasonable baseline for novices and granular controls for experienced administrators.

Since this mechanism isn't exposed through the API itself, there would be no changes required to it.

3. Shim the URL using an external service

Probably the easiest of the three to implement is to expose a configuration that allows the administrator to shim all of the redirections using a third party application. So that the user just provides a shimming URL for the application to redirect to.

This is similar to how some major networks do it, where the shrt.lnk/xyz gets expanded to analytics.social.network/redirect?{url} which then does perform all the checks before redirecting the user to {url}. This would probably be the fastest to implement on the shlink side of things, but also would require admins who want to use the feature to have a second application that performs the aforementioned checks.

@acelaya
Copy link
Member Author

acelaya commented Jan 13, 2022

Thanks for the support detailed suggestion 🙂

@acelaya acelaya added this to the 3.2.0 milestone Jan 16, 2022
@fredericsimard
Copy link

@acelaya This would be a great addition. Since I turned on the service last week, I have received 2500+ "orphaned visits" which are pretty much all attempts by machines to try and find vulnerabilities, like phpmyadmin, wordpress and mysqladmin.

For a more immediate fix, I thought I could add rules to block certain folders and files from being accessed, so I added them to the .htaccess file inside the public folder, but it doesn't seem to work. I don't want to experiment and break the site, where should I add them instead do you think? The Apache Virtual Host?

In fact, and correct me if I'm wrong, I was thinking of blocking access to any subfolders which are not supposed to be accessed anyway since the URLs are always domain.name/short-code. Or is there something I don't know about?

@acelaya acelaya changed the title Support blocklisting domains somehow Support blocklisting long URL domains to prevent malicious redirects Mar 2, 2022
@acelaya
Copy link
Member Author

acelaya commented Mar 2, 2022

Since I turned on the service last week, I have received 2500+ "orphaned visits" which are pretty much all attempts by machines to try and find vulnerabilities

That's not the purpose of what's described here. Shlink will never be able to prevent requests from happening in the first place.

The purpose here is to protect actual visitors from being redirected to malicious sites. I have updated the title to make that clear.

I was thinking of blocking access to any subfolders

There are no subfolders to block. Your document root should be the public folder, which contains nothing but the entry point. That's all the protection you need.

You can find more info here https://shlink.io/documentation/classic-web-server/

@fredericsimard
Copy link

What I meant by subfolders is those machines are trying to reach domain.apex/wp/wp-config.php for example. Since there is no wp subfolder, why not block access to it in the first place so it doesn't spam the orphaned visits statistics.

Like I said I tried changing the .htaccess inside the public folder but that's not enough. Now, should I play with this file or it's better to leave it untouched? I'll put my blocks in the apache virtual host instead.

@acelaya
Copy link
Member Author

acelaya commented Mar 2, 2022

You can just disable orphan visits.

@fredericsimard
Copy link

But then the attacks and scans would continue, I would just be unaware of them. I'll find a solution. Tx

@acelaya acelaya modified the milestones: 3.2.0, 3.3.0 Jul 25, 2022
@acelaya acelaya added the 🥇 gold I will implement these features when I reach my sponsorship goal https://github.com/sponsors/acelaya label Sep 11, 2022
@acelaya acelaya removed this from the 3.3.0 milestone Sep 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature 🥇 gold I will implement these features when I reach my sponsorship goal https://github.com/sponsors/acelaya
Projects
Status: No status
Development

No branches or pull requests

3 participants