You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Doctrine Expr的literal函数是否内部使用预准备语句?两种用法安全性确认

Are These Doctrine QueryBuilder literal() Usages Safe Against SQL/Wildcard Injection?

Great question—let’s break down both scenarios to verify their safety, and clarify how literal() works compared to standard parameter binding.

Scenario 1: Numeric Arithmetic Comparison

$expr = $queryBuilder->expr()->orX();
$expr->add($queryBuilder->expr()->lt(
    'entityName.field - ' . $queryBuilder->expr()->literal($rule->getValue()),
    $queryBuilder->expr()->literal(self::MAX_ERROR)
));

This is fully safe against SQL injection. Here’s why:

  • Doctrine’s literal() method escapes values according to your database’s platform rules (e.g., MySQL, PostgreSQL) before embedding them directly into the SQL string. For numeric inputs, this ensures the value is treated as a literal number, blocking any malicious SQL from being injected.
  • Even though self::MAX_ERROR is a constant, wrapping it in literal() is harmless—it adds consistency and ensures the value is formatted correctly for your database.
  • Wildcard injection isn’t a concern here, since we’re performing a numeric comparison, not a LIKE query.

Scenario 2: LIKE Query with Escaped Wildcards

$expr = $queryBuilder->expr()->orX();
$expr->add($queryBuilder->expr()->like(
    'entityName.field',
    $queryBuilder->expr()->literal(addcslashes($rule->getValue(), '%_') . '%')
));

This is also safe against both SQL injection and wildcard injection, let’s break down the two layers of protection:

  1. SQL Injection Defense: literal() handles escaping of SQL-specific characters (like single quotes) to prevent attackers from breaking out of the string literal and injecting arbitrary SQL.
  2. Wildcard Injection Defense: You’re using addcslashes($rule->getValue(), '%_') to escape the wildcard characters % and _ before appending the trailing % for the LIKE match. This ensures user input like %test% is treated as a literal string (with escaped %s) instead of matching any string containing "test". The literal() method preserves this escaping when embedding the value into the SQL.

A Quick Note: literal() vs Parameter Binding

While both usages are safe, keep in mind that parameter binding (via setParameters()) is generally the preferred approach in Doctrine. It leverages database prepared statements, which are more secure in edge cases and can boost performance via query caching. That said, literal() is a valid tool for scenarios where parameter binding isn’t feasible (like your arithmetic expression), and when used correctly, it’s just as effective against injection.

内容的提问来源于stack exchange,提问作者zozo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:52:23