Security Advisories (1)
CVE-2026-19349 (2026-08-16)

Lemonldap::NG::Portal versions from 2.0.0 before 2.16.9, from 2.17.0 before 2.21.5, from 2.22.0 before 2.23.3 for Perl allow authentication bypass via an OAuth2 state parameter stored as an SSO session in the GitHub and LinkedIn backends. Before redirecting to the identity provider, extractFormInfo() creates the state session with the positional call `getApacheSession( undef, 1, 0, 'GitHubState' )`. getApacheSession() takes a session id followed by a named argument hash, so the trailing arguments become that hash, `kind` defaults to SSO, and the state is written to the global session storage as a regular SSO session. Its identifier is handed to the unauthenticated visitor as the state parameter of the redirection URL. Any visitor who reaches the GitHub or LinkedIn endpoint can replay that identifier as a session cookie and obtain a valid SSO session without authenticating. The session holds neither _user nor authenticationLevel, which the shipped bootstrap configuration accepts because it grants virtual hosts a "default => accept" access rule; deployments whose rules test the user or require an authentication level are less exposed. Only configurations with the GitHub or LinkedIn authentication module enabled are affected.

NAME

Lemonldap:NG::Portal::Captcha - Writing CAPTCHA modules for LemonLDAP::NG.

SYNOPSIS

package Lemonldap::NG::Portal::Captcha::My;

use strict;
use Mouse;
# Add constants used by this module

our $VERSION = '0.1';

extends 'Lemonldap::NG::Portal::Main::Plugin';

sub init {
    my $self = shift;
    return 1;
}

sub init_captcha {
  my ( $self, $req ) = @_;

  # Read option from the manager configuration
  my $option = $self->conf->{captchaOptions}->{option1};

  # This can be used to inject custom JS code at the beginning
  # of the page
  my $script = <your html code>;
  $req->data->{customScript} .= $script;

  # This will add your custom HTML code to the protected form
  my $html = <your html code>;
  $req->captchaHtml($html);
}

sub check_captcha {
  my ( $self, $req ) = @_;

  my $captcha_input = $req->param('some_post_param');
  my $is_captcha_valid = <your code here>;

  if($is_captcha_valid) {
      return 1;
  } else {
      return 0;
  }
}

1;

DESCRIPTION

Captcha modules only need to implement two methods: one for initializing the challenge, before the form is displayed, and the other to verify that the submitted response is correct.

METHODS

Accessors and methods provided by Lemonldap::NG::Portal::Main::Plugin

p: portal object
conf: configuration hash (as reference)
logger alias for p->logger accessor
userLogger alias for p->userLogger accessor
error: alias for p->error method

"Routes" management

Like each module that inherits from Lemonldap::NG::Portal::Plugin, you can define dedicated routes in a Captcha plugin.

addAuthRoute: wrapper to Lemonldap::NG::Handler::PSGI::Try addAuthRoute() method
addUnauthRoute: wrapper to Lemonldap::NG::Handler::PSGI::Try addUnauthRoute() method

Methods that must be provided by a Captcha module

init_captcha($req)

This method is called when the protected form is built by LemonLDAP::NG. Your responsibility is to do any preparatory step, and provide LemonLDAP::NG with the HTML code that it has to display in the form to enable the Captcha.

This is done by setting $req->captchaHtml

check_captcha($req)

This method is called after the user submitted the protected form. Your responibility is to check the user's response (usually provided as a POST field), and return 0 if the response is incorrect, 1 if the response is correct.

LOGGING

Logging is provided by $self->logger and $self->userLogger. See Lemonldap::NG::Portal::Main::Plugin for a detailed description of logging levels.

AUTHORS

LemonLDAP::NG team http://lemonldap-ng.org/team

BUG REPORT

Use OW2 system to report bug or ask for features: https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues

DOWNLOAD

Lemonldap::NG is available at https://lemonldap-ng.org/download

COPYRIGHT AND LICENSE

See COPYING file for details.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.