How to clear an Appserver identity

Posted by Tim Kuehn on 24-Jan-2017 12:51

I've got a system in place to assert a user identity during an appserver call, and I want to de-assert that identity in the call deactivate procedure.

Since SECURITY:SET-CLIENT(?) is illegal, what is the normal way to de-assert a user identity for an ABL session? 

Posted by Peter Judge on 24-Jan-2017 12:56

You don’t.  You should ALWAYS have a user asserted in the session. Always.
 
Create a low-privilege user and assert it in the appserver (session) startup, before you do almost anything else.
In activate, you assert the incoming request’s user and do the work
In deactivate, you assert the low-privilege user.
 
 

All Replies

Posted by Peter Judge on 24-Jan-2017 12:56

You don’t.  You should ALWAYS have a user asserted in the session. Always.
 
Create a low-privilege user and assert it in the appserver (session) startup, before you do almost anything else.
In activate, you assert the incoming request’s user and do the work
In deactivate, you assert the low-privilege user.
 

Posted by Tim Kuehn on 24-Jan-2017 13:08

Thx!

Posted by Peter Judge on 24-Jan-2017 13:12

There’s an example of how you might do this at github.com/.../BusinessLogic .
 
The sample is a little outdated in how it gets the C-P. In a PASOE-based world I’d get the C-P from the CURRENT-REQUEST-INFO’s GetClientPrincipal() method.

Posted by Jeff Ledbetter on 24-Jan-2017 14:41

Out of curiosity, why the emphatic "always"?

Posted by Peter Judge on 24-Jan-2017 14:44

How do you know who’s done what?

Posted by Jeff Ledbetter on 24-Jan-2017 14:51

Obviously one should have a user asserted in some way when the request is made and processed. I was asking in regards to the response to Tim's question of clearing the identity after the request was finished.

Posted by Mike Fechner on 24-Jan-2017 14:56

I personally consider the fact, that the ABL does not support actively losing the identity (at the end of the request) and thus restore the initial state of the AppServer session a missing feature.

We do assert a "nobody" user at the end of the request. But for me, that's just a workaround for a missing feature.

Posted by Tim Kuehn on 24-Jan-2017 15:01

^^^ That's what I as looking for..

Posted by Peter Judge on 24-Jan-2017 15:06

Same principle applies. You never want a session / avm left without a user asserted (not just during a request).
 
A null user is not quite the same – what privileges do they have ?  you also have to check for ? values instead of knowning there’s always a user – and you can have standard (one path) code that checks for authorization etc.

Posted by gus bjorklund on 24-Jan-2017 17:08

well …………

if you had this “missing feature”, how would it work, and what would the language constructs be like ?

reminder:

there is a blank user id

many applications do not use the _user table and instead have their own user table

in 11.1 +, there is a 4GL callback mechanism for user identity authentication

Posted by Simon L. Prinsloo on 24-Jan-2017 23:23

In short, it does not make sense. The default state of the AppServer is to use the blank user, which is in essence a low-privilege user. How is asserting a low-privilege user different than just reverting to the blank user? But now I must maintain a dummy user with a blank or well known password that never change in order to be able to de-assert a legal user. This leads to a lot of exceptioin-to-the-rule code around this user, where the blank user could have served the same purpose with no effort.

The biggest risk today is that, when the session fail to assert a new identity, everything will be recorded as being done by the PREVIOUS user, which breaks the principle of irrefutable auditing. I would rather know that I do not know who did something and hunt the bug than to blame the wrong user and presume the security is solid.

Posted by Mike Fechner on 24-Jan-2017 23:49

I could hardly agree more with Simon!

We still consider it a 4GL - allowing developers to focus on business tasks - and trying to simplify complexity of common tasks.

The fact that we have to distinguish 2 conditions for the same situation - no known user identity on a fresh AppServer and at the end of an AppServer request introduces complexity in one of the most critical areas of an application: security.

Posted by marian.edu on 25-Jan-2017 02:46

Well Simon,


