$ shellfirm

MySQL

Protect live MySQL sessions with shellfirm wrap

Wrapping mysql with shellfirm protects your MySQL sessions from accidental destructive queries, catching dangerous DDL and DML statements before they execute.

Usage

shellfirm wrap mysql -h prod.db.com -u root -p

This starts a normal mysql session with shellfirm checking every SQL statement.

Example session

mysql session (wrapped)
-- Safe queries work normally:
mysql> SELECT count(*) FROM users;
+----------+
| count(*) |
+----------+
| 14523 |
+----------+
-- Dangerous query is intercepted:
mysql> DROP DATABASE app_production;
============ RISKY COMMAND DETECTED ============
Severity: CRITICAL
Description: DROP DATABASE permanently deletes the database and all its tables
Alternative: mysqldump before DROP DATABASE
(Creates a backup of the database so you can restore it if needed.)
? Type yes to continue Esc to cancel ›
-- TRUNCATE is also intercepted:
mysql> TRUNCATE TABLE sessions;
============ RISKY COMMAND DETECTED ============
Severity: HIGH
Description: TRUNCATE removes all rows and cannot be rolled back
Alternative: DELETE FROM sessions WHERE 1=1
(Uses DELETE which can be rolled back inside a transaction.)
? Solve the challenge:: 6 + 9 = ? Esc to cancel ›

What gets intercepted

shellfirm checks these MySQL-specific patterns (from the mysql and database check groups):

PatternSeverityDescription
DROP DATABASECriticalPermanently deletes the entire database
DROP TABLECriticalPermanently deletes a table
TRUNCATEHighRemoves all rows (cannot be rolled back)
DELETE FROM (without WHERE)HighDeletes all rows without filtering
ALTER TABLE ... DROPMediumDrops a column
DROP INDEXMediumRemoves an index
GRANT ALLMediumGrants broad permissions

Configuration

# ~/.shellfirm/settings.yaml
wrappers:
  tools:
    mysql:
      delimiter: ";"
      check_groups:
        - mysql
        - database

Connection methods

All standard MySQL connection methods work with the wrapper:

# Standard connection
shellfirm wrap mysql -h prod.db.com -u analyst -p myapp

# Using defaults file
shellfirm wrap mysql --defaults-file=~/.my.cnf

# Using socket
shellfirm wrap mysql -S /var/run/mysqld/mysqld.sock -u root

# Connection string style
shellfirm wrap mysql --host=prod.db.com --user=root --database=myapp

Multi-line queries

Like psql, multi-line queries are buffered until the ; delimiter:

Multi-line Query Interception
mysql> DROP TABLE
-> IF EXISTS
-> users;
============ RISKY COMMAND DETECTED ============
-- shellfirm intercepts the complete statement

Team policy example

# .shellfirm.yaml
version: 1
deny:
  - "mysql:drop_database"

overrides:
  - id: "mysql:drop_table"
    challenge: Yes
  - id: "mysql:truncate"
    challenge: Yes
  - id: "database:delete_without_where"
    challenge: Yes