Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8881b3047a | ||
|
|
43a439e7d0 | ||
|
|
daf5522b1e | ||
|
|
e7feca0e53 | ||
| 4f72f04eda | |||
|
|
5b54ca34ad | ||
|
|
bc8b23d35e | ||
|
|
d9930978ba |
@@ -63,4 +63,7 @@
|
||||
* ADDED: Better json checking (including entropy).
|
||||
* ADDED: Added version to js/css assets URLs in order to prevent some abusive caches to serve an obsolete version of these files when ZeroBin is upgraded.
|
||||
* "Burn after reading" option has been moved out of Expiration combo to a separate checkbox. Reason is: You can prevent a read-once paste to be available ad vitam eternam on the net.
|
||||
* **Alpha 0.19 (2013-07-05)**:
|
||||
* Corrected XSS security flaw which affected IE<10. Other browsers were not affected.
|
||||
* Corrected spacing display in IE<10.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ZeroBin 0.18 Alpha
|
||||
ZeroBin 0.19 Alpha
|
||||
|
||||
==== THIS IS ALPHA SOFTWARE - USE AT YOUR OWN RISKS ====
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* ZeroBin 0.18 - http://sebsauvage.net/wiki/doku.php?id=php:zerobin */
|
||||
/* ZeroBin 0.19 - http://sebsauvage.net/wiki/doku.php?id=php:zerobin */
|
||||
|
||||
|
||||
/* CSS Reset from YUI 3.4.1 (build 4118) - Copyright 2011 Yahoo! Inc. All rights reserved.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
// change this, if your php files and data is outside of your webservers document root
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
// Immediately start random number generator collector.
|
||||
@@ -152,6 +152,9 @@ function pasteID() {
|
||||
return window.location.search.substring(1);
|
||||
}
|
||||
|
||||
function htmlEntities(str) {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
/**
|
||||
* Set text of a DOM element (required for IE)
|
||||
* This is equivalent to element.text(text)
|
||||
@@ -161,9 +164,9 @@ function pasteID() {
|
||||
function setElementText(element, text) {
|
||||
// For IE<10.
|
||||
if ($('div#oldienotice').is(":visible")) {
|
||||
// IE<10 do not support white-space:pre-wrap; so we have to do this BIG UGLY STINKING THING.
|
||||
element.text(text.replace(/\n/ig,'{BIG_UGLY_STINKING_THING__OH_GOD_I_HATE_IE}'));
|
||||
element.html(element.text().replace(/{BIG_UGLY_STINKING_THING__OH_GOD_I_HATE_IE}/ig,"\n<br />"));
|
||||
// IE<10 does not support white-space:pre-wrap; so we have to do this BIG UGLY STINKING THING.
|
||||
var html = htmlEntities(text).replace(/\n/ig,"\r\n<br>");
|
||||
element.html('<pre>'+html+'</pre>');
|
||||
}
|
||||
// for other (sane) browsers:
|
||||
else {
|
||||
@@ -306,6 +309,7 @@ function send_comment(parentid) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send a new paste to server
|
||||
*/
|
||||
@@ -314,7 +318,17 @@ function send_data() {
|
||||
if ($('textarea#message').val().length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If sjcl has not collected enough entropy yet, display a message.
|
||||
if (!sjcl.random.isReady())
|
||||
{
|
||||
showStatus('Sending paste (Please move your mouse for more entropy)...', spin=true);
|
||||
sjcl.random.addEventListener('seeded', function(){ send_data(); });
|
||||
return;
|
||||
}
|
||||
|
||||
showStatus('Sending paste...', spin=true);
|
||||
|
||||
var randomkey = sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 0), 0);
|
||||
var cipherdata = zeroCipher(randomkey, $('textarea#message').val());
|
||||
var data_to_send = { data: cipherdata,
|
||||
@@ -425,10 +439,9 @@ function stateExistingPaste() {
|
||||
*/
|
||||
function rawText()
|
||||
{
|
||||
history.pushState(document.title, document.title, 'document.txt');
|
||||
var paste = $('div#cleartext').text();
|
||||
var newDoc = document.open('text/plain', 'replace');
|
||||
newDoc.write(paste);
|
||||
var paste = $('div#cleartext').html();
|
||||
var newDoc = document.open('text/html', 'replace');
|
||||
newDoc.write('<pre>'+paste+'</pre>');
|
||||
newDoc.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
spl_autoload_register('auto::loader');
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -50,4 +50,35 @@ class filter
|
||||
}
|
||||
return number_format($size, ($i ? 2 : 0), '.', ' ') . ' ' . $iec[$i];
|
||||
}
|
||||
|
||||
/**
|
||||
* validate paste ID
|
||||
*
|
||||
* @access public
|
||||
* @param string $dataid
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_valid_paste_id($dataid)
|
||||
{
|
||||
return (bool) preg_match('#\A[a-f\d]{16}\z#', $dataid);
|
||||
}
|
||||
|
||||
/**
|
||||
* fixed time string comparison operation to prevent timing attacks
|
||||
* https://crackstation.net/hashing-security.htm?=rd#slowequals
|
||||
*
|
||||
* @access public
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
* @return bool
|
||||
*/
|
||||
public static function slow_equals($a, $b)
|
||||
{
|
||||
$diff = strlen($a) ^ strlen($b);
|
||||
for($i = 0; $i < strlen($a) && $i < strlen($b); $i++)
|
||||
{
|
||||
$diff |= ord($a[$i]) ^ ord($b[$i]);
|
||||
}
|
||||
return $diff === 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -105,7 +105,7 @@ abstract class persistence
|
||||
{
|
||||
self::_initialize();
|
||||
$file = self::$_path . '/' . $filename;
|
||||
file_put_contents($file, $data);
|
||||
file_put_contents($file, $data, LOCK_EX);
|
||||
chmod($file, 0705);
|
||||
return $file;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -39,9 +39,16 @@ class serversalt extends persistence
|
||||
public static function generate()
|
||||
{
|
||||
$randomSalt = '';
|
||||
if (function_exists('mcrypt_create_iv'))
|
||||
{
|
||||
$randomSalt = bin2hex(mcrypt_create_iv(256, MCRYPT_DEV_URANDOM));
|
||||
}
|
||||
else // fallback to mt_rand()
|
||||
{
|
||||
for($i = 0; $i < 16; ++$i) {
|
||||
$randomSalt .= base_convert(mt_rand(), 10, 16);
|
||||
}
|
||||
}
|
||||
self::$_salt = $randomSalt;
|
||||
return self::$_salt;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:vizhash_gd
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.0.4 beta ZeroBin 0.18
|
||||
* @version 0.0.4 beta ZeroBin 0.19
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -20,7 +20,7 @@ class zerobin
|
||||
/*
|
||||
* @const string version
|
||||
*/
|
||||
const VERSION = 'Alpha 0.18';
|
||||
const VERSION = 'Alpha 0.19';
|
||||
|
||||
/**
|
||||
* @access private
|
||||
@@ -272,8 +272,8 @@ class zerobin
|
||||
$pasteid = $_POST['pasteid'];
|
||||
$parentid = $_POST['parentid'];
|
||||
if (
|
||||
!preg_match('/\A[a-f\d]{16}\z/', $pasteid) ||
|
||||
!preg_match('/\A[a-f\d]{16}\z/', $parentid)
|
||||
!filter::is_valid_paste_id($pasteid) ||
|
||||
!filter::is_valid_paste_id($parentid)
|
||||
) $this->_return_message(1, 'Invalid data.');
|
||||
|
||||
// Comments do not expire (it's the paste that expires)
|
||||
@@ -340,18 +340,21 @@ class zerobin
|
||||
private function _delete($dataid, $deletetoken)
|
||||
{
|
||||
// Is this a valid paste identifier?
|
||||
if (preg_match('\A[a-f\d]{16}\z', $dataid))
|
||||
if (!filter::is_valid_paste_id($dataid))
|
||||
{
|
||||
$this->_error = 'Invalid paste ID.';
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that paste exists.
|
||||
if (!$this->_model()->exists($dataid))
|
||||
{
|
||||
$this->_error = 'Paste does not exist, has expired or has been deleted.';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure token is valid.
|
||||
if ($deletetoken != hash_hmac('sha1', $dataid , serversalt::get()))
|
||||
if (filter::slow_equals($deletetoken, hash_hmac('sha1', $dataid , serversalt::get())))
|
||||
{
|
||||
$this->_error = 'Wrong deletion token. Paste was not deleted.';
|
||||
return;
|
||||
@@ -372,8 +375,12 @@ class zerobin
|
||||
private function _read($dataid)
|
||||
{
|
||||
// Is this a valid paste identifier?
|
||||
if (preg_match('#\A[a-f\d]{16}\z#', $dataid))
|
||||
if (!filter::is_valid_paste_id($dataid))
|
||||
{
|
||||
$this->_error = 'Invalid paste ID.';
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that paste exists.
|
||||
if ($this->_model()->exists($dataid))
|
||||
{
|
||||
@@ -426,7 +433,6 @@ class zerobin
|
||||
$this->_error = 'Paste does not exist or has expired.';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display ZeroBin frontend.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* @link http://sebsauvage.net/wiki/doku.php?id=php:zerobin
|
||||
* @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
|
||||
* @license http://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
|
||||
* @version 0.18
|
||||
* @version 0.19
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,4 +44,25 @@ class filterTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('1.00 YiB', filter::size_humanreadable(1024 * $exponent));
|
||||
$this->assertEquals('1.21 YiB', filter::size_humanreadable(1234 * $exponent));
|
||||
}
|
||||
|
||||
public function testPasteIdValidation()
|
||||
{
|
||||
$this->assertTrue(filter::is_valid_paste_id('a242ab7bdfb2581a'), 'valid paste id');
|
||||
$this->assertFalse(filter::is_valid_paste_id('foo'), 'invalid hex values');
|
||||
$this->assertFalse(filter::is_valid_paste_id('../bar/baz'), 'path attack');
|
||||
}
|
||||
|
||||
public function testSlowEquals()
|
||||
{
|
||||
$this->assertTrue(filter::slow_equals('foo', 'foo'), 'same string');
|
||||
$this->assertFalse(filter::slow_equals('foo', true), 'string and boolean');
|
||||
$this->assertFalse(filter::slow_equals('foo', 0), 'string and integer');
|
||||
$this->assertFalse(filter::slow_equals('123foo', 123), 'string and integer');
|
||||
$this->assertFalse(filter::slow_equals('123foo', '123'), 'different strings');
|
||||
$this->assertFalse(filter::slow_equals('6', ' 6'), 'strings with space');
|
||||
$this->assertFalse(filter::slow_equals('4.2', '4.20'), 'floats as strings');
|
||||
$this->assertFalse(filter::slow_equals('1e3', '1000'), 'integers as strings');
|
||||
$this->assertFalse(filter::slow_equals('9223372036854775807', '9223372036854775808'), 'large integers as strings');
|
||||
$this->assertFalse(filter::slow_equals('61529519452809720693702583126814', '61529519452809720000000000000000'), 'larger integers as strings');
|
||||
}
|
||||
}
|
||||
|
||||
17
tst/mcrypt_mock.php
Normal file
17
tst/mcrypt_mock.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
define('MCRYPT_DEV_URANDOM', 1);
|
||||
|
||||
function mcrypt_create_iv($int, $flag)
|
||||
{
|
||||
$randomSalt = '';
|
||||
for($i = 0; $i < 16; ++$i) {
|
||||
$randomSalt .= base_convert(mt_rand(), 10, 16);
|
||||
}
|
||||
// hex2bin requires an even length, pad if necessary
|
||||
if (strlen($randomSalt) % 2)
|
||||
{
|
||||
$randomSalt = '0' . $randomSalt;
|
||||
}
|
||||
return hex2bin($randomSalt);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<phpunit bootstrap="bootstrap.php" colors="true">
|
||||
<testsuite name="ZeroBin Test Suite">
|
||||
<directory suffix=".php">./</directory>
|
||||
<exclude>mcrypt_mock.php</exclude>
|
||||
</testsuite>
|
||||
<filter>
|
||||
<whitelist>
|
||||
|
||||
@@ -37,5 +37,10 @@ class vizhash16x16Test extends PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('image/png', $finfo->file($this->_file));
|
||||
$this->assertNotEquals($pngdata, $vz->generate('2001:1620:2057:dead:beef::cafe:babe'));
|
||||
$this->assertEquals($pngdata, $vz->generate('127.0.0.1'));
|
||||
|
||||
// generating new salt
|
||||
$salt = serversalt::get();
|
||||
require 'mcrypt_mock.php';
|
||||
$this->assertNotEquals($salt, serversalt::generate());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user