Securing Web Apps Against XSS and SQL Injection

Securing Web Apps Against XSS and SQL Injection
Learn how to protect your applications by preventing two of the most common and dangerous web vulnerabilities.
1. Cross-Site Scripting (XSS)
XSS allows attackers to inject malicious scripts into pages viewed by other users. There are three main types:
- Stored XSS: Malicious payloads stored on the server (e.g. in a database) and served to users.
- Reflected XSS: Payloads reflected off the server in responses, often via URL parameters.
- DOM-based XSS: Client-side scripts manipulate innerHTML or document.write using untrusted data.
Example of vulnerable code:
// Node.js + Express example
app.get('/greet', (req, res) => {
const name = req.query.name;
res.send('Hello, ' + name + '
');
});
If an attacker visits ?name=<script>alert('XSS')</script>, the script runs in the user’s browser.
2. SQL Injection
SQL Injection occurs when untrusted input is concatenated into SQL queries, allowing attackers to manipulate your database.
Vulnerable example:
// PHP example
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT * FROM users WHERE username = '" . $username . "' AND password = '" . $password . "'";
$result = mysqli_query($conn, $sql);
An attacker could set username=admin'-- to bypass authentication.
3. Mitigation Strategies
A. Preventing XSS
-
Escape Output: Encode user-supplied data before inserting into HTML.
Example in React:
<div>Hello, <span>{escape(userInput)}</span></div>
-
Content Security Policy (CSP): Restrict sources of executable scripts:
Content-Security-Policy: default-src 'self'; script-src 'self';
- Sanitize HTML: Use libraries like DOMPurify to clean untrusted HTML before injection.
B. Preventing SQL Injection
-
Parameterized Queries / Prepared Statements: Never concatenate strings.
Example in Go with database/sql:
db.Query("SELECT * FROM users WHERE id = ?", userID)
- ORMs: Use Object-Relational Mappers (GORM, Sequelize) which handle parameterization automatically.
- Input Validation: Enforce strict patterns (e.g. alphanumeric only) for user inputs.
4. Best Practices
- Least Privilege: Database users should have minimal permissions (e.g. no DROP or ALTER rights).
- Regular Audits: Scan your code and dependencies for vulnerabilities (e.g. with Snyk or OWASP ZAP).
- Security Headers: Enable X-XSS-Protection, X-Content-Type-Options, and Strict-Transport-Security.
- Automated Testing: Include security tests in your CI pipeline (fuzzing, static analysis).
Conclusion
By escaping output, using parameterized queries, and enforcing strong security policies, you can effectively defend your web applications against XSS and SQL Injection. Make these practices part of your development process to safeguard your users and data.