As you know, there are some security functions in WebSphere MQ that require an exit. By now everyone should be familiar with BlockIP2, the well known channel security exit. But there are a couple of other requirements that a channel exit can’t meet. In this post I’ll describe what those are and post some specs for an exit. I’m not qualified to write an exit but I’m hoping someone who is will do so. If ever these exits show up on the Internet, you can bet I’ll be posting links to them from my site and referring people to them in presentations…well for at least as long as IBM doesn’t have a solution that I can point to, anyway.
WebSphere MQ clusters are supposed to reduce the administrative burden in medium and larger networks. They do this by automagically defining channels between any two nodes in the cluster. If you take security out of the equation, then this does indeed save a lot of administrative overhead. roblem is, you don’t get the same granularity that you do with a point-to-point network.
With point-to-point you have the option to put a different MCAUSER on every channel. The granularity of your security model can be per-node or, if you define multiple channels between nodes, per channel. With WMQ clusters you get a single CLUSRCVR channel per cluster. If you want to get more granularity you need…you gueesed it…a security exit that can dynamically set the MCAUSER based on IP address or certificate distinguished name.
“But wait”, I hear you saying, “BlockIP2 does all that.”
True. But now the question is how do you get BlockIP2 into the SCYEXIT field of the CLUSRCVR? Imagine for a moment that your nework contains a mix of Windows, UNIX and z/OS queue managers. When you set the SCYEXIT field on the CLUSRCVR of a UNIX queue manager, it looks something like this:
Now when the CLUSRCVR definition gets propagated out into the cluster, all the CLUSSDR channels pointing to this QMgr inherit the setting. If they happen to be UNIX queue managers, no problem. Assuming the exit is present in the same location, anyway. But the CLUSSDR channels on the Windows and z/OS queue managers cannot possibly work because the path is specific to UNIX.
To address this problem requires a Channel Auto-Definition (a.k.a. CHAD) exit. The purpose of a CHAD exit is to enable some control over what happens when channels are auto-defined. In the case of WMQ clusters, the CHAD exit is driven when the channel is first defined and then again every time the channel starts up. For our purposes, the interesting functionality would be using the CHAD exit to populate the channel’s SCYEXIT and SCYDATA fields. This way we can leave SCYEXIT blank so that it won’t propagate out into the cluster, but still enjoy the benefit of having a security exit on the CLUSRCVR channel.
My specs for a CHAD exit are thus:
- The exit must be capable of populating, at a minimum, the SCYEXIT and SCYDATA fields of a channel. MSGEXIT/DATA and SND/RCVEXIT/DATA would be useful as well, although not essential at this point.
- The exit must be capable of distinguishing at least between channel types. We probably want to suppress auto-defined SVRCONN and RCVR channels.
- The exit parameters must have per-channel granularity. We may want to apply different settings to different CLUSRCVR channels.
- The exit should allow default settings and string-matching on channel names. Any channel not explicitly matching a named string inherits the defaults.
- The exit should allow setting of additional fields: SSLCIPH, SSLCAUTH, SSLPEER, MAXMSGL, MCAUSER, and possibly others. (Comments anyone?)
- The exit should allow specification of a file or namelist to store parameters. It needs to support different files per QMgr when there are multiple QMgrs on a server.
The second exit addresses a problem that is common in appplications that use WebSphere MQ, specifically that they generally do not check the message type before processing the message. The reason that this is a problem is the ability of a message producer to request confirmation on arrival. When COA is requested, the queue manager sends the report message to the queue specified in the Reply-To fields of the original message. The requestor can specify that the generated report message contain a copy of the entire original message. In the case of COA, the report message is enqueued with the authority of the queue manager.
As an attacker, what this means to me is that I do not need authorization to a queue in order to put a message onto it. All I need is a channel to your queue manager. I then specify COA on my malicious message and specify the desired target queue in the Reply-To fields. The queue doesn’t even need to be on the queue manager that I have access to since I can address it to routable network destination.
Of course, IBM’s advice in the Application Programmer’s Manual all along has been to check the Message Type field before processing any message. Typically, it should be either a request, a reply or a datagram. The problem is that not too many applications bothered to do this basic validation. Worse, many JMS shops consider this validation to be vendor-specific. In truth, it is possible to write the validation in portable code but the property itself is specific to WebSphere MQ so it is not often checked. The result is that many applications are vulnerable to this spoofing attack.
With so many applications vulnerable, at this point the best way to address the issue is probably with a message exit. My specifications for a messsage exit are these:
- Optionally turn off COA on messages arriving over the channel.
- Optionally turn off COD on messages arriving over the channel.
- Optionally move MCAUSER to the MQMD.UserID
- Optionally move an arbitrary parameterized string to MQMD.UserID
- Optionally set MQMD.ReplyToQMgr to the name of the QMgr running the exit.
- Optionally set MQMD.ReplyToQMgr to an arbitrary parameterized string.
- Optionally set MQMD.ReplyToQueue to an arbitrary parameterized string.
- Optionally set MQMD.ReplyToQueue by mapping the destination queue to a parameterized string.
- Options determining disposition of messages not addressed to valid queue:
- Move to DLQ (with DLQ header)
- Move to queue specified by parameter
- Reject and force channel to stop
- Options determining notification method
- Write to exit log file
- Write to event queue
- Write to AMQERR01.LOG
- Combination of the above
Note that a message exit does NOT solve all of the problems with vulnerable applications. For one thing, there is no message exit for WMQ client channels. The implication is that any client connection allows the ability to put COA messages onto any queue.
As of this writing, I don’t know of any free or commercial CHAD exit for WebSphere MQ. Similarly, I don’t know of any message exits that have the functionality I’m looking for regarding confirmation messages. My intent here is to at least hoist up a straw man for discussion. As I stated up front, I’m not qualified to write the C code myself. But I’d be happy to host it here if someone else wants to write it.