mirror of
https://github.com/PrivateBin/PrivateBin.git
synced 2025-11-27 09:40:34 -05:00
Merge branch 'master' into karthikkasturi-master
This commit is contained in:
commit
2e5d6dddac
10 changed files with 92 additions and 15 deletions
|
|
@ -1,9 +1,16 @@
|
|||
#!/bin/sh
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
npm install --global nyc
|
||||
|
|
|
|||
7
.github/workflows/snyk-scan.yml
vendored
7
.github/workflows/snyk-scan.yml
vendored
|
|
@ -12,7 +12,12 @@ jobs:
|
|||
# https://github.com/snyk/actions/tree/master/php
|
||||
snyk-php:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'PrivateBin/PrivateBin' }}
|
||||
if: |
|
||||
github.repository == 'PrivateBin/PrivateBin' && (
|
||||
github.event.pull_request.author_association == 'COLLABORATOR' ||
|
||||
github.event.pull_request.author_association == 'CONTRIBUTOR' ||
|
||||
github.event.pull_request.author_association == 'MEMBER' ||
|
||||
github.event.pull_request.author_association == 'OWNER' )
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install Google Cloud Storage
|
||||
|
|
|
|||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
|
|
@ -1,6 +1,8 @@
|
|||
name: Tests
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -25,6 +25,7 @@ vendor/**/tst
|
|||
vendor/**/tests
|
||||
vendor/**/build_phar.php
|
||||
!vendor/**/*.php
|
||||
vendor/bin/**
|
||||
|
||||
# Ignore local node modules, unit testing logs, api docs and IDE project files
|
||||
js/node_modules/
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@
|
|||
"Error decompressing document, your browser does not support WebAssembly. Please use another browser to view this document.": "Erreur lors de la décompression du document, votre navigateur ne supporte pas WebAssembly. Veuillez utiliser un autre navigateur pour voir ce document.",
|
||||
"Start over": "Recommencer",
|
||||
"Document copied to clipboard": "Document copié dans le presse-papier",
|
||||
"To copy document press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "Pour copier-coller appuyer sur le bouton To copy document press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||
"To copy document press on the copy button or use the clipboard shortcut <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>": "Pour copier appuyer sur le bouton Copier le lien ou utiliser le raccourci <kbd>Ctrl</kbd>+<kbd>c</kbd>/<kbd>Cmd</kbd>+<kbd>c</kbd>",
|
||||
"Copy link": "Copier le lien",
|
||||
"Link copied to clipboard": "Lien copié dans le presse-papier",
|
||||
"Document text": "Texte du document",
|
||||
|
|
|
|||
|
|
@ -106,8 +106,8 @@
|
|||
return window.isSecureContext;
|
||||
}
|
||||
|
||||
// HTTP is obviously insecure
|
||||
if (window.location.protocol !== 'http:') {
|
||||
// HTTPS is considered secure
|
||||
if (window.location.protocol === 'https:') {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -930,7 +930,8 @@ jQuery.PrivateBin = (function($) {
|
|||
}
|
||||
|
||||
// load strings from JSON
|
||||
$.getJSON('i18n/' + newLanguage + '.json', function(data) {
|
||||
const cacheBreaker = document.querySelector('script[src^="js/privatebin.js"]').getAttribute('src').split('.js')[1] || '';
|
||||
$.getJSON('i18n/' + newLanguage + '.json' + cacheBreaker, function(data) {
|
||||
language = newLanguage;
|
||||
translations = data;
|
||||
$(document).triggerHandler(languageLoadedEvent);
|
||||
|
|
@ -5160,7 +5161,7 @@ jQuery.PrivateBin = (function($) {
|
|||
|
||||
// UI loading state
|
||||
TopNav.hideAllButtons();
|
||||
Alert.showLoading('Sending paste…', 'cloud-upload');
|
||||
Alert.showLoading('Sending document…', 'cloud-upload');
|
||||
TopNav.collapseBar();
|
||||
|
||||
// get data
|
||||
|
|
@ -5431,7 +5432,7 @@ jQuery.PrivateBin = (function($) {
|
|||
{
|
||||
Alert.hideMessages();
|
||||
Alert.setCustomHandler(null);
|
||||
Alert.showLoading('Decrypting paste…', 'cloud-download');
|
||||
Alert.showLoading('Decrypting document…', 'cloud-download');
|
||||
|
||||
if (typeof paste === 'undefined' || paste.type === 'click') {
|
||||
// get cipher data and wait until it is available
|
||||
|
|
@ -5776,7 +5777,7 @@ jQuery.PrivateBin = (function($) {
|
|||
// Important: This *must not* run Alert.hideMessages() as previous
|
||||
// errors from viewing a document should be shown.
|
||||
TopNav.hideAllButtons();
|
||||
Alert.showLoading('Preparing new paste…', 'time');
|
||||
Alert.showLoading('Preparing new document…', 'time');
|
||||
|
||||
PasteStatus.hideMessages();
|
||||
PasteViewer.hide();
|
||||
|
|
|
|||
|
|
@ -119,9 +119,9 @@ class Configuration
|
|||
'js/dark-mode-switch.js' => 'sha512-BhY7dNU14aDN5L+muoUmA66x0CkYUWkQT0nxhKBLP/o2d7jE025+dvWJa4OiYffBGEFgmhrD/Sp+QMkxGMTz2g==',
|
||||
'js/jquery-3.7.1.js' => 'sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==',
|
||||
'js/kjua-0.10.0.js' => 'sha512-BYj4xggowR7QD150VLSTRlzH62YPfhpIM+b/1EUEr7RQpdWAGKulxWnOvjFx1FUlba4m6ihpNYuQab51H6XlYg==',
|
||||
'js/legacy.js' => 'sha512-08+subq1Lo+r+la5ENqeXiMgNJcVaaTtBIFGkrjziSpvtgCId3Jtin4/OkSdHYSoeztwwIab8uvCzPKHta6puQ==',
|
||||
'js/legacy.js' => 'sha512-mXAgFn/DonfPANvPO6Kf08zRKCeQ75jXK69gcUUOpPLFkp3KHnDhnvij8nEJxlutD/670Bfi4RNMG6uEjA4nNQ==',
|
||||
'js/prettify.js' => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
|
||||
'js/privatebin.js' => 'sha512-seF8mXWh9E9SBK0qWNfm8RTGneGc05QpDcPyeTk+sg6efB6Edhiu6mvbSDCM4zb/gFqeko7jTYcUSYxhs3UIaA==',
|
||||
'js/privatebin.js' => 'sha512-nMz7sgy/jMKXKAUDcZcsUdVEuKN89Fgf0mvD7DB70pI4R6ExJwCOWaiQTc/czhVVUEwKzbhWrJG/hX2Tqhe5QA==',
|
||||
'js/purify-3.2.6.js' => 'sha512-zqwL4OoBLFx89QPewkz4Lz5CSA2ktU+f31fuECkF0iK3Id5qd3Zpq5dMby8KwHjIEpsUgOqwF58cnmcaNem0EA==',
|
||||
'js/showdown-2.1.0.js' => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
|
||||
'js/zlib-1.3.1-1.js' => 'sha512-5bU9IIP4PgBrOKLZvGWJD4kgfQrkTz8Z3Iqeu058mbQzW3mCumOU6M3UVbVZU9rrVoVwaW4cZK8U8h5xjF88eQ==',
|
||||
|
|
|
|||
|
|
@ -49,7 +49,14 @@ abstract class AbstractProxy
|
|||
*/
|
||||
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.';
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,22 +45,76 @@ class YourlsProxyTest extends TestCase
|
|||
$yourls = new YourlsProxy($this->_conf, 'https://example.com/?foo#bar');
|
||||
$this->assertFalse($yourls->isError());
|
||||
$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->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->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()
|
||||
{
|
||||
// when statusCode is not 200, shorturl may not have been set
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue