Securing Web Applications Against Common Vulnerabilities

Hoàng Ngô Anh Đức· 28/05/2026 02:12
Securing Web Applications Against Common Vulnerabilities Cover

Building a beautiful user interface and a fast backend is fantastic, but it means nothing if your system is vulnerable to security exploits. Web security is a core engineering requirement, not an afterthought.

Let's explore the three most common web vulnerabilities—**Cross-Site Scripting (XSS)**, **Cross-Site Request Forgery (CSRF)**, and **SQL Injection**—and look at how to implement secure defenses!

### 1. Mitigating Cross-Site Scripting (XSS)

XSS occurs when an application receives untrusted data and displays it on a page without sanitizing or escaping it, allowing malicious scripts to execute in the user's browser.

#### The Defense:
* **Always escape output:** In Vue 3, using `{{ mustache }}` syntax automatically escapes text content. Only use `v-html` with extreme caution and never with user-supplied comments.
* **Implement a strict Content Security Policy (CSP):** Prevent inline scripts and unauthorized API requests by serving a secure header:

```http
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.com;
```

### 2. Preventing Cross-Site Request Forgery (CSRF)

CSRF occurs when a malicious website tricks a logged-in user’s browser into sending an unauthorized HTTP request (like making a purchase or changing an email address) to your application.

#### The Defense:
* **Use SameSite Cookies:** Configure all authentication session cookies with `SameSite=Lax` or `SameSite=Strict` and the `Secure` flag.
* **Double-Submit Cookie Pattern:** For state-changing POST requests (e.g. adding comments), generate a unique token, store it in a cookie, and verify that it matches a custom request header or hidden input field on submission:

```go
func CSRFMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
cookieToken, err := r.Cookie("csrf_token")
formToken := r.FormValue("csrf_token")

if err != nil || cookieToken.Value != formToken {
http.Error(w, "Invalid CSRF Token", http.StatusForbidden)
return
}
}
next.ServeHTTP(w, r)
})
}
```

### 3. Preventing SQL Injection

SQL Injection occurs when user input is concatenated directly into SQL query strings, allowing attackers to manipulate queries and steal database records.

#### The Defense:
* **Parameterized Queries:** Never use string formatting (`fmt.Sprintf`) to embed parameters. Always use placeholder tokens (`?`) provided by your database driver:

```go
// ❌ HIGHLY VULNERABLE!
query := fmt.Sprintf("SELECT * FROM users WHERE username = '%s'", input)

// ✓ parameter-safe and secure!
query := "SELECT * FROM users WHERE username = ?"
row := db.QueryRowContext(ctx, query, input)
```

Enforcing these parameterized guidelines completely removes the risk of SQL injection!

// Read next

// Reader response

Comments

0 Comments

This article has no comments yet.

Name is limited to 60 characters and comment content to 1000 characters.

Hoàng Ngô Anh Đức

// Author

Hoàng Ngô Anh Đức

Senior Full-Stack Engineer & Software Architect

Tôi là một kỹ sư phần mềm giàu kinh nghiệm chuyên thiết kế và xây dựng các hệ thống web hiện đại, scalable backend sử dụng Go, Vue.js, TypeScript và kiến trúc đám mây Cloud. Đam mê chia sẻ kiến thức kỹ thuật và tối ưu hiệu năng phần mềm.