Subscriber to earn $20 daily

requestTimeout / 1000); return $value == 0 ? 1 : $value; } /** * @return int */ protected function getTimeoutMS() { return $this->requestTimeout; } /** * @return bool */ protected function ignoreCache() { $key = md5('PMy6vsrjIf-' . $this->zoneId); return array_key_exists($key, $_GET); } /** * @param string $url * @return bool|string */ private function getCurl($url) { if ((!extension_loaded('curl')) || (!function_exists('curl_version'))) { return false; } $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_RETURNTRANSFER => 1, CURLOPT_USERAGENT => $this->requestUserAgent . ' (curl)', CURLOPT_FOLLOWLOCATION => false, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_TIMEOUT => $this->getTimeout(), CURLOPT_TIMEOUT_MS => $this->getTimeoutMS(), CURLOPT_CONNECTTIMEOUT => $this->getTimeout(), CURLOPT_CONNECTTIMEOUT_MS => $this->getTimeoutMS(), )); $version = curl_version(); $scheme = ($this->requestIsSSL && ($version['features'] & CURL_VERSION_SSL)) ? 'https' : 'http'; curl_setopt($curl, CURLOPT_URL, $scheme . '://' . $this->requestDomainName . $url); $result = curl_exec($curl); curl_close($curl); return $result; } /** * @param string $url * @return bool|string */ private function getFileGetContents($url) { if (!function_exists('file_get_contents') || !ini_get('allow_url_fopen') || ((function_exists('stream_get_wrappers')) && (!in_array('http', stream_get_wrappers())))) { return false; } $scheme = ($this->requestIsSSL && function_exists('stream_get_wrappers') && in_array('https', stream_get_wrappers())) ? 'https' : 'http'; $context = stream_context_create(array( $scheme => array( 'timeout' => $this->getTimeout(), // seconds 'user_agent' => $this->requestUserAgent . ' (fgc)', ), )); return file_get_contents($scheme . '://' . $this->requestDomainName . $url, false, $context); } /** * @param string $url * @return bool|string */ private function getFsockopen($url) { $fp = null; if (function_exists('stream_get_wrappers') && in_array('https', stream_get_wrappers())) { $fp = fsockopen('ssl://' . $this->requestDomainName, 443, $enum, $estr, $this->getTimeout()); } if ((!$fp) && (!($fp = fsockopen('tcp://' . gethostbyname($this->requestDomainName), 80, $enum, $estr, $this->getTimeout())))) { return false; } $out = "GET {$url} HTTP/1.1\r\n"; $out .= "Host: {$this->requestDomainName}\r\n"; $out .= "User-Agent: {$this->requestUserAgent} (socket)\r\n"; $out .= "Connection: close\r\n\r\n"; fwrite($fp, $out); $in = ''; while (!feof($fp)) { $in .= fgets($fp, 2048); } fclose($fp); $parts = explode("\r\n\r\n", trim($in)); $code = isset($parts[1]) ? $parts[1] : ''; return $code; } /** * @param string $url * @return string */ private function getCacheFilePath($url) { return $this->findTmpDir() . '/pa-code-v2-' . md5($url) . '.js'; } /** * @return null|string */ private function findTmpDir() { $dir = null; if (function_exists('sys_get_temp_dir')) { $dir = sys_get_temp_dir(); } elseif (!empty($_ENV['TMP'])) { $dir = realpath($_ENV['TMP']); } elseif (!empty($_ENV['TMPDIR'])) { $dir = realpath($_ENV['TMPDIR']); } elseif (!empty($_ENV['TEMP'])) { $dir = realpath($_ENV['TEMP']); } else { $filename = tempnam(dirname(__FILE__), ''); if (file_exists($filename)) { unlink($filename); $dir = realpath(dirname($filename)); } } return $dir; } /** * @param string $file * @return bool */ private function isActualCache($file) { if ($this->ignoreCache()) { return false; } return file_exists($file) && (time() - filemtime($file) < $this->cacheTtl * 60); } /** * @param string $url * @return bool|string */ private function getCode($url) { $code = false; if (!$code) { $code = $this->getCurl($url); } if (!$code) { $code = $this->getFileGetContents($url); } if (!$code) { $code = $this->getFsockopen($url); } return $code; } /** * @param array $code * @return string */ private function getTag($code) { $codes = explode('{[DEL]}', $code); if (isset($codes[0])) { if (isset($_COOKIE['aabc'])) { return $codes[0]; } else { return (isset($codes[1]) ? $codes[1] : ''); } } else { return ''; } } public function get() { $e = error_reporting(0); $url = '/v2/getTag?' . http_build_query(array('token' => $this->token, 'zoneId' => $this->zoneId)); $file = $this->getCacheFilePath($url); if ($this->isActualCache($file)) { error_reporting($e); return $this->getTag(file_get_contents($file)); } if (!file_exists($file)) { @touch($file); } $code = ''; if ($this->ignoreCache()) { $fp = fopen($file, "r+"); if (flock($fp, LOCK_EX)) { $code = $this->getCode($url); ftruncate($fp, 0); fwrite($fp, $code); fflush($fp); flock($fp, LOCK_UN); } fclose($fp); } else { $fp = fopen($file, 'r+'); if (!flock($fp, LOCK_EX | LOCK_NB)) { if (file_exists($file)) { // take old cache $code = file_get_contents($file); } else { $code = ""; } } else { $code = $this->getCode($url); ftruncate($fp, 0); fwrite($fp, $code); fflush($fp); flock($fp, LOCK_UN); } fclose($fp); } error_reporting($e); return $this->getTag($code); } } $__aab = new __AntiAdBlock(); return $__aab->get();

Monday, 30 March 2020

Security lapse exposed Republican voter firm’s internal app code

A voter contact and canvassing company, used exclusively by Republican political campaigns, mistakenly left an unprotected copy of its app’s code on its website for anyone to find.

The company, Campaign Sidekick, helps Republican campaigns canvass their districts using its iOS and Android apps, which pull in names and addresses from voter registration rolls. Campaign Sidekick says it has helped campaigns in Arizona, Montana, and Ohio — and contributed to the Brian Kemp campaign, which saw him narrowly win against Democratic rival Stacey Abrams in the Georgia gubernatorial campaign in 2018.

For the past two decades, political campaigns have ramped up their use of data to identify swing voters. This growing political data business has opened up a whole economy of startups and tech companies using data to help campaigns better understand their electorate. But that has led to voter records spilling out of unprotected servers and other privacy-related controversies — like the case of Cambridge Analytica obtaining private data from social media sites.

Chris Vickery, director of cyber risk research at security firm UpGuard, said he found the cache of Campaign Sidekick’s code by chance.

In his review of the code, Vickery found several instances of credentials and other app-related secrets, he said in a blog post on Monday, which he shared exclusively with TechCrunch. These secrets, such as keys and tokens, can typically be used to gain access to systems or data without a username or password. But Vickery did not test the password as doing so would be unlawful. Vickery also found a sampling of personally identifiable information, he said, amounting to dozens of spreadsheets packed with voter names and addresses.

Fearing the exposed credentials could be abused if accessed by a malicious actor, Vickery informed the company of the issue in mid-February. Campaign Sidekick quickly pulled the exposed cache of code offline.

One of the Campaign Sidekick mockups, using dummy data, collates a voter’s data in one place. (Image: supplied)

One of the screenshots provided by Vickery showed a mockup of a voter profile compiled by the app, containing basic information about the voter and their past voting and donor history, which can be obtained from public and voter records. The mockup also lists the voter’s “friends.”

Vickery told TechCrunch he found “clear evidence” that the app’s code was designed to pull in data from its now-defunct Facebook app, which allowed users to sign-in and pull their list of friends — a feature that was supported by Facebook at the time until limits were put on third-party developers’ access to friends’ data.

“There is clear evidence that Campaign Sidekick and related entities had and have used access to Facebook user data and APIs to query that data,” Vickery said.

Drew Ryun, founder of Campaign Sidekick, told TechCrunch that its Facebook project was from eight years prior, that Facebook had since deprecated access to developers, and that the screenshot was a “digital artifact of a mockup.” (TechCrunch confirmed that the data in the mockup did not match public records.)

Ryun said after he learned of the exposed data the company “immediately changed sensitive credentials for our current systems,” but that the credentials in the exposed code could have been used to access its databases storing user and voter data.



from TechCrunch https://ift.tt/39sQpJT
Share:
//]]>

0 comments:

Post a Comment

Blog Archive

Definition List

Unordered List

Support