Heim  >  Artikel  >  Backend-Entwicklung  >  PHP-Formular verhindert wiederholte Übermittlung (Anti-CSRF-Sicherheitslücke)

PHP-Formular verhindert wiederholte Übermittlung (Anti-CSRF-Sicherheitslücke)

不言
不言Original
2018-04-20 11:44:013800Durchsuche

Der Inhalt dieses Artikels befasst sich mit der Verhinderung der wiederholten Übermittlung von PHP-Formularen (Verhinderung von CSRF-Schwachstellen). Jetzt kann ich ihn mit Ihnen teilen.

Token Eine kurze Diskussion

Token ist ein Token. Seine größte Eigenschaft ist Zufälligkeit und Unvorhersehbarkeit. Normale Hacker oder Software können es nicht erraten.

Was ist also die Funktion von Token? Was ist das Prinzip?

Token wird im Allgemeinen an zwei Stellen verwendet – um wiederholte Formularübermittlungen und Anti-CSRF-Angriffe (Cross-Site Request Forgery) zu verhindern.

Beides wird grundsätzlich durch Session-Tokens umgesetzt. Wenn der Client eine Seite anfordert, generiert der Server ein Zufallszahlen-Token, platziert das Token in der Sitzung und sendet es dann an den Client (normalerweise durch Erstellen eines versteckten Formulars). Wenn der Client das nächste Mal eine Anfrage sendet, wird das Token zusammen mit dem Formular an den Server übermittelt.

Wenn es dann auf „Anti-CSRF-Angriff“ angewendet wird, überprüft der Server den Token-Wert, um festzustellen, ob er mit dem Token-Wert in der Sitzung übereinstimmt bewiesen werden, gültig, nicht gefälscht.

Wenn es jedoch verwendet wird, um „die wiederholte Übermittlung von Formularen zu verhindern“, wird der Token-Wert in der Sitzung nach der ersten Überprüfung derselben auf der Serverseite aktualisiert Wenn der Benutzer wiederholt einreicht, schlägt die sekundäre Überprüfungsbeurteilung fehl, da sich das Token in der vom Benutzer übermittelten Form nicht geändert hat, das Token in der serverseitigen Sitzung jedoch geändert wurde.

Die obige Sitzungsanwendung ist relativ sicher, aber auch umständlich. Gleichzeitig ist die Methode zum gleichzeitigen Generieren mehrerer Token erforderlich verwendet werden, was mehr Ressourcen beansprucht und die Ausführungseffizienz verringert. Daher kann anstelle des Sitzungstokens auch die Methode zum Speichern von Verifizierungsinformationen in Cookies verwendet werden. Wenn es sich beispielsweise um „wiederholte Übermittlungen“ handelt, werden die übermittelten Informationen nach der ersten Übermittlung in das Cookie geschrieben. Bei der zweiten Übermittlung schlägt die zweite Übermittlung fehl, da das Cookie bereits über einen Übermittlungsdatensatz verfügt.

Die Cookie-Speicherung hat jedoch eine fatale Schwäche. Wenn das Cookie gekapert wird (XSS-Angriffe können Benutzercookies leicht erbeuten), kommt es zu einem weiteren Gameover. Hacker werden CSRF-Angriffe direkt implementieren.

1. Verhindern Sie zuerst XSS-Angriffe

2. Überprüfen Sie den Referrer

3. Wichtige Cookie-Einstellungen sind nur https, z. B. Token

4 . Verwenden Sie Signatur, Token

5. get wird nur zum Abfragen von Informationen verwendet

6. Verwenden Sie Post, um das Formular abzusenden

7 . Verwenden Sie Cross-Text mit Vorsicht. Script-Injection

Sicherheit und Effizienz sind also relativ. Lassen Sie uns auf konkrete Themen im Detail eingehen.


Token zum PHP-Formular hinzufügen, um wiederholte Übermittlungen zu verhindern

Das Prinzip besteht darin, einen Zufall zu generieren Zeichenfolge und fügen Sie sie in die Sitzung ein. Hier kann die Überprüfung dieser Zeichenfolge nach dem Absenden des Formulars verhindern, dass andere das Formular selbst schreiben, um die Übermittlung zu betrügen, die Übermittlung zu wiederholen oder auf die Übermittlung doppelklicken.

Der in PHP implementierte einfache Code lautet wie folgt:


<?php
/*
* PHP简单利用token防止表单重复提交
* 此处理方法纯粹是为了给初学者参考
*/
session_start();
function set_token() {
  $_SESSION[&#39;token&#39;] = md5(microtime(true));
}
function valid_token() {
  $return = $_REQUEST[&#39;token&#39;] === $_SESSION[&#39;token&#39;] ? true : false;
  set_token();
  return $return;
}
//如果token为空则生成一个token
if(!isset($_SESSION[&#39;token&#39;]) || $_SESSION[&#39;token&#39;]==&#39;&#39;) {
  set_token();
}
if(isset($_POST[&#39;test&#39;])){
  if(!valid_token()){
    echo "token error";
  }else{
    echo &#39;成功提交,Value:&#39;.$_POST[&#39;test&#39;];
  }
}
?>
<form method="post" action="">
  <input type="hidden" name="token" value="<?php echo $_SESSION[&#39;token&#39;]?>">
  <input type="text" name="test" value="Default">
  <input type="submit" value="提交" />
</form>

<span style="margin:0px;padding:0px;"></span>

上面的比较简单一点的方法,下面的代码更加安全一点.

Token.php


<?php
/*
 * Created on 2013-3-25
 *
 * To change the template for this generated file go to
 * Window - Preferences - PHPeclipse - PHP - Code Templates
 */
function getToken($len = 32, $md5 = true) {
  # Seed random number generator
  # Only needed for PHP versions prior to 4.2
  mt_srand((double) microtime() * 1000000);
  # Array of characters, adjust as desired
  $chars = array (
    &#39;Q&#39;,
    &#39;@&#39;,
    &#39;8&#39;,
    &#39;y&#39;,
    &#39;%&#39;,
    &#39;^&#39;,
    &#39;5&#39;,
    &#39;Z&#39;,
    &#39;(&#39;,
    &#39;G&#39;,
    &#39;_&#39;,
    &#39;O&#39;,
    &#39;`&#39;,
    &#39;S&#39;,
    &#39;-&#39;,
    &#39;N&#39;,
    &#39;<&#39;,
    &#39;D&#39;,
    &#39;{&#39;,
    &#39;}&#39;,
    &#39;[&#39;,
    &#39;]&#39;,
    &#39;h&#39;,
    &#39;;&#39;,
    &#39;W&#39;,
    &#39;.&#39;,
    &#39;/&#39;,
    &#39;|&#39;,
    &#39;:&#39;,
    &#39;1&#39;,
    &#39;E&#39;,
    &#39;L&#39;,
    &#39;4&#39;,
    &#39;&&#39;,
    &#39;6&#39;,
    &#39;7&#39;,
    &#39;#&#39;,
    &#39;9&#39;,
    &#39;a&#39;,
    &#39;A&#39;,
    &#39;b&#39;,
    &#39;B&#39;,
    &#39;~&#39;,
    &#39;C&#39;,
    &#39;d&#39;,
    &#39;>&#39;,
    &#39;e&#39;,
    &#39;2&#39;,
    &#39;f&#39;,
    &#39;P&#39;,
    &#39;g&#39;,
    &#39;)&#39;,
    &#39;?&#39;,
    &#39;H&#39;,
    &#39;i&#39;,
    &#39;X&#39;,
    &#39;U&#39;,
    &#39;J&#39;,
    &#39;k&#39;,
    &#39;r&#39;,
    &#39;l&#39;,
    &#39;3&#39;,
    &#39;t&#39;,
    &#39;M&#39;,
    &#39;n&#39;,
    &#39;=&#39;,
    &#39;o&#39;,
    &#39;+&#39;,
    &#39;p&#39;,
    &#39;F&#39;,
    &#39;q&#39;,
    &#39;!&#39;,
    &#39;K&#39;,
    &#39;R&#39;,
    &#39;s&#39;,
    &#39;c&#39;,
    &#39;m&#39;,
    &#39;T&#39;,
    &#39;v&#39;,
    &#39;j&#39;,
    &#39;u&#39;,
    &#39;V&#39;,
    &#39;w&#39;,
    &#39;,&#39;,
    &#39;x&#39;,
    &#39;I&#39;,
    &#39;$&#39;,
    &#39;Y&#39;,
    &#39;z&#39;,
    &#39;*&#39;
  );
  # Array indice friendly number of chars;
  $numChars = count($chars) - 1;
  $token = &#39;&#39;;
  # Create random token at the specified length
  for ($i = 0; $i < $len; $i++)
    $token .= $chars[mt_rand(0, $numChars)];
  # Should token be run through md5?
  if ($md5) {
    # Number of 32 char chunks
    $chunks = ceil(strlen($token) / 32);
    $md5token = &#39;&#39;;
    # Run each chunk through md5
    for ($i = 1; $i <= $chunks; $i++)
      $md5token .= md5(substr($token, $i * 32 - 32, 32));
    # Trim the token
    $token = substr($md5token, 0, $len);
  }
  return $token;
}
?>

<span style="margin:0px;padding:0px;"></span>

<?php
include_once("token.php");
$token = getToken();
session_start();
$_SESSION[&#39;token&#39;] = $token;
?>
<form action="action.php" method="post"
<input type="hidden" name="token" value="<?=$token?>" />
<!-- 其他input submit之类的 -->
</form>

<span style="margin:0px;padding:0px;"><p style="margin-bottom:0px;clear:both;min-height:1em;color:rgb(62,62,62);font-family:'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;line-height:25.6px;background-color:rgb(255,255,255);"></p></span>


<?php
session_start();
if($_POST[&#39;token&#39;] == $_SESSION[&#39;token&#39;]){
  unset($_SESSION[&#39;token&#39;]);
  echo "这是一个正常的提交请求";
}else{
  echo "这是一个非法的提交请求";
}
?>

<span style="margin:0px;padding:0px;"></span>

form.php

<span style="margin:0px;padding:0px;"></span>


action.php


<span style="margin:0px;padding:0px;"></span>

<span style="margin:0px;padding:0px;"></span>

Verwandte Empfehlungen:

Das Problem der Verwendung von Variablen zur Darstellung des PHP-Formularnamenwerts

Detaillierte Erläuterung des Beispiels für den asynchronen Upload einer PHP-Formulardatei im Iframe



Das obige ist der detaillierte Inhalt vonPHP-Formular verhindert wiederholte Übermittlung (Anti-CSRF-Sicherheitslücke). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn