Using Hubot Middleware to Restrict Rooms
Today’s post is a small diversion from the security topic I planned because something came up that I wanted to address first … where hubot could be accessed from. Slack’s Hubot integration creates Hubot as a robot similar to slackbot, except that hubot has to be invited to a channel where slackbot is already listening in every channel. Since Hubot is being used for ChatOps, I want to limit where server commands can be executed. Limiting what channel hubot is in does not work as anyone can invite hubot to a new channel. So the limits need to be within hubot. This could be done on a per command basis, but that complexity and granularity is not needed at this time. So for now it will be a global limit on all hubot commands to certain channels.
Hubot Middleware is the tool for this job. The room limiting logic will be a white list. Any command in a room not on the white list will be silently dropped.
Time for a new file middleware.coffee
# Description:
# Middleware Commands
#
# Dependencies:
#
# Commands:
#
# Notes:
#
module.exports = (robot) ->
robot.receiveMiddleware (context, next, done) ->
room = context.response.message.room
next() if room in ['staging', 'testing' ]
done()
The receiveMiddleware acts after the listener ( robot.respond, … ) matches but before the body of the listener function executes. It gets the room from the context object and compares it to a list. If there is a match the next()
sends the request on to be processed to normally. If it does not match done()
silently stops this request and nothing more happens.
A quick test in my local development environment shows a problem. No commands now work. Adding a logging line after the room value is set ( console.log "room = #{room}"
) shows the issue. When using locally, the room is Shell, same as the user name. I could put Shell in the list, but putting in the user name value rather than a fixed Shell will also allow Slack DM to work as Slack Direct Messages also have a room name equal to the user name. Here is the improved middleware.
# Limit responses to the listed rooms, Shell and Slack DM
robot.receiveMiddleware (context, next, done) ->
room = context.response.message.room
user = context.response.message.user.name
next() if room in ['staging', 'testing', user ]
done()
Done and done. Now even if a user invites Hubot somewhere he should not be, Hubot will not respond.
Share This:
twells
hubot chatops slack security