@@ -37,10 +37,9 @@ class GitHubHook
3737 private $ _branches = array ();
3838
3939 /**
40- * @var array GitHub's IP addresses for hooks.
41- * @since 1.1
40+ * @var array GitHub's public IP addresses for hooks (CIDR notation).
4241 */
43- private $ _ips = array ('54.235.183.49 ' , '54.235.183.23 ' , '54.235.118.251 ' , '54.235.120.57 ' , '54.235.120.61 ' , '54.235.120.62 ' );
42+ private $ _github_public_cidrs = array ('207.97.227.253/32 ' , '50.57.128.197/32 ' , '108.171.174.178/32 ' , '50.57.231.61/32 ' , '204.232.175.64/27 ' , '192.30.252.0/22 ' );
4443
4544 /**
4645 * Constructor.
@@ -79,6 +78,39 @@ private function _notFound($reason = NULL) {
7978 exit ;
8079 }
8180
81+ /**
82+ * IP in CIDRs Match - checks whether an IP exists within an array of CIDR ranges.
83+ * @link - http://stackoverflow.com/questions/10243594/find-whether-a-given-ip-exists-in-cidr-or-not?lq=1
84+ * @param string $ip - IP address in '127.0.0.1' format
85+ * @param array $cidrs - array storing CIDRS in 192.168.1.20/27 format.
86+ * @return bool
87+ */
88+ private function ip_in_cidrs ($ ip , $ cidrs ) {
89+ $ ipu = explode ('. ' , $ ip );
90+
91+ foreach ($ ipu as &$ v ) {
92+ $ v = str_pad (decbin ($ v ), 8 , '0 ' , STR_PAD_LEFT );
93+ }
94+
95+ $ ipu = join ('' , $ ipu );
96+ $ result = FALSE ;
97+
98+ foreach ($ cidrs as $ cidr ) {
99+ $ parts = explode ('/ ' , $ cidr );
100+ $ ipc = explode ('. ' , $ parts [0 ]);
101+
102+ foreach ($ ipc as &$ v ) $ v = str_pad (decbin ($ v ), 8 , '0 ' , STR_PAD_LEFT ); {
103+ $ ipc = substr (join ('' , $ ipc ), 0 , $ parts [1 ]);
104+ $ ipux = substr ($ ipu , 0 , $ parts [1 ]);
105+ $ result = ($ ipc === $ ipux );
106+ }
107+
108+ if ($ result ) break ;
109+ }
110+
111+ return $ result ;
112+ }
113+
82114 /**
83115 * Enable log of debug messages.
84116 * @since 1.0
@@ -120,7 +152,8 @@ public function log($message) {
120152 * @since 1.0
121153 */
122154 public function deploy () {
123- if (in_array ($ this ->_remoteIp , $ this ->_ips )) {
155+ // Check the remote is a whitelisted GitHub public ip.
156+ if ($ this ->ip_in_cidrs ($ this ->_remote_ip , $ this ->_github_public_cidrs )) {
124157 foreach ($ this ->_branches as $ branch ) {
125158 if ($ this ->_payload ->ref == 'refs/heads/ ' . $ branch ['name ' ]) {
126159
@@ -129,6 +162,7 @@ public function deploy() {
129162 }
130163 }
131164 } else {
165+ // IP of remote is invalid.
132166 $ this ->_notFound ('IP address not recognized: ' . $ this ->_remoteIp );
133167 }
134168 }
0 commit comments