Coordinated Disclosure Timeline

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

v1.577.0

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

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.