VYPR
High severityNVD Advisory· Published Jan 29, 2022· Updated Aug 3, 2024

CVE-2022-24124

CVE-2022-24124

Description

Casdoor before 1.13.1 has a SQL injection vulnerability in the query API's field parameter, allowing unauthorized database access.

AI Insight

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

Casdoor before 1.13.1 has a SQL injection vulnerability in the query API's field parameter, allowing unauthorized database access.

Vulnerability

Casdoor versions before 1.13.1 contain a SQL injection vulnerability in the query API, specifically in the GetSession function used for filtering results. The field and value parameters are directly concatenated into SQL queries without proper sanitization, as demonstrated in the api/get-organizations endpoint. The vulnerable code path is reachable when field and value parameters are supplied, and no authentication is required for this API endpoint. [1][2]

Exploitation

An attacker can exploit this vulnerability by sending crafted HTTP requests to the query API (e.g., api/get-organizations) with malicious input in the field parameter. The attacker does not need authentication or any special privileges. By injecting SQL commands into the field parameter, they can manipulate the underlying database query to extract arbitrary data. [1][3]

Impact

Successful exploitation allows an attacker to retrieve sensitive information from the Casdoor database, including user credentials, application configurations, and other stored data. This is a confidentiality impact, potentially leading to full compromise of the identity and access management system. [1][3]

Mitigation

The vulnerability is fixed in Casdoor version 1.13.1, released on January 26, 2022. The fix introduces a filterField validation function that restricts the field parameter to expected values, preventing direct SQL concatenation. Users should upgrade to version 1.13.1 or later. No workarounds were provided for earlier versions. [1][4]

AI Insight generated on May 21, 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
github.com/casdoor/casdoorGo
< 1.13.11.13.1

Affected products

2

Patches

1
5ec0c7a89005

fix: fix the SQL injection vulnerability in field filter (#442)

https://github.com/casdoor/casdoorYixiang ZhaoJan 26, 2022via ghsa
14 files changed · +31 59
  • object/adapter.go+8 3 modified
    @@ -190,12 +190,17 @@ func (a *Adapter) createTable() {
     }
     
     func GetSession(owner string, offset, limit int, field, value, sortField, sortOrder string) *xorm.Session {
    -	session := adapter.Engine.Limit(limit, offset).Where("1=1")
    +	session := adapter.Engine.Prepare()
    +	if offset != -1 && limit != -1 {
    +		session.Limit(limit, offset)
    +	}
     	if owner != "" {
     		session = session.And("owner=?", owner)
     	}
     	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    +		if filterField(field) {
    +			session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    +		}
     	}
     	if sortField == "" || sortOrder == "" {
     		sortField = "created_time"
    @@ -206,4 +211,4 @@ func GetSession(owner string, offset, limit int, field, value, sortField, sortOr
     		session = session.Desc(util.SnakeString(sortField))
     	}
     	return session
    -}
    +}
    \ No newline at end of file
    
  • object/application.go+1 4 modified
    @@ -56,10 +56,7 @@ type Application struct {
     }
     
     func GetApplicationCount(owner, field, value string) int {
    -	session := adapter.Engine.Where("owner=?", owner)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession(owner, -1, -1, field, value, "", "")
     	count, err := session.Count(&Application{})
     	if err != nil {
     		panic(err)
    
  • object/cert.go+1 4 modified
    @@ -53,10 +53,7 @@ func GetMaskedCerts(certs []*Cert) []*Cert {
     }
     
     func GetCertCount(owner, field, value string) int {
    -	session := adapter.Engine.Where("owner=?", owner)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession(owner, -1, -1, field, value, "", "")
     	count, err := session.Count(&Cert{})
     	if err != nil {
     		panic(err)
    
  • object/check.go+9 1 modified
    @@ -23,10 +23,14 @@ import (
     	goldap "github.com/go-ldap/ldap/v3"
     )
     
    -var reWhiteSpace *regexp.Regexp
    +var (
    +	reWhiteSpace     *regexp.Regexp
    +	reFieldWhiteList *regexp.Regexp
    +)
     
     func init() {
     	reWhiteSpace, _ = regexp.Compile(`\s`)
    +	reFieldWhiteList, _ = regexp.Compile(`^[A-Za-z0-9]+$`)
     }
     
     func CheckUserSignup(application *Application, organization *Organization, username string, password string, displayName string, email string, phone string, affiliation string) string {
    @@ -179,3 +183,7 @@ func CheckUserPassword(organization string, username string, password string) (*
     
     	return user, ""
     }
    +
    +func filterField(field string) bool {
    +	return reFieldWhiteList.MatchString(field)
    +}
    \ No newline at end of file
    
  • object/organization.go+1 6 modified
    @@ -15,8 +15,6 @@
     package object
     
     import (
    -	"fmt"
    -
     	"github.com/casdoor/casdoor/cred"
     	"github.com/casdoor/casdoor/util"
     	"xorm.io/core"
    @@ -39,10 +37,7 @@ type Organization struct {
     }
     
     func GetOrganizationCount(owner, field, value string) int {
    -	session := adapter.Engine.Where("owner=?", owner)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession(owner, -1, -1, field, value, "", "")
     	count, err := session.Count(&Organization{})
     	if err != nil {
     		panic(err)
    
  • object/permission.go+1 4 modified
    @@ -39,10 +39,7 @@ type Permission struct {
     }
     
     func GetPermissionCount(owner, field, value string) int {
    -	session := adapter.Engine.Where("owner=?", owner)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession(owner, -1, -1, field, value, "", "")
     	count, err := session.Count(&Permission{})
     	if err != nil {
     		panic(err)
    
  • object/provider.go+1 4 modified
    @@ -81,10 +81,7 @@ func GetMaskedProviders(providers []*Provider) []*Provider {
     }
     
     func GetProviderCount(owner, field, value string) int {
    -	session := adapter.Engine.Where("owner=?", owner)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession(owner, -1, -1, field, value, "", "")
     	count, err := session.Count(&Provider{})
     	if err != nil {
     		panic(err)
    
  • object/record.go+1 4 modified
    @@ -102,10 +102,7 @@ func AddRecord(record *Record) bool {
     }
     
     func GetRecordCount(field, value string) int {
    -	session := adapter.Engine.Where("1=1")
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession("", -1, -1, field, value, "", "")
     	count, err := session.Count(&Record{})
     	if err != nil {
     		panic(err)
    
  • object/resource.go+2 5 modified
    @@ -40,11 +40,8 @@ type Resource struct {
     }
     
     func GetResourceCount(owner, user, field, value string) int {
    -	session := adapter.Engine.Where("owner=? and user=?", owner, user)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    -	count, err := session.Count(&Resource{})
    +	session := GetSession(owner, -1, -1, field, value, "", "")
    +	count, err := session.Count(&Resource{User: user})
     	if err != nil {
     		panic(err)
     	}
    
  • object/role.go+1 4 modified
    @@ -33,10 +33,7 @@ type Role struct {
     }
     
     func GetRoleCount(owner, field, value string) int {
    -	session := adapter.Engine.Where("owner=?", owner)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession(owner, -1, -1, field, value, "", "")
     	count, err := session.Count(&Role{})
     	if err != nil {
     		panic(err)
    
  • object/syncer.go+1 4 modified
    @@ -56,10 +56,7 @@ type Syncer struct {
     }
     
     func GetSyncerCount(owner, field, value string) int {
    -	session := adapter.Engine.Where("owner=?", owner)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession(owner, -1, -1, field, value, "", "")
     	count, err := session.Count(&Syncer{})
     	if err != nil {
     		panic(err)
    
  • object/token.go+1 4 modified
    @@ -57,10 +57,7 @@ type TokenWrapper struct {
     }
     
     func GetTokenCount(owner, field, value string) int {
    -	session := adapter.Engine.Where("owner=?", owner)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession(owner, -1, -1, field, value, "", "")
     	count, err := session.Count(&Token{})
     	if err != nil {
     		panic(err)
    
  • object/user.go+2 8 modified
    @@ -89,10 +89,7 @@ type User struct {
     }
     
     func GetGlobalUserCount(field, value string) int {
    -	session := adapter.Engine.Where("1=1")
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession("", -1, -1, field, value, "", "")
     	count, err := session.Count(&User{})
     	if err != nil {
     		panic(err)
    @@ -123,10 +120,7 @@ func GetPaginationGlobalUsers(offset, limit int, field, value, sortField, sortOr
     }
     
     func GetUserCount(owner, field, value string) int {
    -	session := adapter.Engine.Where("owner=?", owner)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession(owner, -1, -1, field, value, "", "")
     	count, err := session.Count(&User{})
     	if err != nil {
     		panic(err)
    
  • object/webhook.go+1 4 modified
    @@ -43,10 +43,7 @@ type Webhook struct {
     }
     
     func GetWebhookCount(owner, field, value string) int {
    -	session := adapter.Engine.Where("owner=?", owner)
    -	if field != "" && value != "" {
    -		session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
    -	}
    +	session := GetSession(owner, -1, -1, field, value, "", "")
     	count, err := session.Count(&Webhook{})
     	if err != nil {
     		panic(err)
    

Vulnerability mechanics

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

References

7

News mentions

0

No linked articles in our index yet.