Security Advisories (9)
CVE-2020-11022 (2020-04-29)

In jQuery versions greater than or equal to 1.2 and before 3.5.0, passing HTML from untrusted sources - even after sanitizing it - to one of jQuery's DOM manipulation methods (i.e. .html(), .append(), and others) may execute untrusted code. This problem is patched in jQuery 3.5.0.

CVE-2020-11023 (2020-04-29)

In jQuery versions greater than or equal to 1.0.3 and before 3.5.0, passing HTML containing <option> elements from untrusted sources - even after sanitizing it - to one of jQuery's DOM manipulation methods (i.e. .html(), .append(), and others) may execute untrusted code. This problem is patched in jQuery 3.5.0.

CVE-2019-11358 (2019-04-20)

jQuery before 3.4.0, as used in Drupal, Backdrop CMS, and other products, mishandles jQuery.extend(true, {}, ...) because of Object.prototype pollution. If an unsanitized source object contained an enumerable __proto__ property, it could extend the native Object.prototype.

CVE-2015-9251 (2018-01-18)

jQuery before 3.0.0 is vulnerable to Cross-site Scripting (XSS) attacks when a cross-domain Ajax request is performed without the dataType option, causing text/javascript responses to be executed.

CVE-2011-4969 (2013-03-08)

Cross-site scripting (XSS) vulnerability in jQuery before 1.6.3, when using location.hash to select elements, allows remote attackers to inject arbitrary web script or HTML via a crafted tag.

CVE-2012-6708 (2018-01-18)

jQuery before 1.9.0 is vulnerable to Cross-site Scripting (XSS) attacks. The jQuery(strInput) function does not differentiate selectors from HTML in a reliable fashion. In vulnerable versions, jQuery determined whether the input was HTML by looking for the '<' character anywhere in the string, giving attackers more flexibility when attempting to construct a malicious payload. In fixed versions, jQuery only deems the input to be HTML if it explicitly starts with the '<' character, limiting exploitability only to attackers who can control the beginning of a string, which is far less common.

CVE-2020-7656 (2020-05-19)

jquery prior to 1.9.0 allows Cross-site Scripting attacks via the load method. The load method fails to recognize and remove "<script>" HTML tags that contain a whitespace character, i.e: "</script >", which results in the enclosed script logic to be executed.

CVE-2019-5428

Prototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as _proto_, constructor and prototype. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the Object.prototype are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.

CVE-2014-6071 (2018-01-16)

jQuery 1.4.2 allows remote attackers to conduct cross-site scripting (XSS) attacks via vectors related to use of the text method inside after.

NAME

Yancy::Guides::Model - Building modules for your application's business logic

VERSION

version 1.088

DESCRIPTION

This guide describes how to extend Yancy::Model to add custom business logic.

Model Classes

There are three types of classes in Yancy::Model:

Model

The model class represents the entire database and contains schemas.

Schema

Schema classes represent individual tables, views, or collections and contain items.

Item

Item classes represent individual records from the database.

Using the Default Model

The default Yancy::Model class contains basic CRUD (Create, Retrieve, Update, Delete) methods.

Setup

For now, you must set up the model manually by creating a Yancy::Model object, passing in a Yancy::Backend:

my $model = Yancy::Model->new( backend => $backend );

Schemas

Get a schema using the schema method:

my $users = $model->schema( 'users' );

This returns a Yancy::Model::Schema object (or a custom schema class, see "Schema Classes").

Creating Items

To create an item, use the create method on the schema:

my $user_id = $model->schema( 'users' )->create({
    username => 'bender',
    password => 'shiny',
});

Only the ID of the new item is returned.

Lookup by ID

To look up an item by its ID, use the get method on the schema.

my $bender = $model->schema( 'users' )->get( $bender_id );

This method returns a Yancy::Model::Item object (or a custom item class, see "Item Classes").

