mirror of
https://github.com/PrivateBin/PrivateBin.git
synced 2025-10-03 09:49:14 +02:00
Compare commits
20 commits
952e86b11c
...
394b4cb33d
Author | SHA1 | Date | |
---|---|---|---|
![]() |
394b4cb33d | ||
![]() |
2b8b5d71d2 | ||
![]() |
24afa5a1d8 | ||
![]() |
191ed63b04 | ||
![]() |
bd61a3d021 | ||
![]() |
a6034ace1b | ||
![]() |
616635c66c | ||
![]() |
e4f2383dd8 | ||
![]() |
25dca0838e | ||
![]() |
cfc687d62b | ||
![]() |
168fed64b9 | ||
![]() |
4f13d93af2 | ||
![]() |
f76704a88c | ||
![]() |
dbaa70ec11 | ||
![]() |
879b696f22 | ||
![]() |
0a398d73f0 | ||
![]() |
fae7e233f3 | ||
![]() |
64165d9928 | ||
![]() |
bdfe74c077 | ||
![]() |
2c1a17a07f |
7 changed files with 75 additions and 7 deletions
|
@ -1,9 +1,16 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
export PATH="$PATH:$HOME/.composer/vendor/bin"
|
export PATH="$PATH:$HOME/.composer/vendor/bin"
|
||||||
|
export PATH="$PATH:$PWD/vendor/bin"
|
||||||
|
echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bashrc
|
||||||
|
echo 'export PATH="$PATH:$PWD/vendor/bin"' >> ~/.bashrc
|
||||||
ln -s ./conf.sample.php cfg/conf.php
|
ln -s ./conf.sample.php cfg/conf.php
|
||||||
composer install --no-dev --optimize-autoloader
|
composer install --no-dev --optimize-autoloader
|
||||||
|
|
||||||
|
# for PHP unit testing
|
||||||
|
# composer require google/cloud-storage
|
||||||
|
# composer install --optimize-autoloader
|
||||||
|
|
||||||
sudo chmod a+x "$(pwd)" && sudo rm -rf /var/www/html && sudo ln -s "$(pwd)" /var/www/html
|
sudo chmod a+x "$(pwd)" && sudo rm -rf /var/www/html && sudo ln -s "$(pwd)" /var/www/html
|
||||||
|
|
||||||
npm install --global nyc
|
npm install --global nyc
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -25,6 +25,7 @@ vendor/**/tst
|
||||||
vendor/**/tests
|
vendor/**/tests
|
||||||
vendor/**/build_phar.php
|
vendor/**/build_phar.php
|
||||||
!vendor/**/*.php
|
!vendor/**/*.php
|
||||||
|
vendor/bin/**
|
||||||
|
|
||||||
# Ignore local node modules, unit testing logs, api docs and IDE project files
|
# Ignore local node modules, unit testing logs, api docs and IDE project files
|
||||||
js/node_modules/
|
js/node_modules/
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* FIXED: Allow copying the shortened link after using a URL shortener (#1624)
|
* FIXED: Allow copying the shortened link after using a URL shortener (#1624)
|
||||||
* ADDED: Auto shorten URLs with config option `shortenbydefault` (#1627)
|
* ADDED: Auto shorten URLs with config option `shortenbydefault` (#1627)
|
||||||
* ADDED: Added `shortenviashlink` endpoint with an `shlink` configuration section
|
* ADDED: Added `shortenviashlink` endpoint with an `shlink` configuration section
|
||||||
|
* FIXED: Check for quotes and conical braces when extracting short url (#1644)
|
||||||
|
|
||||||
## 2.0.0 (2025-07-28)
|
## 2.0.0 (2025-07-28)
|
||||||
* ADDED: Error logging in database and filesystem backend (#1554)
|
* ADDED: Error logging in database and filesystem backend (#1554)
|
||||||
|
|
|
@ -149,7 +149,6 @@ describe('PasteStatus', function () {
|
||||||
'<html lang="en">\n' +
|
'<html lang="en">\n' +
|
||||||
'\t<head>\n' +
|
'\t<head>\n' +
|
||||||
'\t\t<meta charset="utf-8" />\n' +
|
'\t\t<meta charset="utf-8" />\n' +
|
||||||
'\t\t<meta http-equiv="Content-Security-Policy" content="default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads">\n' +
|
|
||||||
'\t\t<meta name="robots" content="noindex" />\n' +
|
'\t\t<meta name="robots" content="noindex" />\n' +
|
||||||
'\t\t<meta name="google" content="notranslate">\n' +
|
'\t\t<meta name="google" content="notranslate">\n' +
|
||||||
'\t\t<title>PrivateBin</title>\n' +
|
'\t\t<title>PrivateBin</title>\n' +
|
||||||
|
|
|
@ -49,7 +49,14 @@ abstract class AbstractProxy
|
||||||
*/
|
*/
|
||||||
public function __construct(Configuration $conf, string $link)
|
public function __construct(Configuration $conf, string $link)
|
||||||
{
|
{
|
||||||
if (!str_starts_with($link, $conf->getKey('basepath') . '?')) {
|
if (!filter_var($link, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED | FILTER_FLAG_QUERY_REQUIRED)) {
|
||||||
|
$this->_error = 'Invalid URL given.';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!str_starts_with($link, $conf->getKey('basepath') . '?') ||
|
||||||
|
parse_url($link, PHP_URL_HOST) != parse_url($conf->getKey('basepath'), PHP_URL_HOST)
|
||||||
|
) {
|
||||||
$this->_error = 'Trying to shorten a URL that isn\'t pointing at our instance.';
|
$this->_error = 'Trying to shorten a URL that isn\'t pointing at our instance.';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ use PrivateBin\I18n;
|
||||||
<html lang="<?php echo I18n::getLanguage(); ?>"<?php echo I18n::isRtl() ? ' dir="rtl"' : ''; ?>>
|
<html lang="<?php echo I18n::getLanguage(); ?>"<?php echo I18n::isRtl() ? ' dir="rtl"' : ''; ?>>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="Content-Security-Policy" content="<?php echo I18n::encode($CSPHEADER); ?>">
|
|
||||||
<meta name="robots" content="noindex" />
|
<meta name="robots" content="noindex" />
|
||||||
<meta name="google" content="notranslate">
|
<meta name="google" content="notranslate">
|
||||||
<title><?php echo I18n::_($NAME); ?></title>
|
<title><?php echo I18n::_($NAME); ?></title>
|
||||||
|
|
|
@ -45,22 +45,76 @@ class YourlsProxyTest extends TestCase
|
||||||
$yourls = new YourlsProxy($this->_conf, 'https://example.com/?foo#bar');
|
$yourls = new YourlsProxy($this->_conf, 'https://example.com/?foo#bar');
|
||||||
$this->assertFalse($yourls->isError());
|
$this->assertFalse($yourls->isError());
|
||||||
$this->assertEquals($yourls->getUrl(), 'https://example.com/1');
|
$this->assertEquals($yourls->getUrl(), 'https://example.com/1');
|
||||||
|
|
||||||
|
$yourls = new YourlsProxy($this->_conf, 'https://example.com/?@foreign.malicious.example?foo#bar');
|
||||||
|
$this->assertFalse($yourls->isError());
|
||||||
|
$this->assertEquals($yourls->getUrl(), 'https://example.com/1');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testForeignUrl()
|
/**
|
||||||
|
* @dataProvider providerInvalidUrl
|
||||||
|
*/
|
||||||
|
public function testImvalidUrl($url): void
|
||||||
{
|
{
|
||||||
$yourls = new YourlsProxy($this->_conf, 'https://other.example.com/?foo#bar');
|
$yourls = new YourlsProxy($this->_conf, $url);
|
||||||
|
$this->assertTrue($yourls->isError());
|
||||||
|
$this->assertEquals($yourls->getError(), 'Invalid URL given.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerInvalidUrl(): array
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(''),
|
||||||
|
array(' '),
|
||||||
|
array('foo'),
|
||||||
|
array('https://'),
|
||||||
|
array('https://example.com'), // missing path and query parameter,
|
||||||
|
array('https://example.com/'), // missing query parameter
|
||||||
|
array('https://example.com?paste=something'), // missing path parameter
|
||||||
|
array('https://example.com@foreign.malicious.example?foo#bar'), // missing path parameter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This tests for a trick using username of an URI, see:
|
||||||
|
* {@see https://cloud.google.com/blog/topics/threat-intelligence/url-obfuscation-schema-abuse/?hl=en}
|
||||||
|
*
|
||||||
|
* @dataProvider providerForeignUrlUsernameTrick
|
||||||
|
*/
|
||||||
|
public function testForeignUrlUsingUsernameTrick($url): void
|
||||||
|
{
|
||||||
|
$yourls = new YourlsProxy($this->_conf, $url);
|
||||||
$this->assertTrue($yourls->isError());
|
$this->assertTrue($yourls->isError());
|
||||||
$this->assertEquals($yourls->getError(), 'Trying to shorten a URL that isn\'t pointing at our instance.');
|
$this->assertEquals($yourls->getError(), 'Trying to shorten a URL that isn\'t pointing at our instance.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSneakyForeignUrl()
|
public function providerForeignUrlUsernameTrick(): array
|
||||||
{
|
{
|
||||||
$yourls = new YourlsProxy($this->_conf, 'https://other.example.com/?q=https://example.com/?foo#bar');
|
return array(
|
||||||
|
array('https://example.com@foreign.malicious.example/?foo#bar'),
|
||||||
|
array('https://example.com/@foreign.malicious.example?foo#bar'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerForeignUrl
|
||||||
|
*/
|
||||||
|
public function testForeignUrl($url): void
|
||||||
|
{
|
||||||
|
$yourls = new YourlsProxy($this->_conf, $url);
|
||||||
$this->assertTrue($yourls->isError());
|
$this->assertTrue($yourls->isError());
|
||||||
$this->assertEquals($yourls->getError(), 'Trying to shorten a URL that isn\'t pointing at our instance.');
|
$this->assertEquals($yourls->getError(), 'Trying to shorten a URL that isn\'t pointing at our instance.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function providerForeignUrl(): array
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('ftp://example.com/?n=np'), // wrong protocol
|
||||||
|
array('https://other.example.com/?foo#bar'), // wrong domain
|
||||||
|
array('https://other.example.com/?q=https://example.com/?foo#bar'), // domain included inside string
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testYourlsError()
|
public function testYourlsError()
|
||||||
{
|
{
|
||||||
// when statusCode is not 200, shorturl may not have been set
|
// when statusCode is not 200, shorturl may not have been set
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue