Hello everyone,
I’d like to raise a few questions/concerns regarding the security behavior of SoftOne Web Services, specifically around calling Advanced JavaScript methods via:
https://....oncloud.gr/s1services/JS//
1) clientID validation behavior (and session lifetime)In our Advanced JavaScript modules that are intended to be exposed as web services, we validate the request like this at the beginning of every method:
function checkClientId(obj) { return obj && obj.clientID && obj.clientID.length > 10; }And then:
if (!checkClientId(obj)) return { success: false, error: "Authentication failed due to invalid credentials." };This works fine, but I’d like to better understand how SoftOne validates clientID internally:
Is clientID fully validated server-side (i.e. the call is rejected before JavaScript execution), or is it simply “checked for presence” and then the session is validated only when X.* functions are called?
Is there an official way to validate clientID (or session) without calling a real method?
How is session invalidation expected to work?
A related issue we noticed:
A clientID remains valid even after the user is deactivated, or even after the user’s password has been changed.
Is this expected behavior?
Is there a recommended way to force existing clientID sessions to become invalid when a user is deactivated or their password changes?
We also have other Advanced JavaScript modules that are not intended to be callable via Web Services at all (they are designed to run inside a form, where context variables exist, e.g. FINDOC, etc.).
Example URL format:
https://....oncloud.gr/s1services/JS/CustomClients.CUSTOM_LINSUPDOC/ON_LINLINES_PRICE
When calling this URL directly via HTTP, the response is an error like “FINDOC is undefined”, which suggests that the JavaScript function is being executed even though:
no clientID was provided
and the function is not meant to be exposed externally
My expectation is that such functions should not execute at all when invoked by direct HTTP request (especially without authentication).
Questions:
Is it expected that any Advanced JS function can be triggered via /s1services/JS/<Module>/<Function> even if it was never designed as a webservice?
Is there a recommended way to restrict which JS methods are callable externally (allowlist / blocklist)?
How do you secure internal JS modules to ensure they can only execute in the intended context (inside forms) and not via external HTTP calls?
Any clarification or best-practice guidance would be greatly appreciated, especially around:
correct clientID validation patterns
session invalidation behavior
restricting/unexposing internal JavaScript functions from HTTP access
Thanks in advance!
Dobromir
There is not currently a way to lock the use of Advanced JavaScript modules for use only inside modules. It would be a security improvement if we had that option.
Workaround: Use complex package and module names for internal usage so it would be difficult for someone to guess the package and module names.
If you definitely want to secure some function in the internal modules that is doing serious work outside the module it is supposed to run in, you can seal it by checking if the first argument has the property "clientID" or "service" and stop the execution.
This seems somewhat unsecure at first, but it is a good way if you design APIs for importing/exporting data and you don't want to give API users access via the web services login process. You can then make your own validation process inside the functions and be sure that you didn't expose all the web services to the other API users (if they used the login process).
The way you handle the process seems to be the official one by Softone: If the call has a clientID property, it will be validated first and if OK, the function will be executed. Your response to seal the function is to check if the first argument has a clientID property and that it is big enough to be a valid one.Thanks for the workaround suggestion to “seal” internal functions by detecting clientID / service in the first argument and stopping execution.
However, we have a practical case where the function is an event handler (e.g. ON_LINLINES_PRICE) and it doesn’t receive any arguments at all when executed inside SoftOne (it relies on the form context like FINDOC, etc.).
Example:
.../s1services/JS/CustomClients.CUSTOM_LINSUPDOC/ON_LINLINES_PRICE
When called directly via HTTP, it still “starts executing” and fails only later because context variables are missing.
Do you have any code examples / best practices for protecting such functions that don’t receive an obj argument?
For example, is there any reliable way to detect:
that the function is executed via /s1services/JS/... HTTP request
vs executed inside the SoftOne UI runtime as a real event handler?
Any pattern or snippet would be very helpful.
I agree that using complex package/module/function names can reduce guessing attempts (security-by-obscurity), but the problem is that some of our clients (e.g. financial institutions) run regular security audits and penetration tests.
Even if the names are hard to guess, the fact that internal modules are callable externally at all is something that will likely fail a more comprehensive assessment.
So from a governance / compliance perspective, it would be a big improvement if SoftOne could support an option to explicitly mark JS modules or methods as:
“callable only inside SoftOne”
“callable only via Web Services”
or allowlist/blocklist at module/function level
For “read-only” needs (exposing data from the database), we already use an external .NET Web API with OAuth, and we query the database directly. This is fast, reliable, and easy to secure.
But when we need to create documents in SoftOne, we currently do:
front-facing .NET Web API (OAuth secured)
which then calls SoftOne via /s1services/JS/...
which internally creates documents using Advanced JS
This works, but it is:
relatively slow
more complex than desired
and the exposure of internal JS modules remains a security concern regardless
So the unresolved issue remains: any internal module (even event handlers) can still be triggered externally, and that will likely be raised by any serious penetration test.
Thanks again for the guidance.
If anyone has working examples for securing “argument-less” event handler functions like ON_LINLINES_PRICE, I’d really appreciate it.
Best regards,
Dobromir
--
Softone Developers Network group.
To post to this group, send email to so...@googlegroups.com
---
Λάβατε αυτό το μήνυμα επειδή έχετε εγγραφεί σε ένα θέμα στην ομάδα "Softone Developers Network" στις Ομάδες Google.
Για να απεγγραφείτε απ' αυτό το θέμα, επισκεφτείτε τη διεύθυνση https://groups.google.com/d/topic/soft1/pNZ7y_wizkA/unsubscribe.
Για να απεγγραφείτε απ' αυτή την ομάδα και όλα τα θέματά της, στείλτε ένα μήνυμα ηλεκτρονικού ταχυδρομείου στη διεύθυνση soft1+un...@googlegroups.com.
Για να δείτε αυτή τη συζήτηση, επισκεφτείτε το https://groups.google.com/d/msgid/soft1/c8f59fd9-9456-4edf-acbf-ee3446e0687dn%40googlegroups.com.


X.FORM can be used as a mechanism to protect Advanced JavaScript functions from being invoked externally.
For example, you can check whether (X.FORM != "").
The X.FORM variable is always populated when Advanced JavaScript (AJS) is executed by SoftOne, even if the code is defined at the module level.
When a form context exists (i.e. X.FORM has a value), it indicates that the execution was triggered internally by SoftOne (for example, from within a form).
In this case, the execution of ON_FINDOC_SERIES() can be wrapped with a condition such as:
This ensures that the function is executed only when it is called within a valid form context.
BR,