hitoshura25/cvefixes huggingface dataset:
CVE-2019-1020017 (Ruby, published 2019-07-29T13:15Z)
Description: value: Discourse before 2.3.0 and 2.4.x before 2.4.0.beta3 lacks a confirmation screen when logging in via a user-api OTP.
Severity: MEDIUM (CVSS v3 base score: 5.3)
Weakness: NVD-CWE-noinfo \u2014 Insufficient Information
There is insufficient information about the issue to classify it; details are unkown or unspecified.
Repository: https://github.com/discourse/discourse
Files changed:
app/controllers/session_controller.rb
app/views/session/one_time_password.html.erb
config/locales/server.en.yml
config/routes.rb
spec/requests/session_controller_spec.rb
Commit message: SECURITY: Add confirmation screen when logging in via user-api OTP


Vulnerable code:
    otp_username = $redis.get "otp_#{params[:token]}"
      log_on_user(user)
      $redis.del "otp_#{params[:token]}"
      return redirect_to path("/")
          get "/session/otp/#{token}"

Fixed code:
    @otp_username = otp_username = $redis.get "otp_#{params[:token]}"
      if current_user&.username == otp_username
        $redis.del "otp_#{params[:token]}"
        return redirect_to path("/")
      elsif request.post?
        log_on_user(user)
        $redis.del "otp_#{params[:token]}"
        return redirect_to path("/")
      else
        # Display the form
      end
<%else%>
  <%= form_tag do%>
    <h2><%= t("user_api_key.otp_confirmation.confirm_title", site_name: SiteSetting.title) %></h2>
    <p><%= t("user_api_key.otp_confirmation.logging_in_as", username: @otp_username) %></p>
    <%= submit_tag(t("user_api_key.otp_confirmation.confirm_button"), class: "btn btn-primary") %>
  <%end%>
    otp_confirmation: 
      confirm_title: Continue to %{site_name}
      logging_in_as: Logging in as %{username}
      confirm_button: Finish Login
  post "session/otp/:token" => "session#one_time_password", constraints: { token: /[0-9a-f]+/ }

        post "/session/otp/asd1231dasd123"

        expect(response.status).to eq(404)
        it "should display the form for GET" do
          token = SecureRandom.hex
          $redis.setex "otp_#{token}", 10.minutes, user.username

          get "/session/otp/#{token}"

          expect(response.status).to eq(200)
          expect(response.body).to include(
            I18n.t("user_api_key.otp_confirmation.logging_in_as", username: user.username)
          )
          expect($redis.get("otp_#{token}")).to eq(user.username)

          expect(session[:current_user_id]).to eq(nil)
        end

        it "should redirect on GET if already logged in" do
          sign_in(user)
          token = SecureRandom.hex
          $redis.setex "otp_#{token}", 10.minutes, user.username

          get "/session/otp/#{token}"
          expect(response.status).to eq(302)

          expect($redis.get("otp_#{token}")).to eq(nil)
          expect(session[:current_user_id]).to eq(user.id)
        end

          post "/session/otp/#{token}"
