Comment System with Azure SQL, XSS Protection, Honeypot, and Rate Limits
June 4, 2025
This two-night project involved building a fully working blog comment system backed by Azure SQL. The goal was to allow readers to leave comments while enforcing solid security and a clean UX. Here's how it all came together.
Setting up Azure SQL
I chose Azure SQL Database for hosting comments — Microsoft’s free tier is perfect for small applications like this. I spun up a new logical SQL server with a basic database, configured a firewall rule to allow Azure services, and set up a secure connection string stored as SQL_CONN_STRING
in my Azure Function App settings.
Creating APIs with Azure Functions
Two endpoints were built:
post-comment
: Accepts a comment and writes it to the database.get-comments
: Retrieves and returns comments per post.
Each uses the mssql
package to interact with the Azure SQL instance.
Debugging an npm Issue
One roadblock was that my outer package.json
had mssql
listed, but it wasn’t available in the /api
subfolder where the Azure Function lives. I installed mssql
directly inside /api
, which fixed the issue. A good reminder that local structure matters in serverless apps.
Adding Security
I hardened the API in several ways:
- XSS Protection: Used
DOMPurify
to sanitize bothname
andcomment
server-side. - Honeypot: Added a hidden
website
field in the form. Bots filling this field get blocked immediately. - Rate Limiting: Implemented a server-side SQL-based limit of 5 requests per IP per minute using a
CommentRateLimit
table. - API Key: Added support for
x-api-key
headers for any write operations. Keys aren’t exposed in client JavaScript.
UX Improvements
On the frontend, I added Bootstrap styling to make the comments more readable and visually distinct. Submitting a comment now displays a real-time success or error message, clears the form, and refreshes the comment list without reloading the page.
Final Thoughts
This comment system is fast, secure, and extensible. It runs on serverless architecture with minimal cost (Azure SQL free tier + Azure Functions), and it’s protected against spam, XSS, and simple bot attacks. All data is stored relationally, making it easy to expand later with moderation features or comment threading.
Another solid upgrade to the blog, fully automated and deployed via my Hugo + GitHub workflow.