Allow Form Submissions only from trusted sources

I have a custom LAMP site where there are some landing pages with a form that submits to the application to show some results as a preview sample content which one can subscribe to a paid plan.

The landing pages were created beautifully by a designer and I had to stitch the pages to integrate with the application.

But I was wondering if I could have the landing pages on a separate sub/domain which would POST to my application since there’s no user login for the previews. This way the designer can handle the landing pages on a subdomain which he would have exclusive access to and I would focus on the application itself.

But I implemented token in vanilla PHP for CSRF. This won’t work when the designer is having his pure HTML+CSS pages on the separate subdomain.

So how do I mitigate attacks if I can’t implement CSRF ? I can’t depend solely on http referer.

Main goal is to have the landing pages on React on Vercel etc to get a good pagespeed score. And have the HTML designers not depend on the application devs to update landing pages.

As far as I know, you wont be able to do this if the subdomain is only HTML+CSS. You’re going to need Javascript at the very least to establish a token between the two.

JavaScript is available - but how do I prevent an attack using client side JavaScript alone ?

Well it wouldnt be with Javascript alone; you would use Javascript to fetch a token from the main page to ride with the form data and verify its origin.

If you need to absolutely lock it down, at that point you’re just using a PHP session across subdomains, which means you’d need a code injection when loading the subdomain’s pages.

Never assume that the end user will have javascript enabled. Any solution should be able to work without javascript being available.

If you dont use Javascript, your subdomain pages will have to be some form of server-sided handoff. There is NOT an HTML-only solution to this. The least intrusive to the environment is Javascript; the more controlled is making every controlled-form page in the subdomain a PHP (or other server-side handled) page. shrug

What data is posted from the pages to your app anyway?

Just some form data which is used as input to prompts to ChatGPT API.

HTTP_REFERER can be spoofed so you’d need to go IP based. You want PHP, or similar, as a fallback. Never trust javascript.

<?php
// Define an array of allowed referrer URLs
$allowed_urls = array(
	'https://example.com/form-page1',
	'https://example.com/form-page2',
	'https://example.com/another-allowed-page'
);

// Check if the form is being submitted
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
	// Get the referrer URL
	$referrer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';

	// Check if the referrer URL is in the allowed list
	if (in_array($referrer, $allowed_urls)) {
		// The referrer is allowed, process the form
		// Your form processing code here
		echo 'Form submitted successfully!';
	} else {
		// The referrer is not allowed, show an error message
		echo 'Error: This form can only be submitted from specific pages.';
	}
} else {
	// Show the form or handle other request methods
	echo 'Please submit the form.';
}
?>

IP version:

<?php
// Define an array of allowed IP addresses
$allowed_ips = array(
	'123.456.789.000',
	'111.222.333.444',
	'555.666.777.888'
);

// Function to get the user's IP address
function get_user_ip() {
	$ip = '';

	if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
		$ip = $_SERVER['HTTP_CLIENT_IP'];
	} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
		$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
	} else {
		$ip = $_SERVER['REMOTE_ADDR'];
	}

	return $ip;
}

// Check if the form is being submitted
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
	// Get the user's IP address
	$user_ip = get_user_ip();

	// Check if the IP address is in the allowed list
	if (in_array($user_ip, $allowed_ips)) {
		// The IP address is allowed, process the form
		// Your form processing code here
		echo 'Form submitted successfully!';
	} else {
		// The IP address is not allowed, show an error message
		echo 'Error: This form can only be submitted from specific IP addresses.';
	}
} else {
	// Show the form or handle other request methods
	echo 'Please submit the form.';
}
?>

1 Like

To ensure security, configure your form to accept submissions only from trusted sources. Use techniques like CAPTCHA, validation checks, and whitelisting trusted IP addresses to prevent spam and unauthorized access.

One way of achieving this would be to handle and authenticate sessions using JWT or JSON Web Tokens instead of regular PHP sessions. Those were invented for exactly a scenario like this.