you do remember everyone’s reaction on the ‘anonymous’ user access into an application… the quasi consensus was there always has to be an authenticated user. While this might make sense for a database (RDBMS) for an application server it’s a bit of a stretch imho and having public services in an application is not something that outrageous as it sound :)

However, I’m happy we did managed to have the session manager work with a simple session identifier and that the client-principal is not the only prescription ;)

On the other hand, if the session fails to assert the identity of the user making the request and ‘anonymous’ access is not allowed then it’s our job to deny the access… it doesn’t really matter much that in between requests the previous user identity is maintained, nothing really happens there while the agent sits idle. Bref, I don’t mind having to reset the user - context switching it is done on each request anyway and I can happily ignore the client-principal set by the appsrv into the session system handle and roll my own thing when not happy with the prescribed solution.

Cheers,

Marian Edu

Acorn IT 
+40 740 036 212

Posted by Tim Kuehn on 25-Jan-2017 07:58

[quote user="Simon L. Prinsloo"]In short, it does not make sense. The default state of the AppServer is to use the blank user, which is in essence a low-privilege user. How is asserting a low-privilege user different than just reverting to the blank user? But now I must maintain a dummy user with a blank or well known password that never change in order to be able to de-assert a legal user. [/quote]

I'm thinking a single user ID with a GUID-based password in a client-principal would do the job. 

[quote user="Simon L. Prinsloo"]The biggest risk today is that, when the session fail to assert a new identity, everything will be recorded as being done by the PREVIOUS user, which breaks the principle of irrefutable auditing. I would rather know that I do not know who did something and hunt the bug than to blame the wrong user and presume the security is solid.[/quote]

If you put assert code in the activate event code, deassert code in the deactivate program block, and error checking to ensure that the current call's user Id's been asserted - how can that happen?

Posted by Peter Judge on 25-Jan-2017 08:23

> In short, it does not make sense. The default state of the AppServer is to use the blank user, which is in essence a low-privilege user. How is asserting a low-privilege user different than just
> reverting to the blank user? But now I must maintain a dummy user with a blank or well known password that never change in order to be able to de-assert a legal user. This leads to a lot of
> exceptioin-to-the-rule code around this user, where the blank user could have served the same purpose with no effort.

You can have a sealed CP stored on disk; you don’t need add a user. The nobody@ user can have a domain that’s simply _EXTSSO which means that the AVM will just check the seal and expiration. No need to a user (and you should really never store user accounts in application/business databases).

 

> The biggest risk today is that, when the session fail to assert a new identity, everything will be recorded as being done by the PREVIOUS user, which breaks the principle of irrefutable auditing. I
> would rather know that I do not know who did something and hunt the bug than to blame the wrong user and presume the security is solid.

If this scenario happens and the wrong/PREVIOUS user is nobody@ they have no permissions to do anything and the authorization system will deny them access and log that (probably). Then mike@ will be annoyed since he could not do his work and will contact tech support and complain.

 

> The fact that we have to distinguish 2 conditions for the same situation - no known user identity on a fresh AppServer and at the end of an
> AppServer request introduces complexity in one of the most critical areas of an application: security.

Maybe I misunderstand you but this is exactly my point.

If you always have an asserted user (mike@ or peter@ or nobody@ ) you code will always get a CP, check roles etc. For nobody@, the roles happen to be <blank> , but the code doing the check doesn’t care who the user is, just that they have or don’t have certain roles at a certain point in the application. If a CP is unavailable then there’s a fatal/stop condition in the app/server.

If you have mike@ and peter@ and nothing else then the code needs to check whether a CP exists and if so check roles etc. if not, then the roles are in code (not configuration) and you cannot know when your system is in a bad state.

 

Posted by Peter Judge on 25-Jan-2017 08:26

I think this conversion is more around how to work with a tokenized user (ie CP) rather than how we know which user (session-id or b64-encoded-cp or something else).
 
You should really use the CP as a user token in ABL.

Posted by Jeff Ledbetter on 25-Jan-2017 13:39

Progress-folks like to say this:

"..(and you should really never store user accounts in application/business databases)."

