Previous part: Putting your web application online – Part 5 – Database and USERS
Starting point: | You have a Node++ application on the server with USERS module. |
This part result: | Your application is protected against fake accounts and spamming bots. |
Skill level: | Middle |
Time: | About 15 minutes |
As long as we didn't establish means to write to us, protecting our application has mostly been confined to the operating system level. The minute we published our first submit button, we are on a very different territory. We already have some protection – mainly against brute-force and injections. But that's still not enough.
When Budgeter was getting somewhat popular, suddenly I could see dozens of new accounts daily. It turned out, they had random strings as their user names, just as if they were generated. They didn't show any further activity. When investigating logs, it was clear that they were just bots – for example there were no resources' reading besides create_acc
page. The nasty part of it was that fake registrations seemed to use real email addresses. And Budgeter welcomes every new member with an email – it could soon face a significant negative flagging!
Apart from fake accounts, there was also increasing volume of spam, coming through contact
form.
As there was already a CSRF token, I had to come up with something more sophisticated to tell the difference between human and bot. I don't like puzzles and captchas just drive me crazy! There had to be some other way.
The solution described here has been working for several years now. Breaking this protection would require custom, non-trivial programming work on those bots. I expect it may happen sooner or later, for now though, it does its job in 100% of cases.
Steps to take:
- JavaScript
- Add secret input to the session data
- Generate secret input on session start
- Call ahi after form is displayed
- Verify hidden input's name on form submission
Step 1 – JavaScript
We will need a simple JS function that adds new hidden input to the form. Let's call it ahi
like add hidden input:
Note that it's actually the input name that matters here, not the content.
Step 2 – Add secret input to the session data
In npp_app.h
there is a custom structure for application session data, that we can extend. Replace dummy
or add new member:
Step 3 – Generate secret input on session start
Set secret_input
value to random string:
Step 4 – Call ahi after form is displayed
We can add this to the footer function (if we have one). It actually adds our hidden input to the form:
Step 5 – Verify hidden input's name on form submission
After we have verified that both valid CSRFT and secret input were present in the form, we can save the message in the database:
We also need to add this verification to do_register
.
That's it for now! We are protected against fake accounts and spamming bots.
Next part: Putting your web application online – Part 7 – Sending email
Is something wrong here? Please, let us know!