VYPR
Moderate severityNVD Advisory· Published Jul 29, 2014· Updated May 6, 2026

CVE-2014-3547

CVE-2014-3547

Description

Multiple cross-site scripting (XSS) vulnerabilities in badges/renderer.php in Moodle 2.5.x before 2.5.7, 2.6.x before 2.6.4, and 2.7.x before 2.7.1 allow remote attackers to inject arbitrary web script or HTML via an external badge.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
moodle/moodlePackagist
>= 2.5.0, < 2.5.72.5.7
moodle/moodlePackagist
>= 2.6.0, < 2.6.42.6.4
moodle/moodlePackagist
>= 2.7.0, < 2.7.12.7.1

Affected products

12
  • Moodle/Moodle12 versions
    cpe:2.3:a:moodle:moodle:2.5.0:*:*:*:*:*:*:*+ 11 more
    • cpe:2.3:a:moodle:moodle:2.5.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.5.1:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.5.2:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.5.3:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.5.4:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.5.5:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.5.6:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.6.0:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.6.1:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.6.2:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.6.3:*:*:*:*:*:*:*
    • cpe:2.3:a:moodle:moodle:2.7.0:*:*:*:*:*:*:*

Patches

4
9eef6b523752

MDL-46042 badges: Clean up external badge data

https://github.com/moodle/moodleYuliya BozhkoJun 19, 2014via ghsa
1 file changed · +15 14
  • badges/renderer.php+15 14 modified
    @@ -41,7 +41,7 @@ public function print_badges_list($badges, $userid, $profile = false, $external
                     $bname = $badge->name;
                     $imageurl = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', 'f1', false);
                 } else {
    -                $bname = $badge->assertion->badge->name;
    +                $bname = s($badge->assertion->badge->name);
                     $imageurl = $badge->imageUrl;
                 }
     
    @@ -421,47 +421,48 @@ protected function render_external_badge(external_badge $ibadge) {
             }
     
             $datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), '');
    -        $datatable->data[] = array(get_string('issuername', 'badges'), $issuer->name);
    +        $datatable->data[] = array(get_string('issuername', 'badges'), s($issuer->name));
             $datatable->data[] = array(get_string('issuerurl', 'badges'),
    -                html_writer::tag('a', $issuer->origin, array('href' => $issuer->origin)));
    +                html_writer::tag('a', s($issuer->origin), array('href' => $issuer->origin)));
             if (isset($issuer->contact)) {
                 $datatable->data[] = array(get_string('contact', 'badges'), obfuscate_mailto($issuer->contact));
             }
             $datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), '');
    -        $datatable->data[] = array(get_string('name'), $assertion->badge->name);
    -        $datatable->data[] = array(get_string('description', 'badges'), $assertion->badge->description);
    +        $datatable->data[] = array(get_string('name'), s($assertion->badge->name));
    +        $datatable->data[] = array(get_string('description', 'badges'), s($assertion->badge->description));
             $datatable->data[] = array(get_string('bcriteria', 'badges'),
    -                html_writer::tag('a', $assertion->badge->criteria, array('href' => $assertion->badge->criteria)));
    +                html_writer::tag('a', s($assertion->badge->criteria), array('href' => $assertion->badge->criteria)));
             $datatable->data[] = array($this->output->heading(get_string('issuancedetails', 'badges'), 3), '');
             if (isset($assertion->issued_on)) {
    -            $datatable->data[] = array(get_string('dateawarded', 'badges'), $assertion->issued_on);
    +            $issuedate = !strtotime($assertion->issued_on) ? s($assertion->issued_on) : strtotime($assertion->issued_on);
    +            $datatable->data[] = array(get_string('dateawarded', 'badges'), userdate($issuedate));
             }
    -        if (isset($assertion->badge->expire)) {
    +        if (isset($assertion->expires)) {
                 $today_date = date('Y-m-d');
                 $today = strtotime($today_date);
    -            $expiration = strtotime($assertion->badge->expire);
    +            $expiration = !strtotime($assertion->expires) ? s($assertion->expires) : strtotime($assertion->expires);
                 if ($expiration < $today) {
    -                $cell = new html_table_cell($assertion->badge->expire . get_string('warnexpired', 'badges'));
    +                $cell = new html_table_cell(userdate($expiration) . get_string('warnexpired', 'badges'));
                     $cell->attributes = array('class' => 'notifyproblem warning');
                     $datatable->data[] = array(get_string('expirydate', 'badges'), $cell);
     
                     $image = html_writer::start_tag('div', array('class' => 'badge'));
    -                $image .= html_writer::empty_tag('img', array('src' => $issued['badge']['image']));
    +                $image .= html_writer::empty_tag('img', array('src' => $issued->imageUrl));
                     $image .= html_writer::start_tag('span', array('class' => 'expired'))
                                 . $this->output->pix_icon('i/expired',
    -                                get_string('expireddate', 'badges', $assertion->badge->expire),
    +                                get_string('expireddate', 'badges', userdate($expiration)),
                                     'moodle',
                                     array('class' => 'expireimage'))
                                 . html_writer::end_tag('span');
                     $image .= html_writer::end_tag('div');
                     $imagetable->data[0] = array($image);
                 } else {
    -                $datatable->data[] = array(get_string('expirydate', 'badges'), $assertion->badge->expire);
    +                $datatable->data[] = array(get_string('expirydate', 'badges'), userdate($expiration));
                 }
             }
             if (isset($assertion->evidence)) {
                 $datatable->data[] = array(get_string('evidence', 'badges'),
    -                html_writer::tag('a', $assertion->evidence, array('href' => $assertion->evidence)));
    +                html_writer::tag('a', s($assertion->evidence), array('href' => $assertion->evidence)));
             }
             $table->attributes = array('class' => 'generalbox boxaligncenter issuedbadgebox');
             $table->data[] = array(html_writer::table($imagetable), html_writer::table($datatable));
    
