D'entrée de texte et de caractères spéciaux et de MySQL
J'ai une simple zone de texte dans un formulaire et je veux stocker en toute sécurité des caractères spéciaux dans la base de données après le POST ou GET et j'utilise le code ci-dessous.
$text=mysql_real_escape_string(htmlspecialchars_decode(stripslashes(trim($_GET["text"])),ENT_QUOTES));
Quand j'ai lu le texte à partir de la base de données et de les mettre en valeur du texte j'utilise le code ci-dessus.
$text=htmlspecialchars($text_from_DB,ENT_QUOTES,'UTF-8',false);
<input type="text" value="<?=$text?>" />
Je suis en train d'enregistrer dans la base de données avec pas de caractères spéciaux (ce qui signifie que je ne veux pas écrire dans le champ de base de données "ou")
En fait lors de l'écriture dans la base de données ne htmlspecialchars_decode
pour le texte.
Lors de l'écriture de la forme de la zone de texte ne htmlspecialchars
pour le texte.
Est-ce la meilleure approche pour la sécurité de l'écriture des caractères spéciaux à la base de données?
Vous devez vous connecter pour publier un commentaire.
Vous avez la bonne idée de conserver le texte dans la base de données raw. Pas sûr de ce que toutes les entités HTML stuff est pour; vous ne devriez pas besoin de faire ça pour une base de données d'insertion.
[La seule raison pour laquelle je peux penser pourquoi vous essayez peut-être de l'entité décoder entrants entrée de la base de données serait si vous trouvez que vous obtenez des références de caractère comme
Š
dans votre soumission d'un formulaire de saisie. Si c'est le cas, c'est parce que l'utilisateur est saisie des caractères qui n'existent pas dans l'encodage utilisé par la page avec le formulaire. Cette forme de codage est totalement faux parce que vous ne pouvez pas distinguer entre l'utilisateur de taper desŠ
et littéralement taperŠ
! Vous devriez éviter cela en utilisant le codage UTF-8 pour l'ensemble de vos pages et le contenu, étant donné que chaque personnage s'intègre dans ce codage.]Des chaînes dans votre script doit toujours être en texte brut avec pas de s'échapper. Cela signifie que vous ne faites rien jusqu'à l'heure de la sortie dans un contexte qui n'est pas simple de texte. Donc, pour les mettre dans une chaîne SQL:
(ou utiliser des requêtes paramétrées pour éviter d'avoir à manuellement échapper.) Quand on met le contenu en HTML:
(vous pouvez définir une fonction d'assistance avec un nom plus court comme
function h($s) { echo htmlspecialchars($s, ENT_QUOTES); }
si vous voulez réduire la quantité de saisie que vous avez à faire dans les modèles.)Et... c'est assez bien. Vous n'avez pas besoin de traiter des chaînes de caractères qui sortent de la base de données, car ils sont déjà brute des chaînes de caractères. Vous n'avez pas besoin de traiter des chaînes d'entrée(*), d'autres que toute demande spécifique de validation de champ que vous voulez faire.
*: eh bien, sauf si
magic_quotes_gpc
est activé, dans ce cas vous ne devezstripslashes()
tout ce qui vient de get/post/cookie, ou, ma bonne option, juste immédiatement échouer:htmlspecialchars($category)
sera écrit pour le HTML entest's categories
, oui. Mais c'est juste un encodage pour le navigateur de lire; la valeur réelle de l'résultant de champ de formulaire dans les DOM esttest's categories
, et c'est ce clair de la chaîne, vous recevrez dans votre$_POST['category']
lorsque le formulaire est soumis.stripslashes
là. Simagic_quotes
est sur (et aujourd'hui, il ne faut jamais, jamais, c'est pourquoi j'ai recommandé immédiatement cesser de fumer si vous avez découvert il allumé) alors vous devez faire de la$_GET
/$_POST
unescaping droit au début du script, pas à la base de données de l'insertion.htmlspecialchars_decode
n'a pas sa place ici; je n'ai aucune idée de pourquoi vous y compris.$_GET
. Si vous avez'
dans la soumission d'un formulaire, c'est parce que l'utilisateur délibérément tapé esperluette-hash-trois-neuf-point-virgule dans le champ et vous devez la laisser comme ça.<input name="x" value="'" />
dans un formulaire. Remarquez comment il affiche une apostrophe dans le domaine dans le navigateur, et envoie une apostrophe à PHP lorsque vous le soumettre. HTML-échappement est seulement un moyen de sortir de la bande de caractères dans le navigateur de Modèle d'Objet de Document. Une fois qu'ils sont là, les fuites ne les reverra plus jamais.Lorsque vous écrire db, utilisez htmlentities mais quand vous lisez à l'arrière, utilisez html_entity_decode fonction.
Au passage, si vous êtes à la recherche pour un peu de sécurité, puis pour les chaînes utilisent mysql_real_escape_string et pour utiliser numéros intval.
Je tiens à souligner deux choses:
il n'y a rien de mal à sauver des personnages comme
'
et"
dans une base de données, SQL injections sont juste une question de manipulation de chaîne, en fait, ils n'ont rien à voir avec SQL ou des bases de données -- le problème seulement repose dans la façon dont la chaîne de requête est construite. Si vous voulez écrire vos propres requêtes (non recommandé), vous n'avez pas à coder chaque apostrophe ou guillemet double: il suffit de s'échapper une fois pour construire un coffre-fort de la chaîne, et de les enregistrer dans la base de données. Une meilleure approche est d'utiliser PDO comme mentionné, ou à l'aide de laextension mysqli
qui permet des requêtes préparées avec les étatshtmlentities()
et des fonctions similaires doivent être utilisés lors de l'envoi des données de sortie vers le navigateur, pas pour l'encodage des données stockées dans une base de données pour au moins deux raisons: tout d'abord, il est inutile, la DB ne se soucie pas des entités html, il contient uniquement des données; d'autre part, vous devriez toujours traiter les données provenant de la base de données comme potentiellement dangereux, donc vous devez l'enregistrer en format "raw" et encodez lors de l'utilisation de ce.mysqli
trop. Le reste des points de toujours se tenir bien.La meilleure approche pour la sécurité de l'écrire à un DB est d'utiliser la PDO couche d'abstraction et d'utiliser des requêtes préparées.
http://www.php.net/manual/en/intro.pdo.php
Un bon tutoriel (je l'ai appris de celui-ci) est
http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html
Cependant, vous pourriez avoir à réécrire beaucoup de votre site juste à le mettre en œuvre. Mais c'est sans doute le plus élégant de la méthode que d'avoir à faire usage de l'ensemble de ces fonctions. De Plus, les requêtes préparées sont en train de devenir, de facto, maintenant. Un autre avantage de ceci est que vous n'avez pas à réécrire vos questions si vous passez à une autre base de données (comme de MySQL vers PostgreSQL). Mais je dirais envisager cette option si vous prévoyez de faire évoluer votre site.