What's stopping me from making my own modified version of the client? Client side applications are not supposed to be "protected" or anything, since anyone can theoretically modify them and change the client-side behavior. If there's any secrets in the client then you're doomed already. But if everything is secured via protected API routes then there's nothing to worry about.
The post makes it sound like you're trying to protect against client-side modification through tools like Burp Suite. But that's the wrong way to look at the problem, since anything client side should basically be considered compromised. Your goal is not to block tools like Burp Suite. All that tool does is allow you to play with the requests that are made. There are many other tools out there to do things like that.
So basically it's the client side that does the signature verification, so I could simply copy your app's code using the dev tools in the browser, and then make a modified version that removes the client-side signature check. And if the client sends signed messages to the server, then I can just find the key (it has to be given to the client at some point) and make my own API requests using a custom script that adds the signature. Yes it's way more difficult, but that's the definition of security through obscurity.
In some situations it might make sense to implement something like this, say for a client-side game or something where you want to make cheating more difficult, but the moral of the story is that the client should never be trusted, and your server API is what handles security.
It is not the client sending signed messages to the API, it is the API that sends signed messages to the client. The only key the client has access to is the public key, which is not enough to sign messages. About client-signed messages, I wrote in the article thats exactly the reason I objected to something like HMAC. It would take no effort to find the keys, and then it would definitely be security through obscurity. Protecting the API is done by validation of access-level and of data. The validation is to prevent modification of the responses from the API to the client.
I had this exact concern, but tested a lot if it was possible to somehow remove the line (or add a "return true") to the function on the browser "source", but it never worked. How would you run this modified version? You can place breakpoints, and they'll be hit, but modified code won't run AFAIK. You couldn't simply copy the code, modify it and execute it from localhost or other domains and have it working. because the access-control-allow-origin headers are tight. Unless you're aware of another tool that can do that?
The ethical hacker himself was unable to disable it, and he had a couple of days to mess around with it, and we explained to him how the mechanism worked, so it wasn't like he was operating from "obscurity". I'm sure with enough time, resources, and dedication, a motivated attacker can figure the system out from what is publicly available in the client, but with enough time, resources and dedication an attacker can hack into anything so... what's your point?
Also, this solution doesn't only block "Burp Suite", it blocks this vector of attack as a whole, any local proxy will fail.
You're assuming that CORS will protect your API from rogue clients. It will not. CORS protects your users from rogue clients making requests on behalf of the legitimate client. You can run a browser in unsecured context and bypass CORS. You can install a browser extension and bypass CORS. You can call the API directly from an HTTP client and fake the origin. Please read on what CORS tries to protect you from because it seems you have a misconception of it.
What you implemented here is still just an extra step, but no more secure than just testing if your code is running under your domain, for example. The same way I can get your code to fake the domain I can get it to fake that the signatures are correct. You just made it slightly more difficult to access admin routes.
The real thing that gave you the "secure enough" assessment was fixing the API to not allow a rogue client to create admin accounts. The whole RSA "workaround" just made it slightly harder for an attacker to instruct your client to do what the attacker wants.
I hope you can see how even the examples you brought are evidence of how the barrier to discovery was greatly elevated from this simple action alone.
Your objection is boiling down to "but with infinite time, patience and motivation an attacker will figure it out from what is publicly available", which leads to a dangerous "better to let the client be easy to break since it is impossible to make it impossible to break".
When you say it "just made it slightly harder", I wonder if maybe you're aware of something that the professional pentesters weren't? Would you mind cloning the repository and briefly explaining how you'd break it in practice? Because some of your suggestions won't work.
I hope you can take feedback, as it looks like we attacking your ideas hurt your ego as you were heavily invested in something you found really cool to learn and implement.
Would you mind cloning the repository and briefly explaining how you'd break it in practice?
Does not seem the repo you sent is representative. Host your production client somewhere and let us play with it.
Just as a test to see if the changes made to the source files are applied. They're not. The browser is not webpack. You cannot change the readable source files and have the changes create a new compiled version. This is not how the devtools work.
In the image I changed the function in the source files the way you're suggesting you can, to purposefully fail the verification. If this worked, the application on the left wouldn't show any data after a page refresh. It is still working, because these changes were not reflected.
I'll go through my notifications again, but I've seen no screenshot from you. Just texts.
The browser would have to be webpack in order for you to modify readable code and have it compile into a new working version. To do something remotely similar to what you want, you would have to modify the compiled version, which is not trivial and requires understanding of how React works under the hood. Any attempt at calling this trivial is.......... well, there are no polite ways of saying it, so I won't.
Modifying the compiled version is precisely what you need to do. But you don't need to understand how react works under the hood to do that.
It seems to me you're modifying the code translated from source maps and that won't work. As pointed, this is a misunderstanding of how the overrides tool works.
"It seems to me you're modifying the code translated from source maps and that won't work"
Yes. I'm saying that it won't work for some 10 comments by now.
"As pointed, this is a misunderstanding of how the overrides tool works"
Yes, it IS a misunderstanding: of the people suggesting this is as something that trivially works as they naïvely thought. It doesn't. You have to change the compiled code, which is not trivial.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Not at all. Its security by "you can't change how the application is supposed to work".
What's stopping me from making my own modified version of the client? Client side applications are not supposed to be "protected" or anything, since anyone can theoretically modify them and change the client-side behavior. If there's any secrets in the client then you're doomed already. But if everything is secured via protected API routes then there's nothing to worry about.
The post makes it sound like you're trying to protect against client-side modification through tools like Burp Suite. But that's the wrong way to look at the problem, since anything client side should basically be considered compromised. Your goal is not to block tools like Burp Suite. All that tool does is allow you to play with the requests that are made. There are many other tools out there to do things like that.
So basically it's the client side that does the signature verification, so I could simply copy your app's code using the dev tools in the browser, and then make a modified version that removes the client-side signature check. And if the client sends signed messages to the server, then I can just find the key (it has to be given to the client at some point) and make my own API requests using a custom script that adds the signature. Yes it's way more difficult, but that's the definition of security through obscurity.
In some situations it might make sense to implement something like this, say for a client-side game or something where you want to make cheating more difficult, but the moral of the story is that the client should never be trusted, and your server API is what handles security.
It is not the client sending signed messages to the API, it is the API that sends signed messages to the client. The only key the client has access to is the public key, which is not enough to sign messages. About client-signed messages, I wrote in the article thats exactly the reason I objected to something like HMAC. It would take no effort to find the keys, and then it would definitely be security through obscurity. Protecting the API is done by validation of access-level and of data. The validation is to prevent modification of the responses from the API to the client.
I had this exact concern, but tested a lot if it was possible to somehow remove the line (or add a "return true") to the function on the browser "source", but it never worked. How would you run this modified version? You can place breakpoints, and they'll be hit, but modified code won't run AFAIK. You couldn't simply copy the code, modify it and execute it from localhost or other domains and have it working. because the access-control-allow-origin headers are tight. Unless you're aware of another tool that can do that?
The ethical hacker himself was unable to disable it, and he had a couple of days to mess around with it, and we explained to him how the mechanism worked, so it wasn't like he was operating from "obscurity". I'm sure with enough time, resources, and dedication, a motivated attacker can figure the system out from what is publicly available in the client, but with enough time, resources and dedication an attacker can hack into anything so... what's your point?
Also, this solution doesn't only block "Burp Suite", it blocks this vector of attack as a whole, any local proxy will fail.
You're assuming that CORS will protect your API from rogue clients. It will not. CORS protects your users from rogue clients making requests on behalf of the legitimate client. You can run a browser in unsecured context and bypass CORS. You can install a browser extension and bypass CORS. You can call the API directly from an HTTP client and fake the origin. Please read on what CORS tries to protect you from because it seems you have a misconception of it.
What you implemented here is still just an extra step, but no more secure than just testing if your code is running under your domain, for example. The same way I can get your code to fake the domain I can get it to fake that the signatures are correct. You just made it slightly more difficult to access admin routes.
The real thing that gave you the "secure enough" assessment was fixing the API to not allow a rogue client to create admin accounts. The whole RSA "workaround" just made it slightly harder for an attacker to instruct your client to do what the attacker wants.
I hope you can see how even the examples you brought are evidence of how the barrier to discovery was greatly elevated from this simple action alone.
Your objection is boiling down to "but with infinite time, patience and motivation an attacker will figure it out from what is publicly available", which leads to a dangerous "better to let the client be easy to break since it is impossible to make it impossible to break".
When you say it "just made it slightly harder", I wonder if maybe you're aware of something that the professional pentesters weren't? Would you mind cloning the repository and briefly explaining how you'd break it in practice? Because some of your suggestions won't work.
I hope you can take feedback, as it looks like we attacking your ideas hurt your ego as you were heavily invested in something you found really cool to learn and implement.
Does not seem the repo you sent is representative. Host your production client somewhere and let us play with it.
People giving bad feedback doesn't hurt.
It is representative. The code is about the same.
So it is as bad as I imagined. I literally did this in 5 minutes.
If you did, how? You obviously didn't used devtools, as I'm explaining in another comment.

