Skip to content

Instantly share code, notes, and snippets.

@AmarOk1412
Created February 13, 2019 14:43
Show Gist options
  • Save AmarOk1412/96d769f71635816055ca759748373d26 to your computer and use it in GitHub Desktop.
Save AmarOk1412/96d769f71635816055ca759748373d26 to your computer and use it in GitHub Desktop.
src/redis.c | 23 +++++++++++++++++++++++
src/redis.h | 1 +
2 files changed, 24 insertions(+)
diff --git a/src/redis.c b/src/redis.c
index 6fdc2f6..1ae1b8b 100644
--- a/src/redis.c
+++ b/src/redis.c
@@ -273,6 +273,8 @@ struct redisCommand redisCommandTable[] = {
{"pfcount",pfcountCommand,-2,"w",0,NULL,1,1,1,0,0},
{"pfmerge",pfmergeCommand,-2,"wm",0,NULL,1,-1,1,0,0},
{"pfdebug",pfdebugCommand,-3,"w",0,NULL,0,0,0,0,0},
+ {"post",securityWarningCommand,-1,"lt",0,NULL,0,0,0,0,0},
+ {"host:",securityWarningCommand,-1,"lt",0,NULL,0,0,0,0,0},
{"latency",latencyCommand,-2,"arslt",0,NULL,0,0,0,0,0}
};
@@ -2375,6 +2377,27 @@ void commandCommand(redisClient *c) {
}
}
+/* This callback is bound to POST and "Host:" command names. Those are not
+ * really commands, but are used in security attacks in order to talk to
+ * Redis instances via HTTP, with a technique called "cross protocol scripting"
+ * which exploits the fact that services like Redis will discard invalid
+ * HTTP headers and will process what follows.
+ *
+ * As a protection against this attack, Redis will terminate the connection
+ * when a POST or "Host:" header is seen, and will log the event from
+ * time to time (to avoid creating a DOS as a result of too many logs). */
+void securityWarningCommand(redisClient *c) {
+ static time_t logged_time;
+ time_t now = time(NULL);
+
+ if (labs(now-logged_time) > 60) {
+ redisLog(REDIS_WARNING,"Possible SECURITY ATTACK detected. It looks like somebody is sending POST or Host: commands to Redis. This is likely due to an attacker attempting to use Cross Protocol Scripting to compromise your Redis instance. Connection aborted.");
+ logged_time = now;
+ }
+ c->flags |= REDIS_CLOSE_AFTER_REPLY;
+ addReply(c,createStringObject("",0));
+}
+
/* Convert an amount of bytes into a human readable string in the form
* of 100B, 2G, 100M, 4K, and so forth. */
void bytesToHuman(char *s, unsigned long long n) {
diff --git a/src/redis.h b/src/redis.h
index 8507edc..16c545c 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -1250,6 +1250,7 @@ void authCommand(redisClient *c);
void pingCommand(redisClient *c);
void echoCommand(redisClient *c);
void commandCommand(redisClient *c);
+void securityWarningCommand(redisClient *c);
void setCommand(redisClient *c);
void setnxCommand(redisClient *c);
void setexCommand(redisClient *c);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment