数据清理:带有代码示例的最佳实践


15

我试图了解数据清理(不是数据验证)以帮助我为WordPress编写安全主题。我搜索了Internet,试图为主题开发人员找到一份详细的最佳实践指南。我遇到了一些资源,包括名为“数据验证”的法典页面,尽管没有一个对我有用。该法典页面列出了可用的消毒功能,其用法以及它们的作用,但是无法解释为什么您要使用另一个消毒功能,或者在什么情况下使用特定的消毒功能。这篇文章的目的是要求每个人都提供不良/未经消毒的代码示例,以及如何对其进行重写以进行适当的消毒。这可以是用于清理帖子标题或帖子缩略图src的通用代码,也可以是用于处理以下内容的精致代码:$_POST Ajax请求的数据。

另外,我想知道WordPress用于添加/更新数据库的功能(例如,下面代码块中提到的功能)是否会自动为您完成清理工作?如果是,那么当您采取其他措施来清理发送到这些WordPress函数的数据时,是否会有例外?

add_user_meta
update_user_meta
add_post_meta
update_post_meta
//just to name a few

另外,在PHP中回显HTML与在HTML内联中与PHP内联时,是否需要以不同的方式进行清理?为了更清楚我的要求,以下是代码:

<?php echo '<div class="some-div ' . $another_class . '" data-id="' . $id . '" >' . $text . '</div>'; ?>

<div class="some-div <?php echo $another_class; ?>" data-id="<?php echo $id; ?>"><?php echo $text; ?></div>

上面的两个语句实现了同一件事。但是是否需要以不同的方式来对待它们?


1
如果我们知道您要消毒的内容,可能会有所帮助。主题用于呈现数据...您只需要清理用户提交给您的数据,提交通常由插件处理。
EAMann

@EAMann转义功能(如esc_attr,esc_html等)用于转义输出。如果我错了,请纠正我。呈现数据意味着您正在输出数据,因此主题中也需要转义。否则,将不需要esc函数。我想了解整个WordPress主题中的清理工作,而不仅限于清理一两个代码片段。
约翰·

“呈现数据意味着您正在输出数据,因此在主题中也需要转义”-否。同样,您只需要转义不信任的数据即可
onetrickpony 2012年

@OneTrickPony对我来说越来越清楚了。绝对要确保我理解这一点—如果我要以HTML输出这些内容,则我将转义注释内容,但不会转义注释ID或帖子ID。抱歉,一个接一个地问您一个问题。
约翰

2
“您只需逃避不信任的数据” –我完全同意。我唯一要补充的是您永远不要信任数据;)
Ian Dunn 2012年

Answers:


12

我认为这个法典页面解释得很好。

最重要和最常用的功能可能是esc_attr。举个例子:

<a href="<?php print $author_url; ?>" title="<?php print $author_name; ?>"> 
  <?php print $author_name; ?>
</a>

如果$author_name包含一个"字符,onclick="do_something();"则会使您的属性关闭,并且如果该字符后跟它,则可能会变得更糟:)

这样做print esc_attr($author_name)可以确保对此类字符进行编码,并且浏览器不会执行不应执行的操作。

在一种情况下,您不需要它:当您期望一个数字时,可以将输入数据转换为整数,例如:

print (int)$_POST['some_number'];


您在此处列出的meta *函数已经考虑过清理数据库存储的输入,因此您不必为此担心。

wpdb->prepare()当您自己执行数据库查询时,需要使用该方法。这是一个例子:

$sql = $wpdb->prepare('
    UPDATE wp_posts SET post_title = %s WHERE ID = %d', 
      $_POST['title'], $_POST['id']);

$wpdb->query($sql);

%s%d关键字将被替换为您的消毒$ _ POST值。

我在WP.org存储库中的许多插件中看到的一个非常常见的错误是将已经准备好的查询传递给它(并且准备不好),例如:

$wpdb->prepare('UPDATE wp_posts SET post_title = \''.$_POST['title'].' WHERE ...

不要这样做:)

另外,在PHP中回显HTML与在HTML内联中与PHP内联时,是否需要以不同的方式进行清理?

上面的两个语句实现了同一件事。但是是否需要以不同的方式来对待它们?

没有。


谢谢你的投入。您的解释确实使我更清楚了。
约翰

还需要一点澄清。如果我在PHP中将字符串传递给var(例如$ var ='string';)并将其作为HTML属性回显,则在回显时我是否要对$ var进行清理。或仅在我从数据库中拉出$ var值时才需要进行清理。
约翰

当以某种方式在屏幕上回显它时
onetrickpony 2012年

因此,如果我正确地理解了您的要求,无论我是将字符串传递到PHP代码中的$ var中,还是从数据库中提取数据并传递到$ var中,都需要我进行esc输出。正确?
约翰·

是的,如果该数据来自用户输入,例如评论作者的姓名。如果通过“在PHP代码中将字符串传递到$ var中”表示您为变量分配了一个已知值,那么显然-不,您不必清理该变量
onetrickpony 2012年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.