0174a0a57f6d

MDL-46042 badges: Clean up external badge data

https://github.com/moodle/moodleYuliya BozhkoJun 19, 2014via ghsa
1 file changed · +15 14
  • badges/renderer.php+15 14 modified
    @@ -41,7 +41,7 @@ public function print_badges_list($badges, $userid, $profile = false, $external
                     $bname = $badge->name;
                     $imageurl = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', 'f1', false);
                 } else {
    -                $bname = $badge->assertion->badge->name;
    +                $bname = s($badge->assertion->badge->name);
                     $imageurl = $badge->imageUrl;
                 }
     
    @@ -420,47 +420,48 @@ protected function render_external_badge(external_badge $ibadge) {
             }
     
             $datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), '');
    -        $datatable->data[] = array(get_string('issuername', 'badges'), $issuer->name);
    +        $datatable->data[] = array(get_string('issuername', 'badges'), s($issuer->name));
             $datatable->data[] = array(get_string('issuerurl', 'badges'),
    -                html_writer::tag('a', $issuer->origin, array('href' => $issuer->origin)));
    +                html_writer::tag('a', s($issuer->origin), array('href' => $issuer->origin)));
             if (isset($issuer->contact)) {
                 $datatable->data[] = array(get_string('contact', 'badges'), obfuscate_mailto($issuer->contact));
             }
             $datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), '');
    -        $datatable->data[] = array(get_string('name'), $assertion->badge->name);
    -        $datatable->data[] = array(get_string('description', 'badges'), $assertion->badge->description);
    +        $datatable->data[] = array(get_string('name'), s($assertion->badge->name));
    +        $datatable->data[] = array(get_string('description', 'badges'), s($assertion->badge->description));
             $datatable->data[] = array(get_string('bcriteria', 'badges'),
    -                html_writer::tag('a', $assertion->badge->criteria, array('href' => $assertion->badge->criteria)));
    +                html_writer::tag('a', s($assertion->badge->criteria), array('href' => $assertion->badge->criteria)));
             $datatable->data[] = array($this->output->heading(get_string('issuancedetails', 'badges'), 3), '');
             if (isset($assertion->issued_on)) {
    -            $datatable->data[] = array(get_string('dateawarded', 'badges'), $assertion->issued_on);
    +            $issuedate = !strtotime($assertion->issued_on) ? s($assertion->issued_on) : strtotime($assertion->issued_on);
    +            $datatable->data[] = array(get_string('dateawarded', 'badges'), userdate($issuedate));
             }
    -        if (isset($assertion->badge->expire)) {
    +        if (isset($assertion->expires)) {
                 $today_date = date('Y-m-d');
                 $today = strtotime($today_date);
    -            $expiration = strtotime($assertion->badge->expire);
    +            $expiration = !strtotime($assertion->expires) ? s($assertion->expires) : strtotime($assertion->expires);
                 if ($expiration < $today) {
    -                $cell = new html_table_cell($assertion->badge->expire . get_string('warnexpired', 'badges'));
    +                $cell = new html_table_cell(userdate($expiration) . get_string('warnexpired', 'badges'));
                     $cell->attributes = array('class' => 'notifyproblem warning');
                     $datatable->data[] = array(get_string('expirydate', 'badges'), $cell);
     
                     $image = html_writer::start_tag('div', array('class' => 'badge'));
    -                $image .= html_writer::empty_tag('img', array('src' => $issued['badge']['image']));
    +                $image .= html_writer::empty_tag('img', array('src' => $issued->imageUrl));
                     $image .= html_writer::start_tag('span', array('class' => 'expired'))
                                 . $this->output->pix_icon('i/expired',
    -                                get_string('expireddate', 'badges', $assertion->badge->expire),
    +                                get_string('expireddate', 'badges', userdate($expiration)),
                                     'moodle',
                                     array('class' => 'expireimage'))
                                 . html_writer::end_tag('span');
                     $image .= html_writer::end_tag('div');
                     $imagetable->data[0] = array($image);
                 } else {
    -                $datatable->data[] = array(get_string('expirydate', 'badges'), $assertion->badge->expire);
    +                $datatable->data[] = array(get_string('expirydate', 'badges'), userdate($expiration));
                 }
             }
             if (isset($assertion->evidence)) {
                 $datatable->data[] = array(get_string('evidence', 'badges'),
    -                html_writer::tag('a', $assertion->evidence, array('href' => $assertion->evidence)));
    +                html_writer::tag('a', s($assertion->evidence), array('href' => $assertion->evidence)));
             }
             $table->attributes = array('class' => 'generalbox boxaligncenter issuedbadgebox');
             $table->data[] = array(html_writer::table($imagetable), html_writer::table($datatable));
    
