Hi Folks,Greetings!I have a Reactive Web application in which a Web Block has an ID input parameter. Using this ID, an aggregate retrieves the corresponding data, and the data is then downloaded. However, a hacker can modify the value of the Web Block's input parameter and pass any other ID, allowing them to download data that does not belong to them. I would like a solution to prevent this. Is there a way to stop users from modifying the ID, or is there an alternative approach where I can retrieve the ID without passing it as an input parameter? Alternatively, can I use something else instead of the ID, such as a GUID?
Could you please help me with this issue?
Thank you!
It would be helpful if you could describe the whole picture, what is the actual use-case and how access is granted.
For an anonymous user, a one-time code/password can be a better approach than relying only on a GUID,if the resource contains sensitive data.
Hi @Meer Imtiyaz Ali,
I don't think anonymous access and sensitive data can align here.
The goal is to add layers of security so the data isn't exposed by a single weak point. Suppose someone manages to grab a valid record ID the real question is: what stops them from retrieving that record's data?
That's where role and identity come in. Knowing an ID is one thing; being authorized to read it is another. Obtaining someone's role or identity is far harder than obtaining an ID. We're not trying to eliminate the risk entirely that isn't realistic only to make it progressively stricter, knowing each layer has its own trade-offs.
So the first layer is role-based authorization. Where that isn't available, the next option is changing the form of the reference itself a GUID or an encrypted identifier (e.g. AES) instead of the raw ID.
And if the system is restricted to internal users, you can add network-level layers on top: IP allowlisting/Whitelisting so requests only come from your internal network, and CORS to limit which origins can call your endpoints. How far you can go with this depends on your environment.
You cannot really “stop” users from tampering with IDs in Reactive; anything sent to the browser can be changed. The solution is:
Assume the Web Block input can be manipulated Treat any ID (or GUID) coming from the client as untrusted. Even if you switch from an integer ID to a GUID, a malicious user can still change it if they see it in the request. Using GUIDs only makes guessing harder; it does not replace server‑side authorization checks. Secure way to pass URL parameter ID easily Gusses
Validate ownership/permissions on the server In the server logic that fetches or downloads the data (the aggregate/screen preparation/server action):
GetUserId()
Example pattern:
Input: RecordId (from Web Block)
RecordId
Server action / aggregate filter:
Entity.Id = RecordId AND Entity.UserId = GetUserId()
If the aggregate returns 0 records, abort and show an error/empty result.
Only when the record is found and belongs to GetUserId() proceed with the download.
This way, even if a hacker sends another ID, the server will not return data unless that record is linked to the logged‑in user (or passes whatever business authorization rules you define). This is the “zero‑trust” approach recommended for Reactive apps. secure server actions from manipulated input
Avoid relying solely on client‑side filtering Do not assume “if the UI only shows my own records, it’s safe”. The user can still craft a different request (Postman, browser dev tools). The check must be in the same server action that reads and/or returns the data. secure server actions from manipulated input
Optional: hide or harden identifiers, but keep server checks You can add extra layers but they never replace step 2:
Guid
GenerateGUID()
Alternative to passing IDs in URLs If the concern is “clean” URLs or avoiding exposing IDs in the address bar:
UserId = GetUserId()
Still, if you must identify a specific record, some identifier must travel to the client; that’s why server‑side checks are mandatory.
Summary
Hi @Meer Imtiyaz Ali ,
You can introduce RBAC for the resource you are loading. If you're currently using an Aggregate, you could move the logic into a Data Action and validate that the current user has the required role or access rights before fetching and returning the data.
Using a GUID instead of a long integer ID can also help, since it makes the identifier much harder to guess. However, I would still keep the authorization validation in place.
Also how are you passing this ID to the block, directly from the screen input or is also fetched from an aggregate?
Thanks, @Mihai Melencu, for the quick response!
The Aggregate is defined within a Data Action itself, and the user is anonymous.Yes, I am directly passing the input value from the Screen to the Web Block.
Thanks, Mihai Melencu and Sherif El-Habibi, for your valuable responses. I was able to resolve my requirement by using a GUID, and the solution is working as expected. Thank you both very much for your help and support. I truly appreciate your assistance.Best regards,Meer Imtiyaz Ali
Hi, the ID is encrypted and descripted at the block level. We have already those server actions on the forge components.