Backend Security Fundamentals (Intro + Injection Attacks)
Importance of Security
-
Security is one of the most important aspects of backend engineering
-
Neglecting security leads to:
- Financial damage
- Business loss
- Resource misuse
-
Ultimately:
- Security issues translate into money and trust loss
Scope of Security
Different Areas of Security
-
Browser Security
- Cookies, local storage, HTML vulnerabilities
-
Network Security
- HTTP/HTTPS, encryption, compression
-
Server Security
- Operating system-level vulnerabilities
-
Backend Security
- Vulnerabilities in application code
Practical Focus
-
Security is a huge domain
-
It’s not necessary to:
- Learn everything at once
-
Instead:
- Focus on practical backend vulnerabilities
- Follow a set of rules and mindset
Goal of Learning Security
-
Not to:
- Learn all techniques in one go
-
Instead:
- Build a security mindset
- Always think about risks while coding
Reality of Security
-
No application can be 100% secure
-
Reasons:
- Technology evolves
- New vulnerabilities appear
-
Goal:
- Reduce risk, not eliminate it
Security Mindset
Core Goal
- Become paranoid about your code
- Always keep security in mind while building applications
Key Principle
-
Ask constantly:
- “What could go wrong here?”
Thinking Like an Attacker
Terminology
- Use “attacker” instead of “hacker”
Attacker’s Focus
-
Attackers don’t care about:
- Framework
- Language
-
They care about:
- Where the developer made an assumption
Critical Question
- “Where did the developer make an assumption?”
Common Developer Assumptions
-
Input from user is clean
-
User identity is valid
-
Requests come only from frontend
-
No one will:
- Inspect network tab
- Modify requests
Why Assumptions Happen
-
Deadlines (especially in startups)
-
Focus on:
- Happy path
- Expected user behavior
Attacker Behavior
-
They:
- Modify inputs
- Break boundaries
- Explore edge cases
- Try to violate assumptions
Outcome
-
Every vulnerability comes from:
- Broken assumptions
Injection Attacks
Definition
-
Injection attacks occur when:
- User input is treated as code instead of data
Root Cause
- Confusion between code and data
Fundamental Insight
-
Backend systems interact with multiple languages:
- SQL → Database
- HTML/CSS/JS → Browser
- Shell → Operating System
Key Idea
-
Each language has:
- Its own syntax
- Special characters
- Execution rules
Where Vulnerabilities Arise
-
When:
- Input crosses language boundaries
-
Example:
- Browser input → SQL query
- Browser input → Shell command
Core Pattern
-
User speaks one language (HTML/JS)
-
Backend interprets input in another (SQL/Shell)
-
Result:
- Input gains unintended meaning
SQL Injection
Scenario: Login System
-
User enters:
- Password
-
Backend query:
SELECT * FROM users WHERE email = 'user_input'
Vulnerable Practice
-
Building query using:
- String concatenation
Happy Path
-
Input:
alice@gmail.com
-
Query becomes:
SELECT * FROM users WHERE email = 'alice@gmail.com' -
Result:
- Correct user fetched
Attack Input
' OR '1'='1' --
Resulting Query
SELECT * FROM users WHERE email = '' OR '1'='1' --'
Step-by-Step Breakdown
'→ closes original stringOR '1'='1'→ always true condition--→ comments out rest of query
Final Effect
-
Query becomes:
- Always true
-
Equivalent to:
SELECT * FROM users -
Returns:
- All users
Impact
-
Data leakage
-
Authentication bypass
-
Exposure of sensitive data:
- Emails
- Password hashes
- Addresses
More Dangerous Attack
'; DROP TABLE users; --
Effect
-
Executes:
- Table deletion (if permissions allow)
Important Note
-
Modern DB drivers:
- May block multiple statements
-
But:
- Older systems may still be vulnerable
Root Cause (Reinforced)
-
Treating:
- User input (data)
-
As:
- Executable SQL (code)
SQL Language Special Characters
-
'→ string delimiter -
;→ statement separator -
--→ comment -
Keywords:
OR,DROP,WHERE
Problem
-
Developer assumes:
- Input contains only data
-
Reality:
- Input may contain SQL syntax
Prevention: Parameterized Queries
Concept
-
Separate:
- Query structure
- User input
Example
SELECT * FROM users WHERE email = $1
Execution
- Query template + input passed separately
Key Advantage
-
Database treats input as:
- Pure data
- Not executable code
Attack Prevention
-
Malicious input becomes:
- Just a string
-
No execution occurs
Additional Layer
-
Validation layer should:
- Reject invalid formats (e.g., invalid email)
Industry Standard
-
Supported by:
- All modern DB drivers
- ORMs (default behavior)
Only Way to Be Vulnerable
-
If you:
- Manually build raw query strings
NoSQL Injection
Misconception
- “No SQL = no injection”
Reality
-
NoSQL (e.g., MongoDB) uses:
- JSON-like queries
Attack Vector
-
Inject operators:
$ne,$gt,$exists
Example Issue
- Passing user-controlled JSON directly to DB
Root Cause
-
User controls:
- Query structure
Command Injection
Scenario
- Backend executes OS commands (e.g., image processing)
Example
-
Using CLI tool (e.g., ffmpeg)
-
Command includes:
- User-provided filename
Vulnerable Pattern
-
Building command using:
- String concatenation
Attack Input
; rm -rf /
Result
-
First command executes
-
Then:
- Destructive command runs
Why It Works
-
Shell interprets:
- Input as commands
Advanced Attacks
-
Use:
- Pipes (
|) - Background execution (
&)
- Pipes (
-
Can:
- Install spyware
- Execute hidden processes
Prevention
-
Use APIs that:
- Separate command and arguments
Key Rule
- ❌ Avoid shell string execution
- ✅ Use argument-based execution
Injection Attack Mental Model
Universal Rule
-
User input must always be:
- Data only
- Never executable
Safe Approach
-
Use:
- Parameterized queries
- Argument-based APIs
Danger Signal
-
If you are:
- Building strings for execution
- Including user input
➡️ Stop and rethink
Core Takeaway
- Injection attacks = Code ↔ Data confusion across boundaries
Final Insight
-
Every time:
- User input crosses systems (browser → backend → DB/OS)
-
Ask:
- Is this being treated as data or code?