Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
"vendor-dir": "includes/vendor",
"platform": {
"php": "8.1.0"
}
},
"platform-check": false
},
"autoload": {
"psr-4": {
Expand Down
139 changes: 74 additions & 65 deletions composer.lock

Large diffs are not rendered by default.

24 changes: 0 additions & 24 deletions includes/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,30 +177,6 @@ public function define_core_constants(): void {
if (!defined( 'YOURLS_DB_TABLE_LOG' ))
define( 'YOURLS_DB_TABLE_LOG', YOURLS_DB_PREFIX.'log' );

// minimum delay in sec before a same IP can add another URL. Note: logged in users are not throttled down.
if (!defined( 'YOURLS_FLOOD_DELAY_SECONDS' ))
define( 'YOURLS_FLOOD_DELAY_SECONDS', 15 );

// comma separated list of IPs that can bypass flood check.
if (!defined( 'YOURLS_FLOOD_IP_WHITELIST' ))
define( 'YOURLS_FLOOD_IP_WHITELIST', '' );

// life span of an auth cookie in seconds (60*60*24*7 = 7 days)
if (!defined( 'YOURLS_COOKIE_LIFE' ))
define( 'YOURLS_COOKIE_LIFE', 60*60*24*7 );

// life span of a nonce in seconds
if (!defined( 'YOURLS_NONCE_LIFE' ))
define( 'YOURLS_NONCE_LIFE', 43200 ); // 3600 * 12

// if set to true, disable stat logging (no use for it, too busy servers, ...)
if (!defined( 'YOURLS_NOSTATS' ))
define( 'YOURLS_NOSTATS', false );

// if set to true, force https:// in the admin area
if (!defined( 'YOURLS_ADMIN_SSL' ))
define( 'YOURLS_ADMIN_SSL', false );

// if set to true, verbose debug infos
if (!defined( 'YOURLS_DEBUG' )) {
define('YOURLS_DEBUG', false);
Expand Down
33 changes: 23 additions & 10 deletions includes/functions-auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -635,29 +635,29 @@ function yourls_set_user( $user ) {
* Get YOURLS_COOKIE_LIFE value (ie the life span of an auth cookie in seconds)
*
* Use this function instead of directly using the constant. This way, its value can be modified by plugins
* on a per case basis
* on a per case basis. Defaults to 7 days when YOURLS_COOKIE_LIFE is not defined.
*
* @since 1.7.7
* @see includes/Config/Config.php
* @return integer cookie life span, in seconds
*/
function yourls_get_cookie_life() {
return yourls_apply_filter( 'get_cookie_life', YOURLS_COOKIE_LIFE );
function yourls_get_cookie_life(): int {
$life = defined( 'YOURLS_COOKIE_LIFE' ) ? YOURLS_COOKIE_LIFE : 60 * 60 * 24 * 7; // 7 days
return yourls_apply_filter( 'get_cookie_life', $life );
}

/**
* Get YOURLS_NONCE_LIFE value (ie life span of a nonce in seconds)
*
* Use this function instead of directly using the constant. This way, its value can be modified by plugins
* on a per case basis
* on a per case basis. Defaults to 12 hours when YOURLS_NONCE_LIFE is not defined.
*
* @since 1.7.7
* @see includes/Config/Config.php
* @see https://en.wikipedia.org/wiki/Cryptographic_nonce
* @return integer nonce life span, in seconds
*/
function yourls_get_nonce_life() {
return yourls_apply_filter( 'get_nonce_life', YOURLS_NONCE_LIFE );
function yourls_get_nonce_life(): int {
$life = defined( 'YOURLS_NONCE_LIFE' ) ? YOURLS_NONCE_LIFE : 60 * 60 * 12; // 12 hours
return yourls_apply_filter( 'get_nonce_life', $life );
}

/**
Expand Down Expand Up @@ -702,6 +702,19 @@ function yourls_tick() {
return ceil( time() / yourls_get_nonce_life() );
}

/**
* Get the cookie key (secret used for hashing), as maybe defined in config, filtered
*
* This is the secret key used by yourls_salt() to hash cookies and nonces.
*
* @since 1.10.5
* @return string Cookie key
*/
function yourls_get_cookie_key(): string {
$key = defined('YOURLS_COOKIEKEY') ? YOURLS_COOKIEKEY : hash('sha256', __FILE__);
return yourls_apply_filter( 'get_cookie_key', $key );
}

/**
* Return hashed string
*
Expand All @@ -711,8 +724,8 @@ function yourls_tick() {
* @param string $string string to salt
* @return string hashed string
*/
function yourls_salt( $string ) {
$salt = defined('YOURLS_COOKIEKEY') ? YOURLS_COOKIEKEY : hash('sha256', __FILE__) ;
function yourls_salt(string $string ): string {
$salt = yourls_get_cookie_key();
return yourls_apply_filter( 'yourls_salt', hash_hmac( yourls_hmac_algo(), $string, $salt), $string );
}

Expand Down
26 changes: 24 additions & 2 deletions includes/functions-plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ function yourls_is_active_plugin( $plugin ) {
* @param string $file Physical path to plugin file
* @return array Array of 'Field'=>'Value' from plugin comment header lines of the form "Field: Value"
*/
function yourls_get_plugin_data( $file ) {
function yourls_get_plugin_data(string $file ): array {
$fp = fopen( $file, 'r' ); // assuming $file is readable, since yourls_load_plugins() filters this
$data = fread( $fp, 8192 ); // get first 8kb
fclose( $fp );
Expand All @@ -554,7 +554,29 @@ function yourls_get_plugin_data( $file ) {
continue;
}

$plugin_data[ trim($matches[3]) ] = yourls_esc_html(trim($matches[4]));
// Allow some HTML in the Description field
if ( trim($matches[3]) === 'Description' ) {
$allowed = [
'strong' => [],
'b' => [],
'em' => [],
'i' => [],
'sup' => [],
'sub' => [],
'tt' => [],
'code' => [],
'br' => [],
'a' => [
'href' => true,
'title' => true,
],
];
$data = yourls_esc_html_with_whitelist(trim($matches[4]), $allowed);
} else {
$data = yourls_esc_html(trim($matches[4]));
}

$plugin_data[ trim($matches[3]) ] = $data;
}

return $plugin_data;
Expand Down
16 changes: 15 additions & 1 deletion includes/functions-shorturls.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,27 @@ function yourls_add_new_link( $url, $keyword = '', $title = '', $row_id = 1 ) {

return yourls_apply_filter( 'add_new_link', $return, $url, $keyword, $title );
}
/**
* Get the keyword conversion base, as defined in config, filtered
*
* Expected values are 36 (lowercase + digits) or 62/64 (mixed case + digits).
* Defaults to 36 when undefined or wrongly defined.
*
* @since 1.10.5
* @return int Conversion base
*/
function yourls_get_url_convert(): int {
$convert = defined( 'YOURLS_URL_CONVERT' ) ? (int) YOURLS_URL_CONVERT : 36;
return yourls_apply_filter( 'get_url_convert', $convert );
}

/**
* Determine the allowed character set in short URLs
*
* @return string Acceptable charset for short URLS keywords
*/
function yourls_get_shorturl_charset() {
if ( defined( 'YOURLS_URL_CONVERT' ) && in_array( YOURLS_URL_CONVERT, [ 62, 64 ] ) ) {
if ( in_array( yourls_get_url_convert(), [ 62, 64 ] ) ) {
$charset = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
}
else {
Expand Down
58 changes: 42 additions & 16 deletions includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -610,12 +610,15 @@ function yourls_log_redirect( $keyword ) {
}

/**
* Check if we want to not log redirects (for stats)
* Check if we want to log redirects (for stats)
*
* Logs redirects unless YOURLS_NOSTATS is defined and true. Filterable.
*
* @return bool
*/
function yourls_do_log_redirect() {
return ( !defined( 'YOURLS_NOSTATS' ) || YOURLS_NOSTATS != true );
$do_log = ( !defined( 'YOURLS_NOSTATS' ) || YOURLS_NOSTATS != true );
return (bool)yourls_apply_filter( 'do_log_redirect', $do_log );
}

/**
Expand Down Expand Up @@ -698,13 +701,44 @@ function yourls_allow_duplicate_longurls() {
return yourls_apply_filter('allow_duplicate_longurls', defined('YOURLS_UNIQUE_URLS') && !YOURLS_UNIQUE_URLS);
}

/**
* Get the flood delay in seconds, as maybe defined in config, filtered
*
* This is the minimum delay between two link creations from the same IP.
* Defaults to 15 when undefined.
*
* @since 1.10.5
* @return int Flood delay in seconds
*/
function yourls_get_flood_delay(): int {
$delay = defined( 'YOURLS_FLOOD_DELAY_SECONDS' ) ? (int) YOURLS_FLOOD_DELAY_SECONDS : 15;
return yourls_apply_filter( 'get_flood_delay', $delay );
}

/**
* Get the list of IPs exempt from flood checking, as maybe defined in config, filtered
*
* @since 1.10.5
* @return array List of whitelisted IPs (empty array if none)
*/
function yourls_get_flood_ip_whitelist(): array {
$whitelist = defined( 'YOURLS_FLOOD_IP_WHITELIST' ) ? (string) YOURLS_FLOOD_IP_WHITELIST : '';
$ips = array_filter( array_map( 'trim', explode( ',', $whitelist ) ) );

$ips = yourls_apply_filter( 'get_flood_ip_whitelist', $ips );

// Sanitize each IP, including any value added through the filter, drop empties and reindex
$ips = array_map( fn( $ip ) => yourls_sanitize_ip( trim( (string) $ip ) ), (array) $ips );
return array_values( array_filter( $ips ) );
}

/**
* Check if an IP shortens URL too fast to prevent DB flood. Return true, or die.
*
* @param string $ip
* @return bool|mixed|string
*/
function yourls_check_IP_flood( $ip = '' ) {
function yourls_check_IP_flood(string $ip = '' ): mixed {

// Allow plugins to short-circuit the whole function
$pre = yourls_apply_filter( 'shunt_check_IP_flood', yourls_shunt_default(), $ip );
Expand All @@ -715,11 +749,8 @@ function yourls_check_IP_flood( $ip = '' ) {
yourls_do_action( 'pre_check_ip_flood', $ip ); // at this point $ip can be '', check it if your plugin hooks in here

// Raise white flag if installing or if no flood delay defined
if(
( defined('YOURLS_FLOOD_DELAY_SECONDS') && YOURLS_FLOOD_DELAY_SECONDS === 0 ) ||
!defined('YOURLS_FLOOD_DELAY_SECONDS') ||
yourls_is_installing()
)
$flood_delay = yourls_get_flood_delay();
if( $flood_delay <= 0 || yourls_is_installing() )
return true;

// Don't throttle logged in users
Expand All @@ -729,13 +760,8 @@ function yourls_check_IP_flood( $ip = '' ) {
}

// Don't throttle whitelist IPs
if( defined( 'YOURLS_FLOOD_IP_WHITELIST' ) && YOURLS_FLOOD_IP_WHITELIST ) {
$whitelist_ips = explode( ',', YOURLS_FLOOD_IP_WHITELIST );
foreach( (array)$whitelist_ips as $whitelist_ip ) {
$whitelist_ip = trim( $whitelist_ip );
if ( $whitelist_ip == $ip )
return true;
}
if( in_array( $ip, yourls_get_flood_ip_whitelist() ) ) {
return true;
}

$ip = ( $ip ? yourls_sanitize_ip( $ip ) : yourls_get_IP() );
Expand All @@ -747,7 +773,7 @@ function yourls_check_IP_flood( $ip = '' ) {
if( $lasttime ) {
$now = date( 'U' );
$then = date( 'U', strtotime( $lasttime ) );
if( ( $now - $then ) <= YOURLS_FLOOD_DELAY_SECONDS ) {
if( ( $now - $then ) <= $flood_delay ) {
// Flood!
yourls_do_action( 'ip_flood', $ip, $now - $then );
yourls_die( yourls__( 'Too many URLs added too fast. Slow down please.' ), yourls__( 'Too Many Requests' ), 429 );
Expand Down
Binary file modified includes/geo/GeoLite2-Country.mmdb
Binary file not shown.
1 change: 0 additions & 1 deletion includes/vendor/composer/autoload_namespaces.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions includes/vendor/composer/autoload_psr4.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading