VYPR
Critical severityNVD Advisory· Published Dec 23, 2022· Updated Apr 15, 2025

CVE-2022-47945

CVE-2022-47945

Description

ThinkPHP Framework before 6.0.14 allows local file inclusion via the lang parameter when the language pack feature is enabled (lang_switch_on=true). An unauthenticated and remote attacker can exploit this to execute arbitrary operating system commands, as demonstrated by including pearcmd.php.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CVE-2022-47945 allows unauthenticated remote attackers to achieve local file inclusion and RCE in ThinkPHP prior to 6.0.14 via the lang parameter when language packs are enabled.

Vulnerability

Details

CVE-2022-47945 is a local file inclusion vulnerability in the ThinkPHP framework versions before 6.0.14. The flaw resides in the language pack feature (lang_switch_on=true). When this feature is enabled, the framework's detect() method in the language handling component does not properly sanitize user-supplied input passed through the lang parameter (or via HTTP headers and cookies), allowing directory traversal sequences to reach arbitrary files on the server [1][2][3]. The vulnerable code was removed in commit c4acb8b, which deleted the deprecated detect() method and its insecure handling of the language variable [3].

Exploitation

An unauthenticated remote attacker can exploit this by sending a crafted request with a lang parameter containing path traversal sequences, such as ../../../public/plugins/pearcmd.php. No authentication or special network position is required; the attacker only needs the target to have the language pack feature enabled [1][2]. The official advisory demonstrates that including the pearcmd.php file from a PHP installation (which is not present by default in all configurations but can be leveraged if available) allows the attacker to execute arbitrary operating system commands [1]. The vulnerability affects ThinkPHP versions 6.0.1 through 6.0.13, as well as 5.0.x and 5.1.x when the language pack is enabled [2].

Impact

Successful exploitation leads to arbitrary file inclusion, which an attacker can further weaponize into remote code execution (RCE). By including a file like pearcmd.php, the attacker can pass arguments to execute system commands, potentially gaining full control over the affected server [1][2]. Given the unauthenticated and remote nature, this vulnerability is critical for any exposed ThinkPHP application with the language pack feature turned on.

Mitigation

The vulnerability is patched in ThinkPHP framework version 6.0.14, released in October 2022 [1][4]. Users must upgrade to at least 6.0.14 or, if unable to upgrade, disable the language pack feature by removing the \think\middleware\LoadLangPack::class middleware entry from the application's middleware configuration [2]. Versions 5.x are also affected and may require manual patching or disabling the language pack as a workaround.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
topthink/frameworkPackagist
< 6.0.146.0.14

Affected products

2

Patches

1
c4acb8b4001b

删除废弃方法 优化多语言检测

https://github.com/top-think/frameworkthinkphpSep 14, 2022via ghsa
2 files changed · +13 67
  • src/think/Lang.php+0 54 modified
    @@ -287,58 +287,4 @@ public function get(string $name = null, array $vars = [], string $range = '')
             return $value;
         }
     
    -    /**
    -     * 自动侦测设置获取语言选择
    -     * @deprecated
    -     * @access public
    -     * @param Request $request
    -     * @return string
    -     */
    -    public function detect(Request $request): string
    -    {
    -        // 自动侦测设置获取语言选择
    -        $langSet = '';
    -
    -        if ($request->get($this->config['detect_var'])) {
    -            // url中设置了语言变量
    -            $langSet = strtolower($request->get($this->config['detect_var']));
    -        } elseif ($request->header($this->config['header_var'])) {
    -            // Header中设置了语言变量
    -            $langSet = strtolower($request->header($this->config['header_var']));
    -        } elseif ($request->cookie($this->config['cookie_var'])) {
    -            // Cookie中设置了语言变量
    -            $langSet = strtolower($request->cookie($this->config['cookie_var']));
    -        } elseif ($request->server('HTTP_ACCEPT_LANGUAGE')) {
    -            // 自动侦测浏览器语言
    -            $match = preg_match('/^([a-z\d\-]+)/i', $request->server('HTTP_ACCEPT_LANGUAGE'), $matches);
    -            if ($match) {
    -                $langSet = strtolower($matches[1]);
    -                if (isset($this->config['accept_language'][$langSet])) {
    -                    $langSet = $this->config['accept_language'][$langSet];
    -                }
    -            }
    -        }
    -
    -        if (empty($this->config['allow_lang_list']) || in_array($langSet, $this->config['allow_lang_list'])) {
    -            // 合法的语言
    -            $this->range = $langSet;
    -        }
    -
    -        return $this->range;
    -    }
    -
    -    /**
    -     * 保存当前语言到Cookie
    -     * @deprecated
    -     * @access public
    -     * @param Cookie $cookie Cookie对象
    -     * @return void
    -     */
    -    public function saveToCookie(Cookie $cookie)
    -    {
    -        if ($this->config['use_cookie']) {
    -            $cookie->set($this->config['cookie_var'], $this->range);
    -        }
    -    }
    -
     }
    
  • src/think/middleware/LoadLangPack.php+13 13 modified
    @@ -70,33 +70,33 @@ protected function detect(Request $request): string
     
             if ($request->get($this->config['detect_var'])) {
                 // url中设置了语言变量
    -            $langSet = strtolower($request->get($this->config['detect_var']));
    +            $langSet = $request->get($this->config['detect_var']);
             } elseif ($request->header($this->config['header_var'])) {
                 // Header中设置了语言变量
    -            $langSet = strtolower($request->header($this->config['header_var']));
    +            $langSet = $request->header($this->config['header_var']);
             } elseif ($request->cookie($this->config['cookie_var'])) {
                 // Cookie中设置了语言变量
    -            $langSet = strtolower($request->cookie($this->config['cookie_var']));
    +            $langSet = $request->cookie($this->config['cookie_var']);
             } elseif ($request->server('HTTP_ACCEPT_LANGUAGE')) {
                 // 自动侦测浏览器语言
    -            $match = preg_match('/^([a-z\d\-]+)/i', $request->server('HTTP_ACCEPT_LANGUAGE'), $matches);
    -            if ($match) {
    -                $langSet = strtolower($matches[1]);
    -                if (isset($this->config['accept_language'][$langSet])) {
    -                    $langSet = $this->config['accept_language'][$langSet];
    -                }
    +            $langSet = $request->server('HTTP_ACCEPT_LANGUAGE');
    +        }
    +
    +        if (preg_match('/^([a-z\d\-]+)/i', $langSet, $matches)) {
    +            $langSet = strtolower($matches[1]);
    +            if (isset($this->config['accept_language'][$langSet])) {
    +                $langSet = $this->config['accept_language'][$langSet];
                 }
             }
     
             if (empty($this->config['allow_lang_list']) || in_array($langSet, $this->config['allow_lang_list'])) {
                 // 合法的语言
    -            $range = $langSet;
    -            $this->lang->setLangSet($range);
    +            $this->lang->setLangSet($langSet);
             } else {
    -            $range = $this->lang->getLangSet();
    +            $langSet = $this->lang->getLangSet();
             }
     
    -        return $range;
    +        return $langSet;
         }
     
         /**
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.