@@ -26,29 +26,69 @@ For example this plugin treats all variables named `$bad_data` as taint sources.
26
26
namespace Psalm\Example\Plugin;
27
27
28
28
use PhpParser\Node\Expr\Variable;
29
+ use Psalm\Codebase;
29
30
use Psalm\Plugin\EventHandler\AddTaintsInterface;
30
31
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
31
32
use Psalm\Type\TaintKind;
32
- use Psalm\Type\TaintKindGroup;
33
33
34
34
/**
35
- * Add input taints to all variables named 'bad_data'
35
+ * Add input taints to all variables named 'bad_data' or 'even_badder_data'.
36
+ *
37
+ * RemoveTaintsInterface is also available to remove taints.
36
38
*/
37
39
class TaintBadDataPlugin implements AddTaintsInterface
38
40
{
41
+ private static int $myCustomTaint;
42
+ private static int $myCustomTaintAlias;
43
+ /**
44
+ * Must be called by the PluginEntryPointInterface (__invoke) of your plugin.
45
+ */
46
+ public static function init(Codebase $codebase): void
47
+ {
48
+ // Register a new custom taint
49
+ // The taint name may be used in @psalm-taint-* annotations in the code.
50
+ self::$myCustomTaint = $codebase->getOrRegisterTaint("my_custom_taint");
51
+
52
+ // Register a taint alias that combines multiple pre-registered taint types
53
+ // Taint alias names may be used in @psalm-taint-* annotations in the code.
54
+ self::$myCustomTaintAlias = $codebase->registerTaintAlias(
55
+ "my_custom_taint_alias",
56
+ self::$myCustomTaint | TaintKind::ALL_INPUT
57
+ );
58
+ }
59
+
39
60
/**
40
61
* Called to see what taints should be added
41
62
*
42
- * @return int-mask-of< TaintKind:: * >
63
+ * @return int A bitmap of taint from the IDs
43
64
*/
44
65
public static function addTaints(AddRemoveTaintsEvent $event): int
45
66
{
46
67
$expr = $event->getExpr();
47
68
48
69
if ($expr instanceof Variable && $expr->name === 'bad_data') {
49
- return TaintKindGroup::ALL_INPUT;
70
+ return TaintKind::ALL_INPUT;
71
+ }
72
+
73
+ if ($expr instanceof Variable && $expr->name === 'even_badder_data') {
74
+ return self::$myCustomTaint;
75
+ }
76
+
77
+ if ($expr instanceof Variable && $expr->name === 'even_badder_data_2') {
78
+ return self::$myCustomTaintAlias;
79
+ }
80
+
81
+ if ($expr instanceof Variable && $expr->name === 'secret_even_badder_data_3') {
82
+ // Combine taints using |
83
+ return self::$myCustomTaintAlias | USER_SECRET;
84
+ }
85
+
86
+ if ($expr instanceof Variable && $expr->name === 'bad_data_but_ok_cookie') {
87
+ // Remove taints using & and ~ to negate a taint (group)
88
+ return self::$myCustomTaintAlias & ~TaintKind::INPUT_COOKIE;
50
89
}
51
90
91
+ // No taints
52
92
return 0;
53
93
}
54
94
}
0 commit comments