An Error Was Encountered The URI you submitted has disallowed characters.
訪問類似 /search/q=php+mysql/@user 或 /api/v1/users/email@domain.com 時觸發。
CodeIgniter 預設在 application/config/config.php 中限制 URI 允許字符:
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
任何不在該白名單內的字符(如 @、#、[、]、中文、Emoji)都會被 CI_URI::_filter_uri() 拒絕。
| 方案 | 代碼 | 優點 | 缺點/風險 |
|---|---|---|---|
| 擴展白名單(最常用) | $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-\@'; |
簡單、即時生效、無代碼侵入 | 過度放寬可能引入 XSS/注入風險 |
| 關閉過濾(不推薦) | $config['permitted_uri_chars'] = ''; |
完全兼容任意字符 | 繞過框架安全防線,極易導致漏洞 |
| 路由重寫 + Query String | $route['search/(:any)'] = 'search/index/$1';並用 $_GET['q'] 獲取 |
乾淨 URL,參數在 Query String,天然安全 | 需修改路由、前端鏈接生成邏輯 |
| Base64/URL 編碼傳參 | $url = 'search/q/' . rawurlencode($keyword); |
不改配置,字符安全 | URL 變長、可讀性差、需解碼 |
// application/config/config.php $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-@\+'; // 僅加 @ 和 + // 解釋: // a-z 0-9 字母數字 // ~%.:_\- 波浪線、百分號、點、冒號、下劃線、連字符(預設) // @ 郵箱、用戶名常用 // + 空格編碼、搜索詞常用
原則:只添加業務確實需要的字符,避免添加 ' " < > { } | \ ^ ` [ ] 等高風險字符。
若需複雜驗證(如只允許特定路由段包含 @),可擴展 CI_URI:
<?php
// application/core/MY_URI.php
class MY_URI extends CI_URI {
protected function _filter_uri($str)
{
// 針對特定控制器/方法放寬
if (isset($this->segments[1]) && $this->segments[1] === 'api') {
// API 版本段允許點、連字符、下劃線
return parent::_filter_uri($str); // 繼承默認邏輯
}
// 全局放寬 @
$config =& get_config();
$permitted = $config['permitted_uri_chars'] . '@';
return parent::_filter_uri($str); // 實際需覆寫父類私有方法,建議改配置
}
}
注意:_filter_uri 為 private,無法直接覆寫。最佳實踐仍是修改配置或調整 URL 設計。
/test/@#$% 應報錯,/test/user@domain 應通過。$config['enable_query_strings'] = FALSE(預設),避免雙重解析混淆。html_escape() 或 xss_clean()。$this->uri->segment(n) 獲取參數,而非直接 $_GET。Disallowed characters 錯誤,分析是否為攻擊探測。CodeIgniter 4 棄用 permitted_uri_chars,改用路由正則約束:
// app/Config/Routes.php
$routes->get('search/(:segment)', 'Search::index/$1'); // :segment 預設 [^/]+
$routes->get('user/(:any)', 'User::profile/$1'); // :any 匹配任意含 /
// 自定義正則
$routes->add('email/(:segment)', 'User::byEmail/$1', ['as' => 'user.email'])
->where('segment', '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}');
CI4 更靈活、更安全,建議新專案直接使用 CI4。
「URI 包含不允許字符」是 CodeIgniter 內建的安全防線。解決之道:**最小化擴展白名單**、**優先調整 URL 設計(Query String/路由)**、**嚴禁關閉過濾**。配合輸出轉義、輸入驗證、日誌審計,構建纵深防禦。