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

Need a CAPTCHA system #9

Open
ZacharyDavidSaunders opened this issue Mar 14, 2019 · 6 comments
Open

Need a CAPTCHA system #9

ZacharyDavidSaunders opened this issue Mar 14, 2019 · 6 comments

Comments

@ZacharyDavidSaunders
Copy link
Owner

Sometime, over the course of the last 4 days, the system was brute forced and 800+ illegitimate aliases were created.

This incident did not impact system uptime and the illegitimate aliases will be purged by end of day, however this serves to highlight the need for a CAPTCHA type system.

Luckily, the attack wasn't sophisticated enough to vary the pattern of alias names, making them easy to identify (see examples below):

03a2853c-0863-45db-900e-000a6a4fc8a6
03f135e5-f43d-4fd0-9237-aa99193a0cc2
041f25d8-b8e2-4fbf-ab17-086d78751098
043e3db5-d854-446f-86b2-3da0145e93fd
045f748b-a454-4a22-889e-7e044c903415
047545b2-5cad-4cfa-9d83-8468ea181498
0481e11d-33da-4971-919e-0045d83fbf2b
048557bd-b578-4684-86a7-ed102f3a742f
04ce971a-a91f-49e0-a202-30b956ecd9dc
04fbd611-d4ce-4636-a0b8-9463a47b6ea5
051aab40-6b3b-401e-8512-ee16ef52826e
0529ef90-65e7-4132-a21e-990cdbaed701
05b4c99d-de67-4b80-8515-6a371bff1725
05bed30e-adec-41bc-a863-c5a89f742661
05fcb679-61c1-407a-9637-921570743b06
05fee2e1-50a4-4b8d-9f02-ab8d9fa8d7b9
06161794-c900-43c1-b294-fa8bebb7ae7c
06226bad-62c4-4b71-a75a-9cf17d4f8250
0632f075-a736-4ac7-9d72-03fe969f309e
06e48c70-ae45-4428-9879-d5a322a658c3
06e5f982-735e-4640-8308-a1705470f545

This is obviously a subset of the 800+ aliases, but as you can see, they follow a common structure. Given the low number of aliases created (~800 is pretty small, all things considered), I suspect that this was a proof of concept test and not a full scale attack. Regardless, a CAPTCHA seems necessary.

@ZacharyDavidSaunders
Copy link
Owner Author

Final number of illegitimate aliases was 862. ForwardMX doesn't have a batch update feature and their server got overwhelmed/DOS'd when I sent 862 individual destroy record calls. So, I had to play the "send lots of requests – but not too many" game. Admittedly, this wasn't ideal. My script got less and less efficient the more times it was ran. I could've updated the list each time it was ran and excluded the previously removed (and therefore non-existent) aliases, but I had to export the alias list by hand and continuously updating the list would have been too tedious. The ForwardMX server struggled through but eventually was able to remove all illegitimate aliases.

Here's the script I used to purge:

function run(){
  var numberPurged = 0;
  var list= []; // The exported list of fraudulent aliases. See my earlier comment for examples of these^^.

  for(var i = 0; i < list.length; i++){
    var xhttp = new XMLHttpRequest();
    xhttp.open('POST', ('https://forwardmx.io/api/alias/destroy?' +
        '&key=' + '~~REDACTED~~' +
        '&domain=' + 'pseudoname.io' +
        '&alias=' + list[i]), true);
        xhttp.send();
        numberPurged++;
  }
  console.log(numberPurged);
}

I've been looking to migrate away from ForwardMX to an open source alternative, and ForwardMX's lack of batch updating feature is yet another reason to do so.

@ZacharyDavidSaunders
Copy link
Owner Author

0c92638: I added a rudimentary CAPTCHA system to protect the service while I investigate the possibility of implementing Google's ReCAPTCHA. My system is not ideal (it likely can be bypassed via optical character recognition) and it is not intended to be a long term solution.

@dcstone09
Copy link

dcstone09 commented Mar 25, 2019

I would recommend also adding a rate limiter to the API, possibly https://www.npmjs.com/package/express-rate-limit it could also benefit from logging requests
https://www.npmjs.com/package/morgan

@ZacharyDavidSaunders
Copy link
Owner Author

I'll definitely check those out, thank you. I've been trying to find a solution that will allow the site to be excluded by rate limiting, while enforcing rate limiting on all other API users. These might work well.

I'm also probably going to add https://helmetjs.github.io/ to tighten everything a bit more.

@dcstone09
Copy link

Because the requests on the site are to the API from the user's browser there isn't really any difference between the site and API users. Both should be rate limited equally.
Helmet is a good idea ✅

@ZacharyDavidSaunders
Copy link
Owner Author

For those wondering, a fix is coming for this. I've been gone on vacation (Annapolis, MD ⚓️ is lovely this time of year) and bogged down with grad school work, but I haven't forgotten.

Ideally, I'd like to roll this change into a bigger, quality of life update with changes to the API HTTP methods (e.g. /delete/ should be a DELETE, not a GET), refactoring to make the codebase ES2017 complaint, etc. This all depends on how quickly I can get through more pressing items and how frequently the system is attacked. Even with these attacks, the system continues to be operational and is servicing new (legitimate) users. With that in mind, please understand my delayed response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants