To make things worse, registrars are not quick enough to take down phishing domains..
It is time that the Hive community tries to mitigate this issue on their own.
As a matter of fact, this is what I worked on in the past few days.
NOTE : the demo page will not be sanitized by my universal script until you: 1. Navigate to https://cors-anywhere.herokuapp.com/corsdemo and click on the "Request temporary access" button, 2. refresh the demo website.
I have proved my universal script working on: (see screenshots down below)
HIVE.BLOG - https://hive.blog - @blocktrades
@quochuy
PEAKD - https://peakd.com - @asgarth,
@jarvie
LEOFINANCE - https://leofinance.io - @khaleelkazi
ECENCY - https://ecency.com - @good-karma
3SPEAK - https://3speak.tv - @theycallmedan,
@starkerz
D.BUZZ - https://d.buzz - @chrisrice
STEM social - https://stem.openhive.network - @lemouth
STEM geeks - https://stemgeeks.net - @enforcer48 ?
It would be great if each Hive frontend maintaner could review it and adapt it to their needs (if they need to -- I tested this script in all major Hive frontends already and it did not seem to have unwanted side effects). I highly recommend though that the integration is thoroughly regression tested before it's used in production.
FYI also for:
AnonRamblings @emrebeyler, DTube
@heimindanger, Engage
@arcange, Engrave
@engrave,
@nicniezgrublem, Hive-db
@jesta, Hive-Engine
@aggroed, Hiveblockexplorer
@penguinpablo, Hiveblocks
@roadscape, HiveEngine
@holger80, Quello
@tobias-g, ...
+ other project maintaners: @yabapmatt,
@stoodkev,
@aggroed,
@louis88,
@mahdiyari,
@acidyo,
@fbslo,
@rishi556.
(apologies for the mass tag)
I believe that blocking phishing campaigns in an unified way in all frontends is possible despite the different tech stacks in use. It does no matter which framework the website maintainer used to develop their website (eg. ReactJS, AngularJS, VueJS, JQuery, vanilla JS, etc). Using JS global overrides it is possible to prevent users from falling victim of phishing.
Any known phishing link in the UI will be red and strikethrough-ed. Furthermore if you click on a known phishing link you'll see an alert telling you that it's phishing and it won't allow you to navigate to the phishing domain from the Hive frontend.
Any image that is marked as a phishing attempt (eg. an image with some text saying "claim your $ 1000 in tokens at www.justinscam.com") will not be displayed in any frontend that uses my script (or a variant of it) as soon as its URL is published into the public blacklist.
More details will follow towards the end of the post to list all the native features of the browser that are hardened by my script in order to prevent phishing (ie. iframes, scripts, window open, XHR requests, Fetch api).
Integrating this script is very straightforward. In order to integrate it, simply add a tag to the head section of your index.html page. That's it!
Your index.html :
<head>
// ADD THIS ONE LINE WITH MY SCRIPT vvv
<script src="https://keys-defender.github.io/hive/scripts/universal-bridge-against-phishing.js">
...
</head>
<body>
...
</body>
</html>
This should be enough for your tests. Some intial recommendations though:
Overview of protected features on various Hive Frontends
[screenshot taken after applying my script to Leofinance]
styling applied to known phishing links: red and strike-through
alert displayed when a known phishing link is clicked:
(my comment: @keys-defender/re-keys-defender-6byyqg)
Other frontends:
[screenshot taken after applying my script to 3speak]
[screenshot taken after applying my script to d.buzz]
(my post: @keys-defender/zy71ydsnp4o1ufhs6j7ksz)
[screenshot taken after applying my script to Stem social]
[screenshot taken after applying my script to Stem Geeks]:
[screenshot taken after applying my script to hive.blog]
[screenshot taken after applying my script to hive.blog]
[screenshot taken after applying my script to Peakd]
[screenshot taken after applying my script to Ecency]
Not supported by my universal script:
Potential improvements:
Concerns:
Centralization. Despite being a good start, we should not rely only on @spaminator's API. Some potential solutions to this is to allow users to choose which blacklist to use, or fetch multiple blacklists at the same time. Or even have each Hive website maintainer host their own blacklist.
No load testing was performed on @spaminator API. If all Hive frontends start using their API it may become an issue.
@spaminator team to chim in on this.
The requests from my script are already throttled significantly on the client side and a local cache is used as well.
Proper server-side caching on @spaminator API. Eg. Cache-Control response header set to 5 mins? Cloudfront (AWS) caching / Varnish / Redis?
Scaling. How scalable is @spaminator API? Would they incur in prohibitive cost if too many requests were to be sent daily? Do they have a defense mechanism in place for DDOS attacks? This is not a deal breaker since all users will have a cached version of the blacklist, but an attacker could try and take advantage of this for a new phishing campaign.
Notes for devs that try my script:
IS_DEBUG to false.The list of global overrides added in my script is: document.createElement, element.setAttribute and getAttribute, history.pushState, XMLHttpRequestClass, window.fetch, window.open.
The DOM elements sanitized by my script are: iframe, script, img, a. Other potential candidates that would be easy to cover: input, audio, embed, source, track, video, link.
When the document is fully rendered all the risky elements (anchors, images, etc) are checked again if they weren't already. Eg. comments fetched after the page is fully loaded.
In order to reduce the load on @spaminator's servers, if the user is idle on a page the API is queried again only every 15 minutes. If the user navigates to a different subpath of a Single Page Application (eg. https://hive.blog) (would not cause a page refresh) the api is queried only if at least 5 mins passed from the last query.
The same applies for non-SPA (eg. Leofinance, Peakd). A new API request to fetch the updated list of domains is sent only if more than 5 minutes passed from the last request.
Example of phishing domains fetch on history change
Metrics - I added some timers and I noticed no significant performance impact validating all risky elements against the list of known phishing domains.
The script is already resilient to API 500 responses (eg. DDOS-ed). We could also periodically rotate to different APIs or fetch multiple ones at the same time.
Here is a link to my script transpiled with BabelJS for older browsers and minified to save some milliseconds in the load time: https://keys-defender.github.io/scripts/universal-bridge-against-phishing.min.js
To reiterate, before using this script in production it is highly recommended that you perform regression testing to make sure that existing features are not affected by the global overrides in my script. From my own tests they seem to all work correctly but this should not be put in production as is without review and further testing on each Hive frontend.
Are you bored with your day and willing to read more?
If you're not tired of hearing me rumble about this stuff in your head, here is some more stuff to read..
Why did I decide to work on this solution?
There were some discussion ongoing on Discord and Slack about how to timely react to phishing campaigns that recently plagued Hive. @guiltyparties and
@pfunk claimed that our best shot would be to block dangerous links directly in the Hive frontends.
This though required every single maintainer of the Hive condensers to implement their own logic from scratch in order to block attackers.
The idea I already have had in mind for a while though was to use a single script, as an universal solution for most Hive frontend out there.
I had already worked on something similar for a client of my employer. It was not for phishing, but the same logic applied. The platform I was working on used a custom scheme (eg. somescheme:// instead of https://) and all relative protocol links added by third party scripts (eg. "//www.googletagmanager.com") were defaulting to the custom scheme instead of using HTTPS.
In that occasion I had to use some global overrides to add the https prefix to anything that was meant to go out to third parties. That ended up being handy for this solution on Hive.
When did I work on this Proof of Concept for Hive frontends, you ask?
Late at night in the past few days while caring for my few-days-old newborn. I'm off work and getting bored so I decided to put my sleep deprivation at work and started writing some code for this purpose. I hope it will be useful and get used to effectively improve our Hive frontends and discourage scammers.
Keys-Defender features:
Take care,
@keys-defender (
@gaottantacinque)
Please don't forget to upvote and reblog. Donations are welcome as well, those damn diapers aren't free! =P