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::Lib::2fDevices - Role for registrable second factors

DESCRIPTION

This role provides LemonLDAP::NG modules with a high-level interface to storing information on registrable second factors into the persistent session.

It is recommended that _2fDevices is never accessed directly from code outside of this module

METHODS

update2fDevice

Updates one field of a registered device

$self->update2fDevice($req, $info, $type, $key, $value, $update_key, $update_value);
req: Current LemonLDAP::NG request
info: hashref of current session information
type: 'type' field of the device to update
key, value: update the device whose 'key' field equals value
update_key, update_value: set the matched devices' 'update_key' field to update_value

Returns true if the update was sucessful

add2fDevice

Store a new device

$self->add2fDevice($req, $info, $device);
req: Current LemonLDAP::NG request
info: hashref of current session information
device: hashref of device details. It must contain at least a 'type', 'name' and 'epoch' key

Returns true if the update was sucessful

del2fDevices

Delete the devices specified in the @$devices array

$self->del2fDevices($req, $info, $devices);
req: Current LemonLDAP::NG request
info: hashref of current session information
device: arrayref of type+epoch hashrefs
[ { type => xxx, epoch => xxx }, { type => xxx, epoch => xxx } ]

Returns true if the update was sucessful

del2fDevice

Delete a single device

$self->del2fDevice($req, $info, $type, $epoch);
req: Current LemonLDAP::NG request
info: hashref of current session information
type: type of the device to remove
epoch: timestamp of the device to remove

Returns true if the update was sucessful

find2fDevicesByKey

Find devices from one of its attributes

$self->find2fDevicesByKey($req, $info, $type, $key, $value);
req: Current LemonLDAP::NG request
info: hashref of current session information
type: device type
key, value: attribute to search in the device hash and the value to filter on

Returns an array of devices for which type, key and value match the supplied ones

get2fDevices

Return all registrable devices.

$self->get2fDevices($req, $info);
req: Current LemonLDAP::NG request
info: hashref of current session information

Returns an arrayref of all registrable devices, or undef if an error occured

find2fDevicesByType

Return all registrable devices of a certain type. If type is not given, return all registrable devices

$self->find2fDevicesByType($req, $info, $type);
req: Current LemonLDAP::NG request
info: hashref of current session information
type: type of registrable device to return

Returns an array of all matching devices