Network Security Fundamentals
Network security encompasses the policies, practices, and tools used to prevent unauthorized access, misuse, or modification of a computer network and its resources. For web developers, understanding network security is essential because every HTTP request your application receives has traversed multiple network layers, each of which presents an opportunity for an attacker to intercept, modify, or block traffic.
The OSI (Open Systems Interconnection) model provides a framework for understanding network communication in seven layers. Web applications primarily operate at the Application Layer (Layer 7), but attacks can target any layer. A DDoS attack might flood Layer 3/4 (Network/Transport), while a SQL injection attack targets Layer 7 (Application).
Key Network Security Concepts
- Firewalls: Filter traffic based on rules. Network firewalls operate at Layers 3-4, while Web Application Firewalls (WAFs) operate at Layer 7 and can inspect HTTP request content.
- DNS Security: DNS translates domain names to IP addresses. DNS spoofing, cache poisoning, and DNS hijacking can redirect users to malicious servers. DNSSEC provides cryptographic validation of DNS responses.
- Network Segmentation: Dividing a network into separate zones limits lateral movement. If an attacker compromises one segment, they cannot easily reach others.
- Intrusion Detection/Prevention: IDS monitors traffic for suspicious patterns. IPS actively blocks detected threats. Modern systems use machine learning for anomaly detection.
Firewall Configuration for Web Applications
Web applications typically need only a few ports open to the internet: 80 for HTTP (which should redirect to HTTPS), 443 for HTTPS, and possibly 22 for SSH management (restricted to specific IPs). Everything else should be blocked by default. This is the principle of default deny — block everything and only allow what is explicitly needed.
// Example: Programmatic firewall rules using cloud provider SDK
// AWS Security Group configuration
const securityGroupRules = {
inbound: [
{
protocol: "tcp",
port: 443,
source: "0.0.0.0/0", // HTTPS from anywhere
description: "Allow HTTPS traffic",
},
{
protocol: "tcp",
port: 80,
source: "0.0.0.0/0", // HTTP (redirect to HTTPS)
description: "Allow HTTP for redirect",
},
{
protocol: "tcp",
port: 22,
source: "10.0.0.0/8", // SSH only from internal network
description: "SSH from internal only",
},
],
outbound: [
{
protocol: "tcp",
port: 443,
destination: "0.0.0.0/0", // Allow outbound HTTPS
description: "Outbound HTTPS for APIs",
},
{
protocol: "tcp",
port: 5432,
destination: "10.0.2.0/24", // Database subnet only
description: "PostgreSQL to DB subnet",
},
],
};
// Application-level IP allowlisting middleware
const allowedIPs = new Set(process.env.ADMIN_IPS?.split(",") || []);
function ipAllowlist(req: Request, res: Response, next: NextFunction) {
const clientIP = req.ip || req.socket.remoteAddress;
if (!allowedIPs.has(clientIP!)) {
logger.warn(`Blocked access from unauthorized IP: ${clientIP}`);
return res.status(403).json({ error: "Access denied" });
}
next();
}
// Apply to admin routes
app.use("/admin", ipAllowlist);
DNS Security
DNS is often called the phone book of the internet — it translates human-readable domain names into IP addresses. Because DNS was designed without security in mind, it is vulnerable to several types of attacks. DNS spoofing involves forging DNS responses to redirect users to malicious servers. DNS cache poisoning corrupts the DNS resolver cache to achieve the same goal. DNS tunneling uses DNS queries to exfiltrate data or establish command-and-control channels.
// DNS security: Implementing DNS-over-HTTPS (DoH) for secure DNS resolution
import https from "https";
async function secureResolve(hostname: string): Promise<string[]> {
return new Promise((resolve, reject) => {
const options = {
hostname: "dns.google",
path: `/resolve?name=${encodeURIComponent(hostname)}&type=A`,
method: "GET",
headers: {
Accept: "application/dns-json",
},
};
const req = https.request(options, (res) => {
let data = "";
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
try {
const response = JSON.parse(data);
if (response.Status !== 0) {
reject(new Error(`DNS resolution failed: status ${response.Status}`));
return;
}
const addresses = response.Answer
?.filter((a: any) => a.type === 1)
.map((a: any) => a.data) || [];
resolve(addresses);
} catch (e) {
reject(e);
}
});
});
req.on("error", reject);
req.end();
});
}
// Validate that a domain resolves to expected IPs (detect DNS hijacking)
async function validateDNSResolution(
domain: string,
expectedIPs: string[]
): Promise<boolean> {
const resolvedIPs = await secureResolve(domain);
const unexpected = resolvedIPs.filter((ip) => !expectedIPs.includes(ip));
if (unexpected.length > 0) {
logger.alert({
event: "DNS_HIJACK_SUSPECTED",
domain,
expected: expectedIPs,
resolved: resolvedIPs,
unexpected,
});
return false;
}
return true;
}
DDoS Protection
Distributed Denial of Service (DDoS) attacks overwhelm your application with massive amounts of traffic from many sources simultaneously. Protection involves multiple layers: network-level filtering with your cloud provider or CDN (Cloudflare, AWS Shield), application-level rate limiting, and architectural patterns like auto-scaling and geographic distribution.
// Application-level DDoS protection patterns
import { RateLimiter } from "./rate-limiter";
// Connection tracking to detect potential DDoS
class ConnectionTracker {
private connections: Map<string, { count: number; firstSeen: number }> = new Map();
private readonly maxConnectionsPerIP = 50;
private readonly windowMs = 60000; // 1 minute
track(ip: string): { allowed: boolean; reason?: string } {
const now = Date.now();
const record = this.connections.get(ip);
if (!record || now - record.firstSeen > this.windowMs) {
this.connections.set(ip, { count: 1, firstSeen: now });
return { allowed: true };
}
record.count++;
if (record.count > this.maxConnectionsPerIP) {
return {
allowed: false,
reason: `IP ${ip} exceeded ${this.maxConnectionsPerIP} connections in ${this.windowMs}ms`,
};
}
return { allowed: true };
}
// Periodically clean up old entries
cleanup() {
const now = Date.now();
for (const [ip, record] of this.connections) {
if (now - record.firstSeen > this.windowMs) {
this.connections.delete(ip);
}
}
}
}
// Request size limiting to prevent resource exhaustion
app.use(express.json({ limit: "10kb" })); // Limit JSON body size
app.use(express.urlencoded({ limit: "10kb", extended: true }));
// Slow loris protection: set request timeout
const server = app.listen(3000);
server.timeout = 30000; // 30 second timeout
server.headersTimeout = 10000; // 10 second header timeout
server.keepAliveTimeout = 5000; // 5 second keep-alive
Security Warning: Network Misconfigurations
- Open database ports: Never expose database ports (3306, 5432, 27017) to the internet. Use private subnets and VPN/tunnels.
- Default credentials on network devices: Change all default passwords on routers, switches, and load balancers immediately.
- Unencrypted internal traffic: Even within your private network, use TLS. Internal network breaches happen frequently.
- Missing egress filtering: Control outbound traffic too. If a server is compromised, egress filters prevent data exfiltration.
Network Security Checklist for Web Applications
- Use HTTPS everywhere: Including internal service-to-service communication.
- Implement WAF rules: Block known attack patterns at the edge.
- Enable DNSSEC: Protect against DNS spoofing and cache poisoning.
- Use CDN for DDoS protection: Cloudflare, AWS CloudFront, or similar services absorb volumetric attacks.
- Segment your network: Separate web servers, application servers, and databases into different subnets.
- Monitor network traffic: Use flow logs, IDS/IPS, and anomaly detection.