Skip to content

Commit

Permalink
Improved frame breaker
Browse files Browse the repository at this point in the history
  • Loading branch information
mariuszkrzaczkowski committed Nov 19, 2019
1 parent e43ae86 commit 44c884f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 19 deletions.
26 changes: 26 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
*.php text eol=lf
*.js text eol=lf
*.css text eol=lf
*.less text eol=lf
*.scss text eol=lf
*.sass text eol=lf
*.tpl text eol=lf
*.properties text eol=lf
*.txt text eol=lf
*.md text eol=lf
*.htaccess text eol=lf
*.service text eol=lf
*.html text eol=lf
*.sql text eol=lf
*.ini text eol=lf
*.json text eol=lf
*.yml text eol=lf
*.yarnclean text eol=lf
*.lock text eol=lf
*.yarn-integrity text eol=lf

.github/ export-ignore
tests/ export-ignore
.travis.yml export-ignore
.scrutinizer.yml export-ignore
.sensiolabs.yml export-ignore
56 changes: 37 additions & 19 deletions src/Csrf.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ class Csrf
*/
public static $frameBreaker = true;

/**
* Which window should be verified? It is used to check if the system is loaded in the frame.
*
* @var string top/parent
*/
public static $windowVerification = 'top';

/**
* Whether or not CSRF Magic should be allowed to start a new session in order
* to determine the key.
Expand Down Expand Up @@ -148,12 +155,14 @@ class Csrf
/**
* Rewrites <form> on the fly to add CSRF tokens to them. This can also
* inject our JavaScript library.
*
* @param mixed $buffer
*/
public static function obHandler($buffer)
{
if (!static::$isHtml) {
// not HTML until proven otherwise
if (stripos($buffer, '<html') !== false) {
if (false !== stripos($buffer, '<html')) {
static::$isHtml = true;
} else {
// Customized to take the partial HTML with form
Expand All @@ -165,7 +174,8 @@ public static function obHandler($buffer)
foreach ($headers as $header) {
if (static::$isHtml) {
break;
} elseif (stripos('Content-type', $header) !== false && stripos('/html', $header) === false) {
}
if (false !== stripos('Content-type', $header) && false === stripos('/html', $header)) {
static::$isHtml = false;
}
}
Expand All @@ -181,7 +191,7 @@ public static function obHandler($buffer)
$input = "<input type='hidden' name='" . static::$inputName . "' value=\"$tokens\"$endSlash>";
$buffer = preg_replace('#(<form[^>]*method\s*=\s*["\']post["\'][^>]*>)#i', '$1' . $input, $buffer);
if (static::$frameBreaker && !static::$isPartial) {
$buffer = preg_replace('/<\/head>/', '<script type="text/javascript" nonce="' . static::$cspToken . '">if (top != self && top.location.origin + top.location.pathname != self.location.origin + self.location.pathname) {top.location.href = self.location.href;}</script></head>', $buffer, $count);
$buffer = preg_replace('/<\/head>/', '<script type="text/javascript" nonce="' . static::$cspToken . '">if (' . static::$windowVerification . ' != self && ' . static::$windowVerification . '.location.origin + ' . static::$windowVerification . '.location.pathname != self.location.origin + self.location.pathname) {' . static::$windowVerification . '.location.href = self.location.href;}</script></head>', $buffer, $count);
}
if (($js = static::$rewriteJs) && !static::$isPartial) {
$buffer = preg_replace(
Expand All @@ -208,7 +218,7 @@ public static function obHandler($buffer)
*/
public static function check($fatal = true)
{
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
if ('POST' !== $_SERVER['REQUEST_METHOD']) {
return true;
}
static::start();
Expand All @@ -227,10 +237,10 @@ public static function check($fatal = true)
$ok = true;
} while (false);
if ($fatal && !$ok) {
if (trim($tokens, 'A..Za..z0..9:;,') !== '') {
if ('' !== trim($tokens, 'A..Za..z0..9:;,')) {
$tokens = 'hidden';
}
call_user_func(static::$callback, $tokens);
\call_user_func(static::$callback, $tokens);
}
return $ok;
}
Expand Down Expand Up @@ -270,7 +280,7 @@ public static function getTokens()
if (!$secret) {
return 'invalid';
}
if (static::$user !== false) {
if (false !== static::$user) {
return 'user:' . static::hash(static::$user);
}
if (static::$allowIp) {
Expand All @@ -290,7 +300,7 @@ public static function flattenpost($data)

public static function flattenpost2($level, $key, $data)
{
if (!is_array($data)) {
if (!\is_array($data)) {
return [$key => $data];
}
$ret = [];
Expand Down Expand Up @@ -326,10 +336,12 @@ public static function callback($tokens)
/**
* Checks if a composite token is valid. Outward facing code should use this
* instead of csrf_check_token().
*
* @param mixed $tokens
*/
public static function checkTokens($tokens)
{
if (is_string($tokens)) {
if (\is_string($tokens)) {
$tokens = explode(';', $tokens);
}
foreach ($tokens as $token) {
Expand All @@ -349,11 +361,11 @@ public static function checkTokens($tokens)
*/
public static function checkToken($token)
{
if (strpos($token, ':') === false) {
if (false === strpos($token, ':')) {
return false;
}
list($type, $value) = explode(':', $token, 2);
if (strpos($value, ',') === false) {
[$type, $value] = explode(':', $token, 2);
if (false === strpos($value, ',')) {
return false;
}
$tokenExplode = explode(',', $token, 2);
Expand Down Expand Up @@ -387,7 +399,7 @@ public static function checkToken($token)
if (!static::getSecret()) {
return false;
}
if (static::$user === false) {
if (false === static::$user) {
return false;
}
return $value === static::hash(static::$user, $time);
Expand All @@ -397,7 +409,7 @@ public static function checkToken($token)
}
// do not allow IP-based checks if the username is set, or if
// the browser sent cookies
if (static::$user !== false) {
if (false !== static::$user) {
return false;
}
if (!empty($_COOKIE)) {
Expand All @@ -413,14 +425,17 @@ public static function checkToken($token)

/**
* Sets a configuration value.
*
* @param mixed $key
* @param mixed $val
*/
public static function conf($key, $val)
{
if (!isset(static::$$key)) {
if (!isset(static::${$key})) {
trigger_error('No such configuration ' . $key, E_USER_WARNING);
return;
}
static::$$key = $val;
static::${$key} = $val;
}

/**
Expand All @@ -441,7 +456,7 @@ public static function getSecret()
if (static::$secret) {
return static::$secret;
}
$file = self::$dirSecret . DIRECTORY_SEPARATOR . self::$fileNameSecret;
$file = self::$dirSecret . \DIRECTORY_SEPARATOR . self::$fileNameSecret;
$secret = '';
if (file_exists($file)) {
include $file;
Expand All @@ -463,8 +478,8 @@ public static function getSecret()
public static function generateSecret()
{
$r = '';
for ($i = 0; $i < 32; $i++) {
$r .= chr(mt_rand(0, 255));
for ($i = 0; $i < 32; ++$i) {
$r .= \chr(mt_rand(0, 255));
}
$r .= time() . microtime();
return sha1($r);
Expand All @@ -473,6 +488,9 @@ public static function generateSecret()
/**
* Generates a hash/expiry double. If time isn't set it will be calculated
* from the current time.
*
* @param mixed $value
* @param mixed|null $time
*/
public static function hash($value, $time = null)
{
Expand Down

0 comments on commit 44c884f

Please sign in to comment.