29
29
*/
30
30
]);
31
31
define ('API_ENCRYPTION_KEY ' , 'For TUJ Use Only ' );
32
+ define ('POISONED_IS_BANNED ' , false );
33
+ define ('POISON_CACHE_KEY ' , 'poisoned ' );
34
+ define ('POISON_COOKIE_NAME ' , 'koala ' );
35
+ define ('POISON_DURATION ' , 24 * 60 * 60 );
36
+ define ('POISON_LOG_PATH ' , __DIR__ . '/../logs/poison.log ' );
32
37
33
38
if ((PHP_SAPI != 'cli ' ) && (($ inMaintenance = APIMaintenance ()) !== false )) {
34
39
header ('HTTP/1.1 503 Service Unavailable ' );
@@ -578,6 +583,7 @@ function BotCheck($returnReason = false)
578
583
$ checked = $ _SERVER ['REMOTE_ADDR ' ];
579
584
$ reason = '' ;
580
585
$ banned = IPIsBanned ($ checked , $ reason );
586
+ $ poisoned = PoisonCheck ($ checked );
581
587
582
588
if (isset ($ _SERVER ['HTTP_X_FORWARDED_FOR ' ])) {
583
589
$ filterOpts = array (
@@ -592,10 +598,17 @@ function BotCheck($returnReason = false)
592
598
while (count ($ otherIPs ) && !$ banned ) {
593
599
if ($ otherIP = filter_var (trim (array_shift ($ otherIPs )), FILTER_VALIDATE_IP , $ filterOpts )) {
594
600
$ banned |= IPIsBanned ($ checked = $ otherIP , $ reason );
601
+ $ otherPoisoned = PoisonCheck ($ otherIP );
602
+ $ poisoned = $ poisoned || $ otherPoisoned ;
595
603
}
596
604
}
597
605
}
598
606
607
+ if (POISONED_IS_BANNED && !$ banned && $ poisoned ) {
608
+ $ banned = true ;
609
+ $ reason = 'ip ' ;
610
+ }
611
+
599
612
if ($ returnReason ) {
600
613
return [
601
614
'isbanned ' => $ banned ,
@@ -781,6 +794,61 @@ function IPIsBanned($ip = false, &$result = '')
781
794
return !!$ result ;
782
795
}
783
796
797
+ /**
798
+ * Returns true when the given IP from the current request is poisoned. May emit cookie headers.
799
+ *
800
+ * @param string $ip
801
+ * @return bool
802
+ */
803
+ function PoisonCheck ($ ip ) {
804
+ $ cacheKey = POISON_CACHE_KEY . "_ {$ ip }" ;
805
+
806
+ $ poisonedVia = MCGet ($ cacheKey );
807
+ // Have we flagged this IP as poisoned internally?
808
+ if ($ poisonedVia === false ) {
809
+ // We haven't. Does it think that it's poisoned?
810
+ if (isset ($ _COOKIE [POISON_COOKIE_NAME ])) {
811
+ // It says it is poisoned. Flag it on our end.
812
+ FlagAsPoisoned ($ ip , true , $ poisonedVia = substr ($ _COOKIE [POISON_COOKIE_NAME ], 0 , 80 ));
813
+ }
814
+ }
815
+
816
+ if ($ poisonedVia ) {
817
+ setcookie (POISON_COOKIE_NAME , $ poisonedVia , time () + POISON_DURATION , '/api/ ' , '' , true , true );
818
+ }
819
+
820
+ return !!$ poisonedVia ;
821
+ }
822
+
823
+ /**
824
+ * Flags an IP as poisoned (or not), and logs it.
825
+ *
826
+ * @param string $ip
827
+ * @param bool $isPoisoned
828
+ * @param string $fromIp
829
+ */
830
+ function FlagAsPoisoned ($ ip , $ isPoisoned , $ fromIp = '' ) {
831
+ $ cacheKey = POISON_CACHE_KEY . "_ {$ ip }" ;
832
+
833
+ if ($ isPoisoned ) {
834
+ MCSet ($ cacheKey , $ fromIp ?: $ ip , POISON_DURATION );
835
+ } else {
836
+ MCDelete ($ cacheKey );
837
+ }
838
+
839
+ file_put_contents (
840
+ POISON_LOG_PATH ,
841
+ sprintf (
842
+ "%s # %s Flagged as %spoisoned via %s \n" ,
843
+ $ ip ,
844
+ date ('Y-m-d H:i:s ' ),
845
+ $ isPoisoned ? '' : 'NOT ' ,
846
+ $ fromIp ?: '? '
847
+ ),
848
+ FILE_APPEND | LOCK_EX
849
+ );
850
+ }
851
+
784
852
function CaptchaDetails ()
785
853
{
786
854
global $ db ;
0 commit comments