Skip to content

Instantly share code, notes, and snippets.

Last active July 21, 2021 05:28
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
RPCMS CVE Submission

RPCMS CVE Submission

Official Website:,

Version v1.8: (updated on 12th July 2021, latest version)

Audited on 20th July, 2021, credit to Zhang Zhiyi.

The source code can also be downloaded in this gist ( folder

For better understanding of the problems, in-line comments are added in the key parts of source code after // sign.

Vulnerability 1: Admin User Registration

When API is enabled, the registered user is normal user by default. However, user can manually set the role to be admin to register as admin user.

	public function register(){
		$data['username']=!empty(input('post.username')) ? strip_tags(input('post.username')) : '';
		$data['password']=!empty(input('post.password')) ? strip_tags(input('post.password')) : '';
		$data['nickname']=!empty(input('post.nickname')) ? strip_tags(input('post.nickname')) : $data['username'];
		$data['role']=!empty(input('post.role')) ? strip_tags(input('post.role')) : 'member';// normal user access by default

Trigger the vulnerability (0002.jpg) bypass

Vulnerability 2: Stored XSS1

In the following code, $title is displayed directly without sanitizing, resulting in stored XSS. Specifically, it can be triggered at |0| and |1|.

public function index(){
    if(!isset($this->params[1]) || empty($this->params[1])){
    $page=isset($data[1]) ? intval($data[1]) : 1;
        $userId=isset($user2[$data[0]]) ? $user2[$data[0]]['id'] : '';
    if(empty($userId) || !isset($user[$userId])){
    $LogsMod=new LogsMod();
    $title=$user[$userId]['nickname'];// nickname from the user
    $this->setDescription('关于作者'.$title.'的一些文章整理归档'); //|0|
    $this->assign('title',$title.'-'.$this->webConfig['webName']); //|1|
    return $this->display('/list');

It can be seen that variable nickname can be used by the attacker. By tracing the usage of nickname before loading into database:

function update user password: updatePsw

public function updatePsw(){
        return json(array('code'=>-1,'msg'=>'昵称不可为空'));
    if(!empty($password) && $password != $password2){
        return json(array('code'=>-1,'msg'=>'两次密码输入不一致'));
        return json(array('code'=>200,'msg'=>'修改成功','data'=>!empty($password) ? 1 : 0));
    return json(array('code'=>-1,'msg'=>'修改失败,请稍后重试'));

It can be seen that nickname variable is not properly sanitized, taking the direct post input. A stored XSS can be found here.

Trigger the vulnerability: (0001.jpg) xss

## Vulnerability 3: Stored XSS

Similar to vulnerability 2, after enabling API, users can update to variable nickname directly through API without strip tags. Once nickname is updated, a stored xss can be triggered when user view articles.

public function post(){
    $nickname=input('post.nickname'); //no filtering
    if(!empty($password) && $password != $password2){
This file has been truncated, but you can view the full file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment