Coordinated Disclosure Timeline
- 2024-03-21: Casdoor emailed in reference to the vulnerabilities.
- 2024-04-05: Casdoor acknowledges receipt of email and requests a PR for fixes.
- 2024-04-18: GitHub Security Lab’s researcher responds they don’t have capacity to suggest a PR, but instead provides suggestions on how to fix the issues through pseudocode and explanations.
- 2024-05-20: GHSL reminds maintainer of our 90 day disclosure and offers to answers any questions or concerns. No response from maintainer.
- 2024-07-15: GHSL reminds maintainer that it is past the 90 day policy and that advisories will be published soon if no efforts are made to fix the vulnerabilities. No response from maintainer.
- 2024-08-14: Advisories published.
Summary
Casdoor is vulnerable to a CORS misconfiguration and a reflected Cross-Site Scripting (XSS) vulnerability, both of which may allow an attacker to take actions on behalf of the signed-in user.
Project
casdoor
Tested Version
Details
Issue 1: CORS misconfiguration (GHSL-2024-035
)
A logic vulnerability exists in the beego filter CorsFilter
that allows any website to make cross domain requests to casdoor as the logged in user.
func CorsFilter(ctx *context.Context) {
origin := ctx.Input.Header(headerOrigin)
originConf := conf.GetConfigString("origin")
originHostname := getHostname(origin)
host := removePort(ctx.Request.Host)
if strings.HasPrefix(origin, "http://localhost") || strings.HasPrefix(origin, "https://localhost") || strings.HasPrefix(origin, "http://127.0.0.1") || strings.HasPrefix(origin, "http://casdoor-app") || strings.Contains(origin, ".chromiumapp.org") {
setCorsHeaders(ctx, origin)
return
}
func setCorsHeaders(ctx *context.Context, origin string) {
ctx.Output.Header(headerAllowOrigin, origin)
ctx.Output.Header(headerAllowMethods, "POST, GET, OPTIONS, DELETE")
ctx.Output.Header(headerAllowHeaders, "Content-Type, Authorization")
ctx.Output.Header(headerAllowCredentials, "true")
if ctx.Input.Method() == "OPTIONS" {
ctx.ResponseWriter.WriteHeader(http.StatusOK)
}
}
Due to the a logic error in checking only for a prefix when authenticating the Origin header, any domain can create a valid subdomain with a valid subdomain prefix (Ex: localhost.example.com), allowing the website to make requests to Casdoor as the current signed-in user.
This vulnerability was found with the help of CodeQL’s Cors Misconfiguration Query
Impact
This issue may lead to Account Takeover
. An attacker may be able to make unauthorized actions on behalf of the current user.
Issue 2: Reflected XSS in QrCodePage.js
(GHSL-2024-036
)
The casdoor purchase URL that is created to generate a WechatPay QR code is vulnerable to reflected XSS.
class QrCodePage extends React.Component {
constructor(props) {
super(props);
const params = new URLSearchParams(window.location.search);
this.state = {
classes: props,
owner: props.owner ?? (props.match?.params?.owner ?? null),
paymentName: props.paymentName ?? (props.match?.params?.paymentName ?? null),
providerName: props.providerName ?? params.get("providerName"),
payUrl: props.payUrl ?? params.get("payUrl"),
successUrl: props.successUrl ?? params.get("successUrl"),
provider: props.provider ?? null,
payment: null,
timer: null,
};
}
...
const notifyTask = async() => {
try {
const res = await PaymentBackend.notifyPayment(this.state.owner, this.state.paymentName);
if (res.status !== "ok") {
throw new Error(res.msg);
}
const payment = res.data;
if (payment.state !== "Created") {
Setting.goToLink(this.state.successUrl); <----- possible attacker provided parameter used to redirect user
}
} catch (err) {
Setting.showMessage("error", err.message);
return ;
}
};
this.setState({
timer: setTimeout(async() => {
await notifyTask();
this.setNotifyTask();
}, 2000),
});
}
When purchasing an item through casdoor, the product page allows you to pay via wechat pay. When using wechat pay, a QR code with the wechat pay link is displayed on the payment page, hosted on the domain of casdoor. This page takes a query parameter from the url successUrl
, and redirects the user to that url after a successful purchase. Because the user has no reason to think that the payment page contains sensitive information, they may share it with other or can be social engineered into sending it to others. An attacker can then craft the casdoor link with a special url and send it back to the user, and once payment has gone though an XSS attack occurs.
This vulnerability was found with the help of CodeQL’s Reflected XSS Query
Impact
This issue may lead to Account Takeover
.
CVE
- CVE-2024-41657 - GHSL-2024-035
- CVE-2024-41658 - GHSL-2024-036
Credit
These issues were discovered and reported by GHSL team member @Kwstubbs (Kevin Stubbings).
Contact
You can contact the GHSL team at securitylab@github.com
, please include a reference to GHSL-2024-035
or GHSL-2024-036
in any communication regarding these issues.