200a2b7fad3f

MDL-46042 badges: Clean up external badge data

https://github.com/moodle/moodleYuliya BozhkoJun 19, 2014via ghsa
1 file changed · +15 14
  • badges/renderer.php+15 14 modified
    @@ -41,7 +41,7 @@ public function print_badges_list($badges, $userid, $profile = false, $external
                     $bname = $badge->name;
                     $imageurl = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', 'f1', false);
                 } else {
    -                $bname = $badge->assertion->badge->name;
    +                $bname = s($badge->assertion->badge->name);
                     $imageurl = $badge->imageUrl;
                 }
     
    @@ -420,47 +420,48 @@ protected function render_external_badge(external_badge $ibadge) {
             }
     
             $datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), '');
    -        $datatable->data[] = array(get_string('issuername', 'badges'), $issuer->name);
    +        $datatable->data[] = array(get_string('issuername', 'badges'), s($issuer->name));
             $datatable->data[] = array(get_string('issuerurl', 'badges'),
    -                html_writer::tag('a', $issuer->origin, array('href' => $issuer->origin)));
    +                html_writer::tag('a', s($issuer->origin), array('href' => $issuer->origin)));
             if (isset($issuer->contact)) {
                 $datatable->data[] = array(get_string('contact', 'badges'), obfuscate_mailto($issuer->contact));
             }
             $datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), '');
    -        $datatable->data[] = array(get_string('name'), $assertion->badge->name);
    -        $datatable->data[] = array(get_string('description', 'badges'), $assertion->badge->description);
    +        $datatable->data[] = array(get_string('name'), s($assertion->badge->name));
    +        $datatable->data[] = array(get_string('description', 'badges'), s($assertion->badge->description));
             $datatable->data[] = array(get_string('bcriteria', 'badges'),
    -                html_writer::tag('a', $assertion->badge->criteria, array('href' => $assertion->badge->criteria)));
    +                html_writer::tag('a', s($assertion->badge->criteria), array('href' => $assertion->badge->criteria)));
             $datatable->data[] = array($this->output->heading(get_string('issuancedetails', 'badges'), 3), '');
             if (isset($assertion->issued_on)) {
    -            $datatable->data[] = array(get_string('dateawarded', 'badges'), $assertion->issued_on);
    +            $issuedate = !strtotime($assertion->issued_on) ? s($assertion->issued_on) : strtotime($assertion->issued_on);
    +            $datatable->data[] = array(get_string('dateawarded', 'badges'), userdate($issuedate));
             }
    -        if (isset($assertion->badge->expire)) {
    +        if (isset($assertion->expires)) {
                 $today_date = date('Y-m-d');
                 $today = strtotime($today_date);
    -            $expiration = strtotime($assertion->badge->expire);
    +            $expiration = !strtotime($assertion->expires) ? s($assertion->expires) : strtotime($assertion->expires);
                 if ($expiration < $today) {
    -                $cell = new html_table_cell($assertion->badge->expire . get_string('warnexpired', 'badges'));
    +                $cell = new html_table_cell(userdate($expiration) . get_string('warnexpired', 'badges'));
                     $cell->attributes = array('class' => 'notifyproblem warning');
                     $datatable->data[] = array(get_string('expirydate', 'badges'), $cell);
     
                     $image = html_writer::start_tag('div', array('class' => 'badge'));
    -                $image .= html_writer::empty_tag('img', array('src' => $issued['badge']['image']));
    +                $image .= html_writer::empty_tag('img', array('src' => $issued->imageUrl));
                     $image .= html_writer::start_tag('span', array('class' => 'expired'))
                                 . $this->output->pix_icon('i/expired',
    -                                get_string('expireddate', 'badges', $assertion->badge->expire),
    +                                get_string('expireddate', 'badges', userdate($expiration)),
                                     'moodle',
                                     array('class' => 'expireimage'))
                                 . html_writer::end_tag('span');
                     $image .= html_writer::end_tag('div');
                     $imagetable->data[0] = array($image);
                 } else {
    -                $datatable->data[] = array(get_string('expirydate', 'badges'), $assertion->badge->expire);
    +                $datatable->data[] = array(get_string('expirydate', 'badges'), userdate($expiration));
                 }
             }
             if (isset($assertion->evidence)) {
                 $datatable->data[] = array(get_string('evidence', 'badges'),
    -                html_writer::tag('a', $assertion->evidence, array('href' => $assertion->evidence)));
    +                html_writer::tag('a', s($assertion->evidence), array('href' => $assertion->evidence)));
             }
             $table->attributes = array('class' => 'generalbox boxaligncenter issuedbadgebox');
             $table->data[] = array(html_writer::table($imagetable), html_writer::table($datatable));
    