Care to explain what you are trying to convey with the attached image?
Just as a test to see if the changes made to the source files are applied. They're not. The browser is not webpack. You cannot change the readable source files and have the changes create a new compiled version. This is not how the devtools work.
In the image I changed the function in the source files the way you're suggesting you can, to purposefully fail the verification. If this worked, the application on the left wouldn't show any data after a page refresh. It is still working, because these changes were not reflected.
Then it does not seem you used the tool correctly. My screenshot above was taken from devtools.
Again, the browser does not need to be Webpack for this to work - you are misinterpreting how this works.
I posted the screenshot showing the correct use.
I'll go through my notifications again, but I've seen no screenshot from you. Just texts.
The browser would have to be webpack in order for you to modify readable code and have it compile into a new working version. To do something remotely similar to what you want, you would have to modify the compiled version, which is not trivial and requires understanding of how React works under the hood. Any attempt at calling this trivial is.......... well, there are no polite ways of saying it, so I won't.
Modifying the compiled version is precisely what you need to do. But you don't need to understand how react works under the hood to do that.
It seems to me you're modifying the code translated from source maps and that won't work. As pointed, this is a misunderstanding of how the overrides tool works.
It's not because you don't know how to do it that it is not trivial, by the way.
"It seems to me you're modifying the code translated from source maps and that won't work"
Yes. I'm saying that it won't work for some 10 comments by now.
"As pointed, this is a misunderstanding of how the overrides tool works"
Yes, it IS a misunderstanding: of the people suggesting this is as something that trivially works as they naïvely thought. It doesn't. You have to change the compiled code, which is not trivial.