On 13.07.2026 15:43, Jean Louis Faucher wrote:
On 13 Jul 2026, at 13:10, Rony G. Flatscher <[email protected]> wrote:
A few thoughts about the security manager: it exists to allow for supervising running Rexx
programs. There are sensible instructions/actions in the language that could be exploited in a
malevolent manner; one can mitigate this by appointing a security manager to determine how to
handle them.
Sensible instructions/actions are calls to external routines or commands, access to
stream-related built-in functions (charin, charout, chars, linein, lineout, lines, stream),
requiring (calling) packages/programs, access to any protected method, and access to the
environment directories .local and .environment.
All of this has been working in ooRexx since its existence; ooRexx 5.0.0 broke the supervision of
static requires directives, and it still does not work, which makes the whole concept of a
security manager moot, it seems.
Looking at the security manager-related APIs, there are three classes that possess a
setSecurityManager method: .routine, .package, and .method. How about adding an optional new
trailing "securityManager" argument to their constructors? Supplying it would cause the
supervision messages (CALL, COMMAND, STREAM, METHOD, REQUIRES, LOCAL, ENVIRONMENT) to be sent to
the supplied security manager. Could that mitigate the situation regarding REQUIRES?
I don't know.
Months ago, I worked on this, but I've forgotten most of the details.
https://sourceforge.net/p/oorexx/mailman/oorexx-devel/thread/c728c239-9ac8-494c-b85d-5a38abe5ed31%40wu.ac.at/#msg59259308
I remember that a security manager at the interpreter level catches the
::requires.
+1 +1 +1
https://sourceforge.net/p/oorexx/patches/223/
That was a WIP, was interruped because of a recursion problem with a BSF test
case.
And that would probably reduce performance because all security checkpoints would be triggered
everywhere.
What would be your assessment in the light of your patch v3? Would the
recursion problem be solvable?
In principle being able to set a security manager (temporarily) for an ooRexx instance may be very
helpful in certain use-cases (e.g., to get statistics about security checkpoints triggered by an
application with all its constituents; to get coarse profiling data, etc.), and performance then
might not be a critical factor for such use cases at all.
I would be very much in favor of getting this WIP into production as its considerable value for
developing and testing professional ooRexx applications!
---
Still, I wonder whether it would be become possible again for routine, method and package "code
blocks" to get the REQUIRES security checkpoint to be triggered for them?
Even if a solution is not backwardly compatible (like the idea with supplying an optional security
manager argument when creating routines, methods and packages; or allowing to set a default security
manager at the class level of .routine, .method, .package that would be used at creation time; ...).
---
Another concern is that the setSecurityManager method is not protected. This allows a code block
(from a routine, method, or package) to use it to set/change, or remove a security manager.
Well, they are protected (P in col 7).
ooRexx[sh]> ?m setSecurityManager
P. P.GP. 'SETSECURITYMANAGER' : 'Method' (REXX)
P. P.GP. 'SETSECURITYMANAGER' : 'Package' (REXX)
P. P.GP. 'SETSECURITYMANAGER' : 'Routine' (REXX)
Yes, you are right, sorry!
Missed the respective METHOD check points in the (locally overwhelming) debug output, very sorry for
the noise!
---
When experimenting with this ability (to change the security manager from within the supervised
code block), the following observations were taken:
* the security manager of the supervised code block wil get the supervise
messages CALL,
COMMAND, STREAM, METHOD, REQUIRES (for dynamic requires only!), LOCAL,
ENVIRONMENT
* removing the security manager of the supervised code block by sending
".context~executable~setSecurityManager": this affects the supervise
messages CALL, COMMAND,
LOCAL, ENVIRONMENT, and STREAM, which do not get sent anymore. However, the
supervise
messages METHOD, REQUIRES still get sent to the originally set security
manager, which seems
to be a bug
* adding a new security manager to the code block by
sending ".context~executable~setSecurityManager(.allowAll~new)": this
affects the supervise
messages CALL, COMMAND, LOCAL, ENVIRONMENT, which get sent to the new
security manager.
However, the supervise message STREAM does not get sent to it; the
supervise messages METHOD,
REQUIRES still get sent to the originally set security manager, which seems
to be a bug
So something is wrong when changing the security managers for code blocks depending on the
supervise messages:
* the original security manager for the supervise messages METHOD, REQUIRES
does not get changed
* the supervise message STREAM, once the security manager got removed, does
not get
re-established to a newly set security manager
---
It is interesting to note, and potentially a bug, that accessing some environment symbols are not
supervised (neither the LOCAL nor the ENVIRONMENT supervise message gets sent), e.g. .Object, .true
I think that .True is no longer an environment symbol.
According to "1.13.6. Environment Symbols" (documenting short-circuits introduced with 5.0 if
recalling correctly), and "Chapter 6. Rexx Runtime Objects" .True is an environment symbol.
Here the full list of the entries in .local and .environment:
C:\Users\Administrator>rexxtry
REXX-ooRexx_5.2.0(MT)_64-bit 6.06 18 Apr 2026
rexxtry.rex lets you interactively try REXX statements.
Each string is executed when you hit Enter.
Enter 'call tell' for a description of the features.
Go on - try a few... Enter 'exit' to end.
call rgf_util2
........................................... rexxtry.rex on WindowsNT
call dump2 .local
type: The Directory class: (10 items)
# 1: index=[DEBUGINPUT] -> item=[The DEBUG INPUT monitor
id#_FFFFFE07_31C09E2F]
# 2: index=[ERROR] -> item=[The ERROR monitor
id#_FFFFFE07_31C0854F]
# 3: index=[INPUT] -> item=[The INPUT monitor
id#_FFFFFE07_31C10CCF]
# 4: index=[OUTPUT] -> item=[The OUTPUT monitor
id#_FFFFFE07_31C091BF]
# 5: index=[STDERR] -> item=[STDERR id#_FFFFFE07_31C12AAF]
# 6: index=[STDIN] -> item=[STDIN id#_FFFFFE07_31C1581F]
# 7: index=[STDOUT] -> item=[STDOUT id#_FFFFFE07_31C141BF]
# 8: index=[STDQUE] -> item=[SESSION id#_FFFFFE07_31C06C6F]
# 9: index=[SYSCARGS] -> item=[an Array (0 items)
id#_FFFFFE07_31C05FAF]
# 10: index=[TRACEOUTPUT] -> item=[The TRACE OUTPUT monitor
id#_FFFFFE07_31C078DF]
--------------------------------------------------
........................................... rexxtry.rex on WindowsNT
call dump2 .environment
type: The Directory class: (78 items)
# 1: index=[ALARM] -> item=[The Alarm class
id#_FFFFFE07_31CA9BEF]
# 2: index=[ALARMNOTIFICATION] -> item=[The
AlarmNotification class id#_FFFFFE07_31D1659F]
# 3: index=[ARGUTIL] -> item=[The ArgUtil class
id#_FFFFFE07_31C9B22F]
# 4: index=[ARRAY] -> item=[The Array class
id#_FFFFFE07_31E1199F]
# 5: index=[BAG] -> item=[The Bag class
id#_FFFFFE07_31DC003F]
# 6: index=[BUFFER] -> item=[The Buffer class
id#_FFFFFE07_31CF181F]
# 7: index=[CASELESSCOLUMNCOMPARATOR] -> item=[The
CaselessColumnComparator class id#_FFFFFE07_31CB023F]
# 8: index=[CASELESSCOMPARATOR] -> item=[The
CaselessComparator class id#_FFFFFE07_31CC4AAF]
# 9: index=[CASELESSDESCENDINGCOMPARATOR] -> item=[The
CaselessDescendingComparator class id#_FFFFFE07_31CC0AFF]
# 10: index=[CIRCULARQUEUE] -> item=[The CircularQueue
class id#_FFFFFE07_31D9AB9F]
# 11: index=[CLASS] -> item=[The Class class
id#_FFFFFE07_31E475BF]
# 12: index=[COLLECTION] -> item=[The Collection
class id#_FFFFFE07_31E113EF]
# 13: index=[COLUMNCOMPARATOR] -> item=[The
ColumnComparator class id#_FFFFFE07_31CBCAFF]
# 14: index=[COMPARABLE] -> item=[The Comparable
class id#_FFFFFE07_31E44A3F]
# 15: index=[COMPARATOR] -> item=[The Comparator
class id#_FFFFFE07_31CCA69F]
# 16: index=[DATETIME] -> item=[The DateTime class
id#_FFFFFE07_31E3F90F]
# 17: index=[DESCENDINGCOMPARATOR] -> item=[The
DescendingComparator class id#_FFFFFE07_31CC8CFF]
# 18: index=[DIRECTORY] -> item=[The Directory class
id#_FFFFFE07_31DD92CF]
# 19: index=[ENDOFLINE] -> item=["0D0A"x]
# 20: index=[ENVIRONMENT] -> item=[The Environment
Directory (78 items) id#_FFFFFE07_31E47EBF]
# 21: index=[EVENTSEMAPHORE] -> item=[The EventSemaphore
class id#_FFFFFE07_31CF994F]
# 22: index=[FALSE] -> item=[0]
# 23: index=[FILE] -> item=[The File class
id#_FFFFFE07_31E1967F]
# 24: index=[IDENTITYTABLE] -> item=[The IdentityTable
class id#_FFFFFE07_31DFAADF]
# 25: index=[INPUTOUTPUTSTREAM] -> item=[The
InputOutputStream class id#_FFFFFE07_31E161AF]
# 26: index=[INPUTSTREAM] -> item=[The InputStream
class id#_FFFFFE07_31E14A9F]
# 27: index=[INVERTINGCOMPARATOR] -> item=[The
InvertingComparator class id#_FFFFFE07_31CB884F]
# 28: index=[LIST] -> item=[The List class
id#_FFFFFE07_31E0FB9F]
# 29: index=[LOCAL] -> item=[The Local Directory
(10 items) id#_FFFFFE07_31C0D2AF]
# 30: index=[MAPCOLLECTION] -> item=[The MapCollection
class id#_FFFFFE07_31DFDD7F]
# 31: index=[MESSAGE] -> item=[The Message class
id#_FFFFFE07_31D16A0F]
# 32: index=[MESSAGENOTIFICATION] -> item=[The
MessageNotification class id#_FFFFFE07_31D1662F]
# 33: index=[METHOD] -> item=[The Method class
id#_FFFFFE07_31DE3FAF]
# 34: index=[MONITOR] -> item=[The Monitor class
id#_FFFFFE07_31CD7FBF]
# 35: index=[MUTABLEBUFFER] -> item=[The MutableBuffer
class id#_FFFFFE07_31DEF44F]
# 36: index=[MUTEXSEMAPHORE] -> item=[The MutexSemaphore
class id#_FFFFFE07_31CF6D6F]
# 37: index=[NIL] -> item=[The NIL object
id#_FFFFFE07_31E475EF]
# 38: index=[NUMERICCOMPARATOR] -> item=[The
NumericComparator class id#_FFFFFE07_31CB45EF]
*# 39: index=[OBJECT] -> item=[The Object class id#_FFFFFE07_31E4647F]*
# 40: index=[OLEOBJECT] -> item=[The OLEObject class
id#_FFFFFE07_31C92F4F]
# 41: index=[OLEVARIANT] -> item=[The OLEVariant
class id#_FFFFFE07_31C8A31F]
# 42: index=[ORDERABLE] -> item=[The Orderable class
id#_FFFFFE07_31E3E3FF]
# 43: index=[ORDEREDCOLLECTION] -> item=[The
OrderedCollection class id#_FFFFFE07_31E115BF]
# 44: index=[OUTPUTSTREAM] -> item=[The OutputStream
class id#_FFFFFE07_31E14CEF]
# 45: index=[PACKAGE] -> item=[The Package class
id#_FFFFFE07_31D088EF]
# 46: index=[POINTER] -> item=[The Pointer class
id#_FFFFFE07_31CF434F]
# 47: index=[PROPERTIES] -> item=[The Properties
class id#_FFFFFE07_31DD8EAF]
# 48: index=[QUEUE] -> item=[The Queue class
id#_FFFFFE07_31D9AFBF]
# 49: index=[RELATION] -> item=[The Relation class
id#_FFFFFE07_31DCC1DF]
# 50: index=[REXXCONTEXT] -> item=[The RexxContext
class id#_FFFFFE07_31D0361F]
# 51: index=[REXXINFO] -> item=[a RexxInfo
id#_FFFFFE07_31C2668F]
# 52: index=[REXXQUEUE] -> item=[The RexxQueue class
id#_FFFFFE07_31CD26AF]
# 53: index=[RGF.ALPHA] ->
item=[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]
# 54: index=[RGF.ALPHA.LOW] ->
item=[abcdefghijklmnopqrstuvwxyz]
# 55: index=[RGF.ALPHA.UPPER] ->
item=[ABCDEFGHIJKLMNOPQRSTUVWXYZ]
# 56: index=[RGF.ALPHANUMERIC] ->
item=[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]
# 57: index=[RGF.DIGITS] -> item=[0123456789]
# 58: index=[RGF.NON.PRINTABLE] ->
item=["000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFF"x]
# 59: index=[RGF.SYMBOL.CHARS] -> item=[.!_?]
# 60: index=[ROUTINE] -> item=[The Routine class
id#_FFFFFE07_31D0B79F]
# 61: index=[SET] -> item=[The Set class
id#_FFFFFE07_31DC1D6F]
# 62: index=[SETCOLLECTION] -> item=[The SetCollection
class id#_FFFFFE07_31DC198F]
# 63: index=[SINGLETON] -> item=[The Singleton class
id#_FFFFFE07_31C7DEBF]
# 64: index=[STACKFRAME] -> item=[The StackFrame
class id#_FFFFFE07_31CECF9F]
# 65: index=[STEM] -> item=[The Stem class
id#_FFFFFE07_31DACF8F]
# 66: index=[STREAM] -> item=[The Stream class
id#_FFFFFE07_31E1636F]
# 67: index=[STREAMSUPPLIER] -> item=[The StreamSupplier
class id#_FFFFFE07_31E0A03F]
# 68: index=[STRING] -> item=[The String class
id#_FFFFFE07_31E44E1F]
# 69: index=[STRINGTABLE] -> item=[The StringTable
class id#_FFFFFE07_31DF3BEF]
# 70: index=[SUPPLIER] -> item=[The Supplier class
id#_FFFFFE07_31E0A45F]
# 71: index=[TABLE] -> item=[The Table class
id#_FFFFFE07_31DF6B0F]
# 72: index=[TICKER] -> item=[The TICKER class
id#_FFFFFE07_31CA14CF]
# 73: index=[TIMESPAN] -> item=[The TimeSpan class
id#_FFFFFE07_31E3C7DF]
# 74: index=[TRACEOBJECT] -> item=[The TraceObject
class id#_FFFFFE07_31DF37CF]
*# 75: index=[TRUE] -> item=[1]*
# 76: index=[VALIDATE] -> item=[The Validate class
id#_FFFFFE07_31E3A5EF]
# 77: index=[VARIABLEREFERENCE] -> item=[The
VariableReference class id#_FFFFFE07_31CFC48F]
# 78: index=[WEAKREFERENCE] -> item=[The WeakReference
class id#_FFFFFE07_31CEF84F]
--------------------------------------------------
In the short-circuit cases (.True is dubbed an "environment constant" in rexxref.pdf's "1.13.6.
Environment Symbols") and some other cases LOCAL and ENVIRONMENT do not get consulted, such that
there would be no need for a security checkpoint, as no access of .local or .environment is taking
place. This should be probably documented in the security manager chapter ("Chapter 13. The Security
Manager").
---
So there are different aspects in this context that need to be thought about,
checked and fixed.
Any thoughts about this? Any comments, ideas how to proceed from here on?
Also, how about the terminology used here (supervise messages that get sent to a security
manager), is it understandable, clearer, easier than the current documentation?
Not sure...
https://chatgpt.com/s/t_6a54e7f6c2fc8191b93392e26fcdf0f8
I tend to trust this kind of feedback, it's very helpful for me as a non-native
English speaker.
Thank you *very* much, I concur (not being a native English speaker myself), sounds much clearer
("security checkpoint"; we also should update the rexxref.pdf documentation accordingly)! The
clearer the concepts and the language, the "easier" to comprehend the concepts and how they are put
to work.
---rony
P.S.: Also terms like "code block" (I think that was the term Josep Maria suggested, but I may be
mistaken) should be defined in the documentation as they ease the communication, once the term got
defined.
_______________________________________________
Oorexx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/oorexx-devel