But, I've never a good explanation for why that is.

What *is* the purpose of the _user table if it is not for users?

I am far from being a security expert so please excuse my elementary-level understanding.

Posted by Tim Kuehn on 25-Jan-2017 13:55

Here's some samples lines from my .lg

[2017/01/25@14:22:11.570-0500] P-1004       T-7344  I APPSRV  8: (452)   Login by SYSTEM on batch.

[2017/01/25@14:22:11.578-0500] P-1004       T-7344  I APPSRV  8: (7129)  Usr 8 set name to .

[2017/01/25@14:22:11.606-0500] P-1004       T-7344  I APPSRV  8: (7129)  Usr 8 set name to restricted.

who/what/how is this name set to ""?

"restricted" is code I've got running.

Posted by Tim Kuehn on 25-Jan-2017 13:57

"..(and you should really never store user accounts in application/business databases)." -

I expect security since any code in the app can get to them. Ditto for D&L, etc.

The usual suggestion is to store that info on a secure, separate server and make calls that server to handle identity & authentication stuff. 

Posted by Peter Judge on 25-Jan-2017 14:04

“user accounts” can be stored in _User or one of your own db tables. The principal remains the same regardless: if the  user accounts and the business data are in the same DB and if that db is stolen/hacked then an attacker has the keys (users) and the valuables (data) all together. People are generally bad at storing passwords so there’s a real risk of losing your data. If the user accounts are held separate from the data then the attacker only has part of what they need.
 
It’s also a good separation of responsibilities to keep  the user accounts separate from the business data IMO.
 
The _user table is something like 30 years old. Times and recommended practices change; that taken together with keeping things from not breaking is at least (partly) why it still exists in the OE db.
 
 

Posted by Jeff Ledbetter on 25-Jan-2017 14:30

".. People are generally bad at storing passwords so there’s a real risk of losing your data. If the user accounts are held separate from the data then the attacker only has part of what they need."

"It’s also a good separation of responsibilities to keep  the user accounts separate from the business data IMO"

Okay, those makes sense.

We have never been able to successfully implement the CLIENT-PRINCIPAL object nor quite grasp the intricacies outlined in the 'Identity Management' guide, so my opinion is probably worthless on this subject (and most other subjects). :)

Posted by ske on 26-Jan-2017 00:22

Wouldn't one difference between being able to clear the user or setting a low-privilege user, be that clearing the user should be an operation that never can fail? What do you do if setting the low-privilege user fails, for whatever strange reason...?

Posted by Mike Fechner on 26-Jan-2017 00:28

Very good point!

Sent from Nine

Von: ske <bounce-ske@community.progress.com>
Gesendet: 26.01.2017 7:23 vorm.
An: TU.OE.Development@community.progress.com
Betreff: RE: [Technical Users - OE Development] How to clear an Appserver identity

Update from Progress Community
ske

Wouldn't one difference between being able to clear the user or setting a low-privilege user, be that clearing the user should be an operation that never can fail? What do you do if setting the low-privilege user fails, for whatever strange reason...?

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

Posted by Simon L. Prinsloo on 26-Jan-2017 02:49

That is exactly my point. I've seen cases in the current model where When setting the low-privilege user fails for any reason, the previous higher privilege user remains in effect. If the next call fail so set a user, auditing will then record everything as if it was done by the previous user. Which auditor will be happy with that?

Progress says the audit trail is irrefutable, but it is not. Even a minor glitch in your handling of the security will result in blaming the wrong user.

I would rather see a clearly defective audit trail of unauthenticated/unknown users doing things, which alerts me to the fact that I have a problem, than having an apparent perfect audit trail which actually blames the wrong users with no proof of the defect.

After all, the blank user / any user in an invalid state should have no privileges beyond what is needed to get authenticated in any case, but that is up to the application/framework programmer and prone to defects that you really want to be able to detect early and with ease.

Posted by Tim Kuehn on 26-Jan-2017 11:07

Is this an issue that can happen with an appserver? I would think the activate / deactivate triggers would catch any contingencies that could happen.

This thread is closed