ea76b652fc4f

MDL-46042 badges: Clean up external badge data

https://github.com/moodle/moodleYuliya BozhkoJun 18, 2014via ghsa
1 file changed · +21 20
  • badges/renderer.php+21 20 modified
    @@ -41,7 +41,7 @@ public function print_badges_list($badges, $userid, $profile = false, $external
                     $bname = $badge->name;
                     $imageurl = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', 'f1', false);
                 } else {
    -                $bname = $badge->assertion->badge->name;
    +                $bname = s($badge->assertion->badge->name);
                     $imageurl = $badge->imageUrl;
                 }
     
    @@ -381,20 +381,20 @@ protected function render_external_badge(external_badge $ibadge) {
             $issuer = $assertion->badge->issuer;
             $userinfo = $ibadge->recipient;
             $table = new html_table();
    -        $today_date = date('Y-m-d');
    -        $today = strtotime($today_date);
    -        $expiration = isset($assertion->badge->expire) ? strtotime($assertion->badge->expire) : $today + 86400;
    +        $today = strtotime(date('Y-m-d'));
     
             $output = '';
             $output .= html_writer::start_tag('div', array('id' => 'badge'));
             $output .= html_writer::start_tag('div', array('id' => 'badge-image'));
    -        if ($expiration < $today) {
    -            $output .= $this->output->pix_icon('i/expired',
    -                    get_string('expireddate', 'badges', $assertion->badge->expire),
    -                    'moodle',
    -                    array('class' => 'expireimage'));
    -        } else {
    -            $output .= html_writer::empty_tag('img', array('src' => $issued->imageUrl));
    +        $output .= html_writer::empty_tag('img', array('src' => $issued->imageUrl));
    +        if (isset($assertion->expires)) {
    +            $expiration = !strtotime($assertion->expires) ? s($assertion->expires) : strtotime($assertion->expires);
    +            if ($expiration < $today) {
    +                $output .= $this->output->pix_icon('i/expired',
    +                        get_string('expireddate', 'badges', userdate($expiration)),
    +                        'moodle',
    +                        array('class' => 'expireimage'));
    +            }
             }
             $output .= html_writer::end_tag('div');
     
    @@ -419,7 +419,7 @@ protected function render_external_badge(external_badge $ibadge) {
     
             $output .= $this->output->heading(get_string('issuerdetails', 'badges'), 3);
             $dl = array();
    -        $dl[get_string('issuername', 'badges')] = $issuer->name;
    +        $dl[get_string('issuername', 'badges')] = s($issuer->name);
             $dl[get_string('issuerurl', 'badges')] = html_writer::tag('a', $issuer->origin, array('href' => $issuer->origin));
     
             if (isset($issuer->contact)) {
    @@ -429,25 +429,26 @@ protected function render_external_badge(external_badge $ibadge) {
     
             $output .= $this->output->heading(get_string('badgedetails', 'badges'), 3);
             $dl = array();
    -        $dl[get_string('name')] = $assertion->badge->name;
    -        $dl[get_string('description', 'badges')] = $assertion->badge->description;
    -        $dl[get_string('bcriteria', 'badges')] = html_writer::tag('a', $assertion->badge->criteria, array('href' => $assertion->badge->criteria));
    +        $dl[get_string('name')] = s($assertion->badge->name);
    +        $dl[get_string('description', 'badges')] = s($assertion->badge->description);
    +        $dl[get_string('bcriteria', 'badges')] = html_writer::tag('a', s($assertion->badge->criteria), array('href' => $assertion->badge->criteria));
             $output .= $this->definition_list($dl);
     
             $output .= $this->output->heading(get_string('issuancedetails', 'badges'), 3);
             $dl = array();
             if (isset($assertion->issued_on)) {
    -            $dl[get_string('dateawarded', 'badges')] = $assertion->issued_on;
    +            $issuedate = !strtotime($assertion->issued_on) ? s($assertion->issued_on) : strtotime($assertion->issued_on);
    +            $dl[get_string('dateawarded', 'badges')] = userdate($issuedate);
             }
    -        if (isset($assertion->badge->expire)) {
    +        if (isset($assertion->expires)) {
                 if ($expiration < $today) {
    -                $dl[get_string('expirydate', 'badges')] = $assertion->badge->expire . get_string('warnexpired', 'badges');
    +                $dl[get_string('expirydate', 'badges')] = userdate($expiration) . get_string('warnexpired', 'badges');
                 } else {
    -                $dl[get_string('expirydate', 'badges')] = $assertion->badge->expire;
    +                $dl[get_string('expirydate', 'badges')] = userdate($expiration);
                 }
             }
             if (isset($assertion->evidence)) {
    -            $dl[get_string('evidence', 'badges')] = html_writer::tag('a', $assertion->evidence, array('href' => $assertion->evidence));
    +            $dl[get_string('evidence', 'badges')] = html_writer::tag('a', s($assertion->evidence), array('href' => $assertion->evidence));
             }
             $output .= $this->definition_list($dl);
             $output .= html_writer::end_tag('div');
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.