CVE-2021-37633 (JavaScript, published 2021-08-09T20:15Z)
Description: value: Discourse is an open source discussion platform. In versions prior to 2.7.8 rendering of d-popover tooltips can be susceptible to XSS attacks. This vulnerability only affects sites which have modified or disabled Discourse's default Content Security Policy. This issue is patched in the latest `stable` 2.7.8 version of Discourse. As a workaround users may ensure that the Content Security Policy is enabled, and has not been modified in a way which would make it more vulnerable to XSS attacks.
Severity: MEDIUM (CVSS v3 base score: 6.1)
Weakness: CWE-79 \u2014 Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Repository: https://github.com/discourse/discourse
Files changed:
app/assets/javascripts/discourse/app/lib/d-popover.js
app/assets/javascripts/discourse/tests/unit/lib/sanitizer-test.js
app/assets/javascripts/pretty-text/addon/sanitizer.js
Commit message: SECURITY: Sanitize d-popover attributes (#13958)



Vulnerable code:
export const POPOVER_SELECTORS =
  "[data-html-popover], [data-html-tooltip], [data-popover], [data-tooltip]";
  content =
    content ||
    $enteredElement.attr("data-html-popover") ||
    $enteredElement.attr("data-html-tooltip");

          (name.indexOf("data-") === 0 && forTag["data-*"]) ||

Fixed code:
export const POPOVER_SELECTORS = "[data-popover], [data-tooltip]";

    cooked(
      `<div data-value="<something>" data-html-value="<something>"></div>`,
      `<div data-value="&lt;something&gt;"></div>`
    );
          (name.indexOf("data-html-") === -1 &&
            name.indexOf("data-") === 0 &&
            forTag["data-*"]) ||
CVE-2021-37693 (Ruby, published 2021-08-13T16:15Z)
Description: value: Discourse is an open-source platform for community discussion. In Discourse before versions 2.7.8 and 2.8.0.beta4, when adding additional email addresses to an existing account on a Discourse site an email token is generated as part of the email verification process. Deleting the additional email address does not invalidate an unused token which can then be used in other contexts, including reseting a password.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-613 \u2014 Insufficient Session Expiration
According to WASC, "Insufficient Session Expiration is when a web site permits an attacker to reuse old session credentials or session IDs for authorization."
Repository: https://github.com/discourse/discourse
Files changed:
app/models/email_change_request.rb
spec/requests/users_controller_spec.rb
Commit message: SECURITY: Destroy `EmailToken` when `EmailChangeRequest` is destroyed (#13950)



Vulnerable code:
  belongs_to :old_email_token, class_name: 'EmailToken'
  belongs_to :new_email_token, class_name: 'EmailToken'

Fixed code:
  belongs_to :old_email_token, class_name: 'EmailToken', dependent: :destroy
  belongs_to :new_email_token, class_name: 'EmailToken', dependent: :destroy

    it "can destroy associated email tokens" do
      new_email = 'new.n.cool@example.com'
      updater = EmailUpdater.new(guardian: user.guardian, user: user)

      expect { updater.change_to(new_email) }
        .to change { user.email_tokens.count }.by(1)

      expect { delete "/u/#{user.username}/preferences/email.json", params: { email: new_email } }
        .to change { user.email_tokens.count }.by(-1)

      expect(user.email_tokens.first.email).to eq(user.email)
    end
CVE-2021-37693 (Ruby, published 2021-08-13T16:15Z)
Description: value: Discourse is an open-source platform for community discussion. In Discourse before versions 2.7.8 and 2.8.0.beta4, when adding additional email addresses to an existing account on a Discourse site an email token is generated as part of the email verification process. Deleting the additional email address does not invalidate an unused token which can then be used in other contexts, including reseting a password.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-640 \u2014 Weak Password Recovery Mechanism for Forgotten Password
The product contains a mechanism for users to recover or change their passwords without knowing the original password, but the mechanism is weak.
Repository: https://github.com/discourse/discourse
Files changed:
app/models/email_change_request.rb
spec/requests/users_controller_spec.rb
Commit message: SECURITY: Destroy `EmailToken` when `EmailChangeRequest` is destroyed (#13950)



Vulnerable code:
  belongs_to :old_email_token, class_name: 'EmailToken'
  belongs_to :new_email_token, class_name: 'EmailToken'

Fixed code:
  belongs_to :old_email_token, class_name: 'EmailToken', dependent: :destroy
  belongs_to :new_email_token, class_name: 'EmailToken', dependent: :destroy

    it "can destroy associated email tokens" do
      new_email = 'new.n.cool@example.com'
      updater = EmailUpdater.new(guardian: user.guardian, user: user)

      expect { updater.change_to(new_email) }
        .to change { user.email_tokens.count }.by(1)

      expect { delete "/u/#{user.username}/preferences/email.json", params: { email: new_email } }
        .to change { user.email_tokens.count }.by(-1)

      expect(user.email_tokens.first.email).to eq(user.email)
    end
CVE-2022-21642 (Ruby, published 2022-01-05T19:15Z)
Description: value: Discourse is an open source platform for community discussion. In affected versions when composing a message from topic the composer user suggestions reveals whisper participants. The issue has been patched in stable version 2.7.13 and beta version 2.8.0.beta11. There is no workaround for this issue and users are advised to upgrade.
Severity: MEDIUM (CVSS v3 base score: 4.3)
Weakness: CWE-200 \u2014 Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
Repository: https://github.com/discourse/discourse
Files changed:
app/models/user_search.rb
spec/models/user_search_spec.rb
Commit message: SECURITY: only show user suggestions with regular post (#15436)



Vulnerable code:
        .where('users.id IN (SELECT user_id FROM posts WHERE topic_id = ?)', @topic_id)

Fixed code:
        .where('users.id IN (SELECT user_id FROM posts WHERE topic_id = ? AND post_type = ?)', @topic_id, Post.types[:regular])
    fab!(:post8) { Fabricate :post, user: mr_brown, topic: topic2, post_type: Post.types[:whisper] }
    it "does not reveal whisper users" do
      results = search_for("", topic_id: topic2.id)
      expect(results).to eq [mr_blue.username]
    end
CVE-2022-21678 (Ruby, published 2022-01-13T18:15Z)
Description: value: Discourse is an open source discussion platform. Prior to version 2.8.0.beta11 in the `tests-passed` branch, version 2.8.0.beta11 in the `beta` branch, and version 2.7.13 in the `stable` branch, the bios of users who made their profiles private were still visible in the `<meta>` tags on their users' pages. The problem is patched in `tests-passed` version 2.8.0.beta11, `beta` version 2.8.0.beta11, and `stable` version 2.7.13 of Discourse.
Severity: MEDIUM (CVSS v3 base score: 4.3)
Weakness: CWE-863 \u2014 Incorrect Authorization
The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.
Repository: https://github.com/discourse/discourse
Files changed:
lib/guardian/user_guardian.rb
spec/requests/users_controller_spec.rb
Commit message: FIX: Hide user's bio if profile is restricted

The bio was sometimes visible in the meta tags even though it it should
not have been.


Vulnerable code:
    user.trust_level == TrustLevel[0] && anonymous?

Fixed code:
    (user.trust_level == TrustLevel[0] && anonymous?) || !can_see_profile?(user)
    it "should not be able to view a private user profile" do
      user1.user_profile.update!(bio_raw: "Hello world!")
      user1.user_option.update!(hide_profile_and_presence: true)

      get "/u/#{user1.username}"

      expect(response.status).to eq(200)
      expect(response.body).not_to include("Hello world!")
    end
CVE-2022-21678 (Unknown, published 2022-01-13T18:15Z)
Description: value: Discourse is an open source discussion platform. Prior to version 2.8.0.beta11 in the `tests-passed` branch, version 2.8.0.beta11 in the `beta` branch, and version 2.7.13 in the `stable` branch, the bios of users who made their profiles private were still visible in the `<meta>` tags on their users' pages. The problem is patched in `tests-passed` version 2.8.0.beta11, `beta` version 2.8.0.beta11, and `stable` version 2.7.13 of Discourse.
Severity: MEDIUM (CVSS v3 base score: 4.3)
Weakness: CWE-863 \u2014 Incorrect Authorization
The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.
Repository: https://github.com/discourse/discourse
Files changed:
Commit message: SECURITY: Hide user's bio if profile is restricted (#15477)

The bio was sometimes visible in the meta tags even though it it should
not have been.

Vulnerable code:

Fixed code:
CVE-2022-21684 (Ruby, published 2022-01-13T21:15Z)
Description: value: Discourse is an open source discussion platform. Versions prior to 2.7.13 in `stable`, 2.8.0.beta11 in `beta`, and 2.8.0.beta11 in `tests-passed` allow some users to log in to a community before they should be able to do so. A user invited via email to a forum with `must_approve_users` enabled is going to be automatically logged in, bypassing the check that does not allow unapproved users to sign in. They will be able to do everything an approved user can do. If they logout, they cannot log back in. This issue is patched in the `stable` version 2.7.13, `beta` version 2.8.0.beta11, and `tests-passed` version 2.8.0.beta11. One may disable invites as a workaround. Administrators can increase `min_trust_level_to_allow_invite` to reduce the attack surface to more trusted users.
Severity: MEDIUM (CVSS v3 base score: 8.8)
Weakness: CWE-287 \u2014 Improper Authentication
When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
Repository: https://github.com/discourse/discourse
Files changed:
app/controllers/invites_controller.rb
spec/requests/invites_controller_spec.rb
Commit message: SECURITY: Do not sign in unapproved users (#15552)



Vulnerable code:
      log_on_user(user) if user.active?
        if user.active?
          response[:message] = I18n.t('invite.confirm_email')

Fixed code:
      log_on_user(user) if user.active? && user.guardian.can_access_forum?
        if user.active? && user.guardian.can_access_forum?
          response[:message] = if user.active?
            I18n.t('activation.approval_required')
          else
            I18n.t('invite.confirm_email')
          end

      it 'does not log in the user if they were not approved' do
        SiteSetting.must_approve_users = true

        put "/invites/show/#{invite.invite_key}.json", params: { password: SecureRandom.hex, email_token: invite.email_token }

        expect(session[:current_user_id]).to eq(nil)
        expect(response.parsed_body["message"]).to eq(I18n.t('activation.approval_required'))
      end

      it 'does not log in the user if they were not activated' do
        put "/invites/show/#{invite.invite_key}.json", params: { password: SecureRandom.hex }

        expect(session[:current_user_id]).to eq(nil)
        expect(response.parsed_body["message"]).to eq(I18n.t('invite.confirm_email'))
      end
CVE-2022-23546 (Ruby, published 2023-01-05T19:15Z)
Description: value: In version 2.9.0.beta14 of Discourse, an open-source discussion platform, maliciously embedded urls can leak an admin's digest of recent topics, possibly exposing private information. A patch is available for version 2.9.0.beta15. There are no known workarounds for this issue.
Severity: nan (CVSS v3 base score: 5.5)
Weakness: CWE-200 \u2014 Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
Repository: https://github.com/discourse/discourse
Files changed:
app/assets/javascripts/admin/addon/models/email-preview.js
config/routes.rb
spec/requests/admin/email_controller_spec.rb
Commit message: SECURITY: Convert send_digest to a post request (#19746)

Co-authored-by: Isaac Janzen <isaac.janzen@discourse.org>

Vulnerable code:
          get "send-digest" => "email#send_digest"

Fixed code:
      type: "POST",
          post "send-digest" => "email#send_digest"
  describe '#send_digest' do
    context "when logged in as an admin" do
      before { sign_in(admin) }

      it "sends the digest" do
        post "/admin/email/send-digest.json", params: {
          last_seen_at: 1.week.ago, username: admin.username, email: email('previous_replies')
        }
        expect(response.status).to eq(200)
      end
    end
  end
CVE-2022-23549 (Ruby, published 2023-01-05T19:15Z)
Description: value: Discourse is an option source discussion platform. Prior to version 2.8.14 on the `stable` branch and version 2.9.0.beta16 on the `beta` and `tests-passed` branches, users can create posts with raw body longer than the `max_length` site setting by including html comments that are not counted toward the character limit. This issue is patched in versions 2.8.14 and 2.9.0.beta16. There are no known workarounds.
Severity: nan (CVSS v3 base score: 6.5)
Weakness: NVD-CWE-Other \u2014 Other
NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
Repository: https://github.com/discourse/discourse
Files changed:
lib/validators/stripped_length_validator.rb
spec/requests/posts_controller_spec.rb
Commit message: SECURITY: Check the length of raw post body (#19733)

Co-authored-by: Jarek Radosz <jradosz@gmail.com>

Vulnerable code:
    if !value.nil?
      value = get_sanitized_value(value)
      record.errors.add attribute, (I18n.t('errors.messages.too_short', count: range.begin)) if value.length < range.begin
      record.errors.add attribute, (I18n.t('errors.messages.too_long_validation', max: range.end, length: value.length)) if value.length > range.end
      record.errors.add attribute, (I18n.t('errors.messages.blank'))

Fixed code:
    if value.nil?
      record.errors.add attribute, I18n.t('errors.messages.blank')
    elsif value.length > range.end
      record.errors.add attribute, I18n.t('errors.messages.too_long_validation', max: range.end, length: value.length)
      value = get_sanitized_value(value)

      if value.length < range.begin
        record.errors.add attribute, I18n.t('errors.messages.too_short', count: range.begin)
      end

        it "doesn't enqueue replies when the post is too long (including a html comment)" do
          SiteSetting.max_post_length = 10
          raw = "A post <!-- " + ("a" * 3000) + "-->"

          post "/posts.json", params: {
            raw: raw,
            title: "this is the test title for the topic"
          }

          expect(response).not_to be_successful
          parsed = response.parsed_body
          expect(parsed["action"]).not_to eq("enqueued")
        end
CVE-2022-23641 (Ruby, published 2022-02-15T21:15Z)
Description: value: Discourse is an open source discussion platform. In versions prior to 2.8.1 in the `stable` branch, 2.9.0.beta2 in the `beta` branch, and 2.9.0.beta2 in the `tests-passed` branch, users can trigger a Denial of Service attack by posting a streaming URL. Parsing Oneboxes in the background job trigger an infinite loop, which cause memory leaks. This issue is patched in version 2.8.1 of the `stable` branch, 2.9.0.beta2 of the `beta` branch, and 2.9.0.beta2 of the `tests-passed` branch. As a workaround, disable onebox in admin panel completely or specify allow list of domains that will be oneboxed.
Severity: MEDIUM (CVSS v3 base score: 6.5)
Weakness: CWE-835 \u2014 Loop with Unreachable Exit Condition ('Infinite Loop')
The product contains an iteration or loop with an exit condition that cannot be reached, i.e., an infinite loop.
Repository: https://github.com/discourse/discourse
Files changed:
lib/final_destination.rb
spec/components/final_destination_spec.rb
Commit message: SECURITY: Onebox response timeout and size limit (#15927)

Validation to ensure that Onebox request is no longer than 10 seconds and response size is not bigger than 1 MB

Vulnerable code:
      middlewares: middlewares
          Oneboxer.cache_response_body(@uri.to_s, response.body)
        next_url = fetch_canonical_url(response.body)

Fixed code:
  MAX_REQUEST_TIME_SECONDS = 10
  MAX_REQUEST_SIZE_BYTES = 1_048_576 # 1024 * 1024
    request_start_time = Time.now
    response_body = +""
    request_validator = lambda do |chunk, _remaining_bytes, _total_bytes|
      response_body << chunk
      raise Excon::Errors::ExpectationFailed.new("response size too big: #{@uri.to_s}") if response_body.bytesize > MAX_REQUEST_SIZE_BYTES
      raise Excon::Errors::ExpectationFailed.new("connect timeout reached: #{@uri.to_s}") if Time.now - request_start_time > MAX_REQUEST_TIME_SECONDS
    end

      middlewares: middlewares,
      response_block: request_validator
          Oneboxer.cache_response_body(@uri.to_s, response_body)
        next_url = fetch_canonical_url(response_body)
  let(:body_response) do
    {
      status: 200,
      body: "<body>test</body>"
    }
  end

    it 'raises error when response is too big' do
      stub_const(described_class, "MAX_REQUEST_SIZE_BYTES", 1) do
        stub_request(:get, "https://codinghorror.com/blog").to_return(body_response)
        final = FinalDestination.new('https://codinghorror.com/blog', opts.merge(follow_canonical: true))
        expect { final.resolve }.to raise_error(Excon::Errors::ExpectationFailed, "response size too big: https://codinghorror.com/blog")
      end
    end

    it 'raises error when response is too slow' do
      stub_request(:get, "https://codinghorror.com/blog").to_return(lambda { |request| freeze_time(11.seconds.from_now) ; body_response })
      final = FinalDestination.new('https://codinghorror.com/blog', opts.merge(follow_canonical: true))
      expect { final.resolve }.to raise_error(Excon::Errors::ExpectationFailed, "connect timeout reached: https://codinghorror.com/blog")
    end
CVE-2022-31025 (Ruby, published 2022-06-07T15:15Z)
Description: value: Discourse is an open source platform for community discussion. Prior to version 2.8.4 on the `stable` branch and 2.9.0beta5 on the `beta` and `tests-passed` branches, inviting users on sites that use single sign-on could bypass the `must_approve_users` check and invites by staff are always approved automatically. The issue is patched in Discourse version 2.8.4 on the `stable` branch and version `2.9.0.beta5` on the `beta` and `tests-passed` branches. As a workaround, disable invites or increase `min_trust_level_to_allow_invite` to reduce the attack surface to more trusted users.
Severity: MEDIUM (CVSS v3 base score: 5.3)
Weakness: NVD-CWE-Other \u2014 Other
NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
Repository: https://github.com/discourse/discourse
Files changed:
app/models/invite_redeemer.rb
spec/models/invite_redeemer_spec.rb
Commit message: FIX: Approves user when redeeming an invite for invites only sites (#16984)

When a site has `SiteSetting.invite_only` enabled, we create a
`ReviewableUser`record when activating a user if the user is not
approved. Therefore, we need to approve the user when redeeming an
invite.

There are some uncertainties surrounding why a `ReviewableRecord` is
created for a user in an invites only site but this commit does not seek
to address that.

Follow-up to 7c4e2d33fa4b922354c177ffc880a2f2701a91f9

Vulnerable code:
    if SiteSetting.must_approve_users? && EmailValidator.can_auto_approve_user?(user.email)
      user.email_tokens.create!(email: user.email, scope: EmailToken.scopes[:signup])

Fixed code:
    if (!SiteSetting.must_approve_users && SiteSetting.invite_only) ||
       (SiteSetting.must_approve_users? && EmailValidator.can_auto_approve_user?(user.email))

  fab!(:admin) { Fabricate(:admin) }

    it "approves and actives user when redeeming an invite with email token and SiteSetting.invite_only is enabled" do
      SiteSetting.invite_only = true
      Jobs.run_immediately!

      invite = Fabricate(:invite,
        invited_by: admin,
        email: 'walter.white@email.com',
        emailed_status: Invite.emailed_status_types[:sent],
      )

      user = InviteRedeemer.create_user_from_invite(
        invite: invite,
        email: invite.email,
        email_token: invite.email_token,
        username: 'walter',
        name: 'Walter White'
      )

      expect(user.name).to eq("Walter White")
      expect(user.username).to eq("walter")
      expect(user.email).to eq("walter.white@email.com")
      expect(user.approved).to eq(true)
      expect(user.active).to eq(true)
      expect(ReviewableUser.count).to eq(0)
    end