How do hackers trick frontend validation?
I think you are very confused about what both CORS and SOP do... neither is relevant to these attacks at all.
There are lots of ways to bypass client-side validation. HTTP is just a stream of bytes, and in HTTP 1.x they're even human-readable text (at least for the headers). This makes it trivial to forge or manipulate requests. Here's a subset of ways to do it, grouped by rough categories:
Bypass validation in the browser
- Browse to your site and input the invalid values. Use the browser dev tools to remove the validation events or manipulate their execution to pass validation anyhow. Submit the form.
- Use the browser dev console to send requests from the site as though through the validated form, but with unvalidated inputs (just directly invoke the function that makes the request).
- Use the browser dev tools to "edit and re-send" a request, and before re-sending, change the valid values in the body to invalid ones.
- For GET requests: just type any URL with invalid parameters into the location bar.
- For POST requests that use non-samesite cookies for authentication: create a web page that POSTs to your server with the expected values (including any CSRF-protection token) but with invalid values, load it in browser, and submit.
Bypass validation using non-browser tools
- Set the browser to run through an intercepting proxy (like most in the security industry, I usually use Burp Suite, but you can use others like Fiddler too). Capture the outbound request, tamper with the fields to make them invalid, and send it on its way.
- Use an intercepting proxy again, but this time replay a previous request with modified, invalid values (in Burp, this is exactly what the Repeater tool is for).
- Right-click a request in the browser's dev tools' network history, select "Copy as cURL", paste the resulting
curl
command into a command line, edit the validated fields to make them invalid, hit Enter to send.
Crafting malicious requests from scratch
- Using Burp Repeater, specify the protocol, domain, and port for your site. Add the necessary headers, including any cookies or other headers needed for authorization. Add the desired parameters, with invalid values. Click "Send".
- Using
curl
, send a request to your site with the required headers and whatever body, including invalid values, you want. - Using
ncat
, open a connection to your site, using TLS, on port 443. Type out the HTTP top line, headers, and body (after all, it's just text, although it'll get encrypted before sending). Send the end-of-file input if needed (usually the server will just respond immediately though). - Write a little script/program in any language with a TCP or HTTP client library (from JS running on Node to a full-blown compiled golang binary) that creates a request with all the required headers and invalid fields, and sends it to your server. Run the script/program.
SOP only applies when the request is sent using a browser AND the request originates from a web page hosted at a different origin (combination of domain, protocol, and port) than the request's destination. Even then, SOP primarily protects against the originating page seeing the response; it doesn't prevent attacks from occurring. If you're the attacker trying to get past client-side validation, then you can just send the request from the origin you're attacking, and SOP is entirely irrelevant. Or just send the request from something that isn't a browser (like a proxy, or curl
, or a custom script); none of those even have SOP in the first place.
CORS is a way to poke holes in SOP (CORS doesn't add any security; it's a way to partially relax the security feature of SOP), so it doesn't even matter unless SOP is relevant. However, in many cases you can make a cross-origin request with invalid parameters (as in the case where I create my own attack page and point the browser at it, then use it to submit an invalid request to your site) because for most requests, SOP only restricts whether you can see the response - you can send the request cross-origin even if the server doesn't allow CORS at all - and often, seeing the response isn't needed.
Pulling the authorization tokens (cookies, header values, whatever) out of the browser after authentication is easy (just examine the network traffic in the dev tools, or use a proxy). Remember, for validation to even be in question, the attacker has to be able to use your site via a browser, which presumably means they can authenticate. Or just submit an authentication request using curl
or whatever, scrape the returned token out of the response, and use it in the malicious invalid requests; no browser needed at all!
There's nothing the browser can do (in terms of sending requests to the server), that I can't do from a shell prompt with some common, open-source utilities.
EDIT: As @chrylis-cautiouslyoptimistic points out, this includes spoofing the Origin header in the request. Although the Origin header is not normally configurable within the browser - it is set automatically by the browser when certain types of requests are made - it's possible to edit it after sending the request (by intercepting or re-playing the request), or to simply forge it in the first place. Any protective measure based on the presence, absence, or value of this header will only be effective in the case that the attacker is indirectly submitting the request through an unwitting victim's browser (as in the case of CSRF), typically because the attacker can't authenticate to the site or wants to attack through another user's account. For any other case, the attacker can simply choose what value, if any, to give as the Origin.
EDIT 2: As @Tim mentioned, things like SOP and anti-CSRF measures are all intended to protect the user of a website from an attack by somebody else on the internet (either another user of the same site, or an outsider who wants to exploit your access to the site). They don't provide any protection at all when the authorized user is the attacker and the target is the site itself or all of its users, through something like a stored XSS, SQL injection, or malicious file upload (the types of things people sometimes try to prevent with client-side validation).
Maybe a very short answer will help as well.
I never thought about it much, I just thought this meant someone could bypass the validations by making a request on something like Postman. But then I learned that with a same origin policy that's not possible.
The same-origin policy is something that browsers voluntarily implement to protect their users. It does not affect Postman because Postman does not implement this policy. Therefore, your original thought is correct.
Postman and same origin policy aren't obstacles. To understand this, I need to explain why, as a developer, you virtually never trust the client/front end.
Front and back end trust
If someone controls a computer, they control what it sends the server. That's literal: every last byte of it, every last header or request, every last POST field in a form or GET parameter in a URI, every web socket and connection, every last timing (within broad timing limits that aren't an issue here).
They can make that computer send the back end literally, anything whatsoever they want, on demand. Any GET. Any POST. Any header field. Anything. They can include any header. Any origin. Any cookie information they choose and know. Literally, anything. Common exceptions for most use-cases are perhaps physical "black box" encryption cards/keys, and the client's IP address, both of which are trickier barriers if checked during a session - and even the IP can usually be spoofed in various ways, especially if they don't care about a reply.
The upshot is that from a security perspective you can't trust anything a client sends. You can raise the bar quote a lot, enough for most everyday uses. Secure transport (TLS/HTTPS) to make it extremely difficult to modify or intercept or change the traffic if someone controls an intermediate computer it's routed through. A well implemented OS and browser, that stop scripts or malware outside that specific web page from interfering locally. Certificate checking one or both ends. Secured networks that authenticate what may attach.
But every last one of those is raising a bar, not an absolute defence. Every one of those has been broken before, gets broken now at times, will be broken in future. None is guaranteed bug and loophole free either. None can defend against a user, malware, or rootkitted remote access at the client end that deliberately, or ignorantly subverts the defences on the client PC, because such a user can typically change or bypass anything the OS or browser are programmed to do. None is a true perfect defence.
So if you have any software or web based system with a back-end and front-end, its a golden rule that you don't trust the data the client provides. You recheck it when received at the back.end. If the request is to access or send a web page or file, is that okay, should that session be allowed access to that file, is the filename a valid one? If the request is some data or a form to process, are all the fields reasonable and containing valid data, is that session allowed to make those changes.
You don't trust a thing that isn't under your own secured known control.
Server, you'll trust by and large (you manage the OS and security, or have trusted partners who do). But client and wider network no trust at all. And even for the server, you have security checks on it, be it malware and behaviour detection, access controls, or network scanning software, because you could be wrong about that, too.
So you validate at the client browser/app (front-end) for convenience of the client, because most clients are honest and many mistakes can quickly be detected in the browser or app.
But you validate at the server (back-end) to actually do your real checking if the request or data is valid and should be processed or rejected.
That said, your answer is...
You asked how its done. The software to do it can be done many ways - malware, deliberate user act, misconfigured client system/software, intercepting computer/proxy.
But however it's done, this is the basic process that exploits these issues within a client, makes any client packet fundamentally untrustworthy (including origin and referrer fields), and makes it impossible to trust them. It excludes external matters such as certificate misuse, which are outside the OP scope.
- Study what a genuine reply/packet/request/post looks like in the app.
- Modify the packet using built in browser tools, browser extensions, transparent proxies/proxy apps, or create a hand crafted request based on it, with the different headers needed.
(After all, the back-end doesn't actually know what the "real" values should be, or the "real" origin or referrer is, it only knows what the packet * says * they are, or the origin or referrer are. Which takes between 15 seconds and 2 minutes to modify to anything on earth I want it to be, or well under a millisecond if its done by software.) - Modify or fake anything else needed, or craft custom versions, of any packets, and send those instead (wither prepared in advance or modified at the time)
- Done.