Допустим у меня отправляется форма ajax, в ней помимо данных, также имеется ip-адрес человека, но его же можно легко изменить! Возьмут, скажем, поставят ip неизвестно кого и как тогда "поймать" самозванца? Также могут зациклить отправку данных, создать нагрузку на сервер. Как с этим бороться? Ясное дело, что можно использовать сессии или капчу, но возможно ли без этого, обойтись? Вернее, есть ли другие варианты и как всё-таки можно получить ip-адрес пользователя так, чтобы он не смог его изменить (при том, что форма отправляется через ajax)?
Никак. Любые данные полученные от пользователя могут быть подменены. Получение IP адреса делается на сервере который точно знает откуда на самом деле пришел запрос.
Возьмут, скажем, поставят ip неизвестно кого и как тогда "поймать" самозванца?
А еще это можно организовать на сетевом уровне, скажем через прокси.
А еще у некоторых пользователей (например тех кто сидят через 3G или публичные wifi сети) ip динамический.
Также могут зациклить отправку данных, создать нагрузку на сервер
С одной машины - не серьезно. В любом случае есть rate-limit и это дело можно настроить в nginx. В случае с прокси или распределенной атакой не поможет.
SimBioT19: жизнь боль, все бесполезно. Если у вас с этим пока нет проблем - лучше ничего не делать. Если проблемы уже есть, проследите сцанарии, пробуйте варианты
Очень просто, сервер не должен доверять клиенту вообще и всегда полностью проверять все входящие данные и уж тем более не доверять делать клиенту какие-либо значимые бизнес-операции.
1. Шифруем IP и формируем hash-подпись своего сервера и отдаём форму в браузер с этими данными (тип hidden или внутрь URI в action, как параметры).
2. После нажатия Submit, форма отправляет запрос на целевой URL с шифрованным IP и hash-подписью.
3. При получении данных формы - целевой URL проверяет подпись и раскодирует IP.
4. Сверяет реальный IP с шифрованным и подпись.
Если все ОК - то форма передана успешно.
tachini: подмена - это речь про proxy или о подмене внутри формы?
Если про proxy - тут нет вопросов.
Если про подмену между серверами (генератором формы и целевым URL) - тогда это довольно сильно затруднительно.