To search for items, use the list method on the schema. The list method returns a hash reference with items and total keys. items is an array reference of Yancy::Model::Item objects. total is the total number of items that match the query.

my $result = $model->schema( 'users' )->list({ active => 1 });
if ( $result->{total} > 0 ) {
    my @users = $result->{items}->@*;
    say "Found $result->{total} active users: ",
        map { $_->{username} } @users;
}

Updating Items

To update an item, first get the item object and then call set to update its data.

my $bender = $model->schema( 'users' )->get( $bender_id );
$bender->set({ password => 'daffodil' });

Bulk-updating items is not yet supported, but may be added in a later release (patches welcome!)

Deleting Items

If you already have an item, you can use its delete method to delete it. Otherwise, you can delete an item by its ID.

$model->schema( 'users' )->get( $user_id )->delete;
$model->schema( 'users' )->delete( $user_id );

Bulk-deleting items is not yet supported, but may be added in a later release (patches welcome!)

Relationships

Related data can be prefetched and added to an item using the join option to get or list.

my $user = $model->schema( 'users' )->get( $id, join => 'user_roles' );
my $result = $model->schema( 'users' )->list( {}, join => 'user_roles' );

The resulting data is added in a key named for the join:

my $roles = $user->{user_roles};

TODO: Items could have a related method that gets related data after-the-fact.

Future Development: Queries

In the future, a query method may be added that will return an object that can build up arguments for a call to the list method, as well as act as a cursor for that call.

Starting a Custom Model

When building your own model layer, you only need to create classes when you want to add custom code. By default, the Yancy::Model class will load classes from all of its configured namespaces.

Make sure to add your namespace to the "namespaces" in Yancy::Model array:

unshift @{ $model->namespaces }, 'MyApp';

This adds MyApp::Schema as a namespace for schema classes, and MyApp::Item as a namespace for item classes.

Create a Model Class

If you need it, you can create a model class by extending Yancy::Model.

package MyApp::Model;
use Mojo::Base 'Yancy::Model', -signatures;

Your model class could include methods for the most common data lookups:

sub get_user( $self, $id ) {
    return $self->schema( 'user' )->get( $id );
}

Your model class should also store configuration needed by the other classes:

# Invitation e-mails come from this address
has email_from => 'no-reply@example.com';

Schema Classes

Schema classes contain code for working with the entire schema or a subset of the schema. Any code that affects more than one item should live in the schema class.

To create a schema class, extend Yancy::Model::Schema. The name of the schema class should be the camel-cased version of the schema's name.

package MyApp::Schema::User; # schema: 'user'
use Mojo::Base 'Yancy::Model::Schema', -signatures;

The schema class should contain methods that work on the collection: Creating new items, searching for items.

# Invite a new user
sub invite( $self, $email ) {
    my $id = $self->create({ email => $email });
    $self->get( $id )->send_invite_mail;
    return $id;
}

Item Classes

Item classes contain code for working on a single item.

To create an item class, extend Yancy::Model::Item. The name of the item class should be the camel-cased version of the schema's name.

package MyApp::Item::User;
use Mojo::Base 'Yancy::Model::Item', -signatures;

# Send the invite mail to this user
sub send_invite_mail( $self ) {
    my $to = $self->data->{email};
    my $from = $self->model->email_from;
    # TODO: Send e-mail
}

Adding Custom Validation

To add custom validation to a schema, override the validate method of Yancy::Model::Schema. This method is called by both Schema and Item classes.

Adding Input / Output Transforms (Filters)

To transform a model's input before creation or update, override the create method of Yancy::Model::Schema and the set method of Yancy::Model::Schema. The set method of the Schema class is called by both Schema and Item classes. You cannot modify data in the validate method.

To transform a model's data after being read from the database, override the build_item method of Yancy::Model::Schema.

SEE ALSO

Yancy::Model, Yancy::Guides::Schema, Yancy::Backend, Yancy::Guides

AUTHOR

Doug Bell <preaction@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2021 by Doug Bell.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.