Man-in-the-Middle (MITM) — Attacks and Securing Your Web Products

Serhii Koziy
3 min readJan 21, 2025

As a Senior Frontend Developer, ensuring the security of web applications is a critical part of the development lifecycle. One of the most common and dangerous threats you might face is a Man-in-the-Middle (MITM) attack. In this article, we’ll delve into what MITM attacks are, their implications for React applications, and strategies for protection with TypeScript examples.

What is a Man-in-the-Middle (MITM) Attack?

A Man-in-the-Middle (MITM) attack occurs when an attacker secretly intercepts and possibly alters communication between two parties, typically a client (browser) and a server. The attacker might eavesdrop, steal sensitive information, or manipulate data in transit.

Common Scenarios of MITM Attacks:

  • Unsecured Wi-Fi networks: Attackers set up rogue access points to capture network traffic.
  • DNS spoofing: Traffic is redirected to a malicious site.
  • HTTPS stripping: Downgrading a secure HTTPS connection to an unsecured HTTP connection.
  • Session hijacking: Exploiting an authenticated session to impersonate the user.

The Risks for React Applications

React applications, being client-side heavy, frequently communicate with backend services via APIs. If these communications are not secured, they become prime targets for MITM attacks. Consequences include:

  • Data theft: Sensitive user data such as login credentials, payment information, or personal details can be exposed.
  • Injection attacks: Altered responses can execute malicious code in your app.
  • Loss of user trust: Security breaches severely damage your application’s reputation.

How to Protect Your React Application

1. Enforce HTTPS

Always use HTTPS to encrypt communication between the client and server. Modern browsers enforce strict security policies when HTTPS is enabled.

Implementation:

Ensure your server is configured to use TLS certificates. For React, add security headers in your production server (e.g., Nginx or Apache). Also, use Strict-Transport-Security to enforce HTTPS:

const httpsRedirectMiddleware = (req: any, res: any, next: any) => {
if (!req.secure) {
return res.redirect('https://' + req.headers.host + req.url);
}
next();
};

This middleware ensures all HTTP traffic is redirected to HTTPS.

2. Implement Content Security Policy (CSP)

CSP prevents unauthorized scripts or resources from being executed in your application.

Implementation:

Add a meta tag in your HTML or configure headers on the server:

<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; connect-src 'self' https://api.example.com"
/>

This restricts resources to trusted origins.

3. Secure API Communication

Ensure API requests are authenticated and encrypted. Use HTTPS, and include appropriate headers to prevent interception.

Example with Axios in TypeScript:

import axios, { AxiosRequestConfig } from 'axios';

const apiClient = axios.create({
baseURL: 'https://api.example.com',
headers: {
'Content-Type': 'application/json',
},
});

apiClient.interceptors.request.use((config: AxiosRequestConfig) => {
config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
return config;
});

apiClient.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Handle unauthorized access
console.error('Unauthorized! Redirecting to login.');
}
return Promise.reject(error);
}
);

4. Validate Certificates with Public Key Pinning

Pinning public keys ensures the client communicates only with your server.

Example with Fetch in TypeScript:

const fetchWithCertValidation = async (url: string) => {
try {
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`,
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Certificate validation failed:', error);
}
};

5. Use Secure Storage for Sensitive Data

Avoid storing sensitive information in localStorage or sessionStorage. Instead, use secure cookies with HttpOnly, Secure, and SameSite attributes.

6. Monitor and Audit Logs

Implement logging to monitor suspicious activities. Tools like Sentry and Datadog can help track and analyze issues.

7. Implement Two-Factor Authentication (2FA)

For additional security, enable 2FA for user authentication. Use tools like Auth0 or Firebase Authentication.

8. Regular Updates and Dependency Audits

Keep dependencies up-to-date to patch known vulnerabilities. Use tools like npm audit or yarn audit to identify risks.

Example:

npm audit --fix

Conclusion

Protecting your React application from MITM attacks requires a multi-layered approach. By enforcing HTTPS, securing API communications, and following best practices like CSP and secure data storage, you can significantly reduce the risk. As a developer, adopting a security-first mindset ensures not only the safety of user data but also the longevity and trustworthiness of your application.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response