Jump to content

Obsolete:Fundraising/tech/Spikes/Fundraiser 2012 412

From Wikitech
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
This page contains historical information. It may be outdated or unreliable.
2012

Fundraising 2012 spike #412

See the spike #412 in mingle.

We have need of an IPA velocity filter for DonationInterface.

The AbuseFilter extension handles IP ranges; however, the tool they are using is Mediawiki's IP class.

As it turns it may not need very mush special code as this will just be doing a count from a database to obtain a rate from a time interval.

Requirements

  • define a limit of transactions per time interval for repeat IPAs
  • it would be helpful if a risk score was saved with each record
  • it might need the contribution tracking id
  • whitelist, blacklist and rate editable in LocalSettings
  • DO NOT VIOLATE PCI COMPLIANCE with storing to much information :)

Schema changes

This would require a table that would have the following fields:

  • `id` INTEGER
  • `ipa` INTEGER 4 bytes
  • `risk_score` DOUBLE
  • `contribution_tracking_id`
  • `created` DATETIME

It might be helpful to have built in garbage collection that deletes data after a specified lifetime.

This would prevent the table from growing to large over the course of a campaign.

Example as a filter function

This is an example of how to run an IP velocity filter as a custom filter function.

/**
 * This custom filter function checks the global variable:
 *
 * IpaMap
 *
 * How the score is tabulated:
 *  - If a IPA is blacklisted, a score of 100 will be generated. No further checks.
 *  - If a IPA is whitelisted, a score of zero will be generated. No further checks.
 *  - If a limit is defined, then count the occurences and generate a score.
 *  - Returns an integer: 0 <= $score <= 100
 *
 * @see GatewayAdapter::$debugarray
 * @see GatewayAdapter::log()
 *
 * @see $wgDonationInterfaceCustomFiltersFunctions
 * @see $wgDonationInterfaceIpaMap
 *
 * @return integer
 */
public function getScoreIpaMap() {

	// The score to return
	$score = 0;
	
	// Perform a check to generate a score
	$check = true;

	$ipa = wfGetIP();

	$ipaMap = $this->getGlobal( 'IpaMap' );

	$msg = self::getGatewayName() . ': IPA map: '
		. print_r( $ipaMap, true );

	$this->log( $msg, LOG_DEBUG );

	// Lookup blacklist
	if ( $check && isset( $ipaMap['blacklist'] ) ) {

		if ( in_array( $ipa, $ipaMap['blacklist'] ) ) {
			$score = 100;
			$check = false;
		}
	}
	
	// Lookup whitelist
	if ( $check && isset( $ipaMap['whitelist'] ) ) {

		if ( in_array( $ipa, $ipaMap['whitelist'] ) ) {
			$score = 0;
			$check = false;
		}
	}
	
	// Lookup the IPA in the database and calculate the score.
	if ( $check ) {

		$score = $this->getIpaCountScore( $ipa, $ipaMap );
	}

	// Save the IPA in the database
	$this->recordIpa( $ipa );

	// @see $wgDonationInterfaceDisplayDebug
	$this->debugarray[] = 'custom filters function: get ipa [ '
		. $ipa . ' ] map score = ' . $score;

	return $score;
}

Filtering by cidr notation

It might be helpful to whitelist or blacklist countries by cidr notation using the IP class

IP::isInRange( $ipa, '192.0.2.0/24')

Implementing this as a firewall

It is also possible to put this higher up in the stack to prevent a form from being displayed due to repeat attacks by the same IPA.