diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java index cef65d29f..c17449ce6 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/AsciiDoctorTemplateResolver.java @@ -115,6 +115,7 @@ public class AsciiDoctorTemplateResolver extends FileTemplateResolver { Map attributes = new HashMap<>(); attributes.put("source-highlighter", "coderay"); attributes.put("backend", "xhtml"); + attributes.put("icons", org.asciidoctor.Attributes.FONT_ICONS); Map options = new HashMap<>(); options.put("attributes", attributes); diff --git a/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java index 28572c26b..7f2712d7f 100644 --- a/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java +++ b/webgoat-container/src/main/java/org/owasp/webgoat/asciidoc/WebWolfMacro.java @@ -3,7 +3,6 @@ package org.owasp.webgoat.asciidoc; import org.asciidoctor.ast.AbstractBlock; import org.asciidoctor.extension.InlineMacroProcessor; import org.springframework.core.env.Environment; -import org.springframework.util.StringUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; diff --git a/webgoat-container/src/main/resources/static/css/asciidoctor-default.css b/webgoat-container/src/main/resources/static/css/asciidoctor-default.css new file mode 100644 index 000000000..e09f19382 --- /dev/null +++ b/webgoat-container/src/main/resources/static/css/asciidoctor-default.css @@ -0,0 +1,2126 @@ +/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */ +/* Uncomment @import statement to use as custom stylesheet */ +/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/ +article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section { + display: block +} + +audio, video { + display: inline-block +} + +audio:not([controls]) { + display: none; + height: 0 +} + +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100% +} + +a { + background: none +} + +a:focus { + outline: thin dotted +} + +a:active, a:hover { + outline: 0 +} + +h1 { + font-size: 2em; + margin: .67em 0 +} + +abbr[title] { + border-bottom: 1px dotted +} + +b, strong { + font-weight: bold +} + +dfn { + font-style: italic +} + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0 +} + +mark { + background: #ff0; + color: #000 +} + +code, kbd, pre, samp { + font-family: monospace; + font-size: 1em +} + +pre { + white-space: pre-wrap +} + +q { + quotes: "\201C" "\201D" "\2018" "\2019" +} + +small { + font-size: 80% +} + +sub, sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline +} + +sup { + top: -.5em +} + +sub { + bottom: -.25em +} + +img { + border: 0 +} + +svg:not(:root) { + overflow: hidden +} + +figure { + margin: 0 +} + +fieldset { + border: 1px solid silver; + margin: 0 2px; + padding: .35em .625em .75em +} + +legend { + border: 0; + padding: 0 +} + +button, input, select, textarea { + font-family: inherit; + font-size: 100%; + margin: 0 +} + +button, input { + line-height: normal +} + +button, select { + text-transform: none +} + +button, html input[type="button"], input[type="reset"], input[type="submit"] { + -webkit-appearance: button; + cursor: pointer +} + +button[disabled], html input[disabled] { + cursor: default +} + +input[type="checkbox"], input[type="radio"] { + box-sizing: border-box; + padding: 0 +} + +button::-moz-focus-inner, input::-moz-focus-inner { + border: 0; + padding: 0 +} + +textarea { + overflow: auto; + vertical-align: top +} + +table { + border-collapse: collapse; + border-spacing: 0 +} + +*, *::before, *::after { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box +} + +html, body { + font-size: 100% +} + +body { + background: #fff; + color: rgba(0, 0, 0, .8); + padding: 0; + margin: 0; + font-family: "Noto Serif", "DejaVu Serif", serif; + font-weight: 400; + font-style: normal; + line-height: 1; + position: relative; + cursor: auto; + tab-size: 4; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased +} + +a:hover { + cursor: pointer +} + +img, object, embed { + max-width: 100%; + height: auto +} + +object, embed { + height: 100% +} + +img { + -ms-interpolation-mode: bicubic +} + +.left { + float: left !important +} + +.right { + float: right !important +} + +.text-left { + text-align: left !important +} + +.text-right { + text-align: right !important +} + +.text-center { + text-align: center !important +} + +.text-justify { + text-align: justify !important +} + +.hide { + display: none +} + +img, object, svg { + display: inline-block; + vertical-align: middle +} + +textarea { + height: auto; + min-height: 50px +} + +select { + width: 100% +} + +.center { + margin-left: auto; + margin-right: auto +} + +.stretch { + width: 100% +} + +.subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { + line-height: 1.45; + color: #7a2518; + font-weight: 400; + margin-top: 0; + margin-bottom: .25em +} + +div, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { + margin: 0; + padding: 0; + direction: ltr +} + +a { + color: #2156a5; + text-decoration: underline; + line-height: inherit +} + +a:hover, a:focus { + color: #1d4b8f +} + +a img { + border: 0 +} + +p { + font-family: inherit; + font-weight: 400; + font-size: 1em; + line-height: 1.6; + margin-bottom: 1.25em; + text-rendering: optimizeLegibility +} + +p aside { + font-size: .875em; + line-height: 1.35; + font-style: italic +} + +h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { + font-family: "Open Sans", "DejaVu Sans", sans-serif; + font-weight: 300; + font-style: normal; + color: #ba3925; + text-rendering: optimizeLegibility; + margin-top: 1em; + margin-bottom: .5em; + line-height: 1.0125em +} + +h1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { + font-size: 60%; + color: #e99b8f; + line-height: 0 +} + +h1 { + font-size: 2.125em +} + +h2 { + font-size: 1.6875em +} + +h3, #toctitle, .sidebarblock > .content > .title { + font-size: 1.375em +} + +h4, h5 { + font-size: 1.125em +} + +h6 { + font-size: 1em +} + +hr { + border: solid #dddddf; + border-width: 1px 0 0; + clear: both; + margin: 1.25em 0 1.1875em; + height: 0 +} + +em, i { + font-style: italic; + line-height: inherit +} + +strong, b { + font-weight: bold; + line-height: inherit +} + +small { + font-size: 60%; + line-height: inherit +} + +code { + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + font-weight: 400; + color: rgba(0, 0, 0, .9) +} + +ul, ol, dl { + font-size: 1em; + line-height: 1.6; + margin-bottom: 1.25em; + list-style-position: outside; + font-family: inherit +} + +ul, ol { + margin-left: 1.5em +} + +ul li ul, ul li ol { + margin-left: 1.25em; + margin-bottom: 0; + font-size: 1em +} + +ul.square li ul, ul.circle li ul, ul.disc li ul { + list-style: inherit +} + +ul.square { + list-style-type: square +} + +ul.circle { + list-style-type: circle +} + +ul.disc { + list-style-type: disc +} + +ol li ul, ol li ol { + margin-left: 1.25em; + margin-bottom: 0 +} + +dl dt { + margin-bottom: .3125em; + font-weight: bold +} + +dl dd { + margin-bottom: 1.25em +} + +abbr, acronym { + text-transform: uppercase; + font-size: 90%; + color: rgba(0, 0, 0, .8); + border-bottom: 1px dotted #ddd; + cursor: help +} + +abbr { + text-transform: none +} + +blockquote { + margin: 0 0 1.25em; + padding: .5625em 1.25em 0 1.1875em; + border-left: 1px solid #ddd +} + +blockquote cite { + display: block; + font-size: .9375em; + color: rgba(0, 0, 0, .6) +} + +blockquote cite::before { + content: "\2014 \0020" +} + +blockquote cite a, blockquote cite a:visited { + color: rgba(0, 0, 0, .6) +} + +blockquote, blockquote p { + line-height: 1.6; + color: rgba(0, 0, 0, .85) +} + +@media screen and (min-width: 768px) { + h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { + line-height: 1.2 + } + + h1 { + font-size: 2.75em + } + + h2 { + font-size: 2.3125em + } + + h3, #toctitle, .sidebarblock > .content > .title { + font-size: 1.6875em + } + + h4 { + font-size: 1.4375em + } +} + +table { + background: #fff; + margin-bottom: 1.25em; + border: solid 1px #dedede +} + +table thead, table tfoot { + background: #f7f8f7 +} + +table thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { + padding: .5em .625em .625em; + font-size: inherit; + color: rgba(0, 0, 0, .8); + text-align: left +} + +table tr th, table tr td { + padding: .5625em .625em; + font-size: inherit; + color: rgba(0, 0, 0, .8) +} + +table tr.even, table tr.alt { + background: #f8f8f7 +} + +table thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { + display: table-cell; + line-height: 1.6 +} + +h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { + line-height: 1.2; + word-spacing: -.05em +} + +h1 strong, h2 strong, h3 strong, #toctitle strong, .sidebarblock > .content > .title strong, h4 strong, h5 strong, h6 strong { + font-weight: 400 +} + +.clearfix::before, .clearfix::after, .float-group::before, .float-group::after { + content: " "; + display: table +} + +.clearfix::after, .float-group::after { + clear: both +} + +:not(pre):not([class^=L]) > code { + font-size: .9375em; + font-style: normal !important; + letter-spacing: 0; + padding: .1em .5ex; + word-spacing: -.15em; + background: #f7f7f8; + -webkit-border-radius: 4px; + border-radius: 4px; + line-height: 1.45; + text-rendering: optimizeSpeed; + word-wrap: break-word +} + +:not(pre) > code.nobreak { + word-wrap: normal +} + +:not(pre) > code.nowrap { + white-space: nowrap +} + +pre { + color: rgba(0, 0, 0, .9); + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + line-height: 1.45; + text-rendering: optimizeSpeed +} + +pre code, pre pre { + color: inherit; + font-size: inherit; + line-height: inherit +} + +pre > code { + display: block +} + +pre.nowrap, pre.nowrap pre { + white-space: pre; + word-wrap: normal +} + +em em { + font-style: normal +} + +strong strong { + font-weight: 400 +} + +.keyseq { + color: rgba(51, 51, 51, .8) +} + +kbd { + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + display: inline-block; + color: rgba(0, 0, 0, .8); + font-size: .65em; + line-height: 1.45; + background: #f7f7f7; + border: 1px solid #ccc; + -webkit-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, .2), 0 0 0 .1em white inset; + box-shadow: 0 1px 0 rgba(0, 0, 0, .2), 0 0 0 .1em #fff inset; + margin: 0 .15em; + padding: .2em .5em; + vertical-align: middle; + position: relative; + top: -.1em; + white-space: nowrap +} + +.keyseq kbd:first-child { + margin-left: 0 +} + +.keyseq kbd:last-child { + margin-right: 0 +} + +.menuseq, .menuref { + color: #000 +} + +.menuseq b:not(.caret), .menuref { + font-weight: inherit +} + +.menuseq { + word-spacing: -.02em +} + +.menuseq b.caret { + font-size: 1.25em; + line-height: .8 +} + +.menuseq i.caret { + font-weight: bold; + text-align: center; + width: .45em +} + +b.button::before, b.button::after { + position: relative; + top: -1px; + font-weight: 400 +} + +b.button::before { + content: "["; + padding: 0 3px 0 2px +} + +b.button::after { + content: "]"; + padding: 0 2px 0 3px +} + +p a > code:hover { + color: rgba(0, 0, 0, .9) +} + +#header, #content, #footnotes, #footer { + width: 100%; + margin-left: auto; + margin-right: auto; + margin-top: 0; + margin-bottom: 0; + max-width: 62.5em; + *zoom: 1; + position: relative; + padding-left: .9375em; + padding-right: .9375em +} + +#header::before, #header::after, #content::before, #content::after, #footnotes::before, #footnotes::after, #footer::before, #footer::after { + content: " "; + display: table +} + +#header::after, #content::after, #footnotes::after, #footer::after { + clear: both +} + +#content { + margin-top: 1.25em +} + +#content::before { + content: none +} + +#header > h1:first-child { + color: rgba(0, 0, 0, .85); + margin-top: 2.25rem; + margin-bottom: 0 +} + +#header > h1:first-child + #toc { + margin-top: 8px; + border-top: 1px solid #dddddf +} + +#header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { + border-bottom: 1px solid #dddddf; + padding-bottom: 8px +} + +#header .details { + border-bottom: 1px solid #dddddf; + line-height: 1.45; + padding-top: .25em; + padding-bottom: .25em; + padding-left: .25em; + color: rgba(0, 0, 0, .6); + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -ms-flex-flow: row wrap; + -webkit-flex-flow: row wrap; + flex-flow: row wrap +} + +#header .details span:first-child { + margin-left: -.125em +} + +#header .details span.email a { + color: rgba(0, 0, 0, .85) +} + +#header .details br { + display: none +} + +#header .details br + span::before { + content: "\00a0\2013\00a0" +} + +#header .details br + span.author::before { + content: "\00a0\22c5\00a0"; + color: rgba(0, 0, 0, .85) +} + +#header .details br + span#revremark::before { + content: "\00a0|\00a0" +} + +#header #revnumber { + text-transform: capitalize +} + +#header #revnumber::after { + content: "\00a0" +} + +#content > h1:first-child:not([class]) { + color: rgba(0, 0, 0, .85); + border-bottom: 1px solid #dddddf; + padding-bottom: 8px; + margin-top: 0; + padding-top: 1rem; + margin-bottom: 1.25rem +} + +#toc { + border-bottom: 1px solid #e7e7e9; + padding-bottom: .5em +} + +#toc > ul { + margin-left: .125em +} + +#toc ul.sectlevel0 > li > a { + font-style: italic +} + +#toc ul.sectlevel0 ul.sectlevel1 { + margin: .5em 0 +} + +#toc ul { + font-family: "Open Sans", "DejaVu Sans", sans-serif; + list-style-type: none +} + +#toc li { + line-height: 1.3334; + margin-top: .3334em +} + +#toc a { + text-decoration: none +} + +#toc a:active { + text-decoration: underline +} + +#toctitle { + color: #7a2518; + font-size: 1.2em +} + +@media screen and (min-width: 768px) { + #toctitle { + font-size: 1.375em + } + + body.toc2 { + padding-left: 15em; + padding-right: 0 + } + + #toc.toc2 { + margin-top: 0 !important; + background: #f8f8f7; + position: fixed; + width: 15em; + left: 0; + top: 0; + border-right: 1px solid #e7e7e9; + border-top-width: 0 !important; + border-bottom-width: 0 !important; + z-index: 1000; + padding: 1.25em 1em; + height: 100%; + overflow: auto + } + + #toc.toc2 #toctitle { + margin-top: 0; + margin-bottom: .8rem; + font-size: 1.2em + } + + #toc.toc2 > ul { + font-size: .9em; + margin-bottom: 0 + } + + #toc.toc2 ul ul { + margin-left: 0; + padding-left: 1em + } + + #toc.toc2 ul.sectlevel0 ul.sectlevel1 { + padding-left: 0; + margin-top: .5em; + margin-bottom: .5em + } + + body.toc2.toc-right { + padding-left: 0; + padding-right: 15em + } + + body.toc2.toc-right #toc.toc2 { + border-right-width: 0; + border-left: 1px solid #e7e7e9; + left: auto; + right: 0 + } +} + +@media screen and (min-width: 1280px) { + body.toc2 { + padding-left: 20em; + padding-right: 0 + } + + #toc.toc2 { + width: 20em + } + + #toc.toc2 #toctitle { + font-size: 1.375em + } + + #toc.toc2 > ul { + font-size: .95em + } + + #toc.toc2 ul ul { + padding-left: 1.25em + } + + body.toc2.toc-right { + padding-left: 0; + padding-right: 20em + } +} + +#content #toc { + border-style: solid; + border-width: 1px; + border-color: #e0e0dc; + margin-bottom: 1.25em; + padding: 1.25em; + background: #f8f8f7; + -webkit-border-radius: 4px; + border-radius: 4px +} + +#content #toc > :first-child { + margin-top: 0 +} + +#content #toc > :last-child { + margin-bottom: 0 +} + +#footer { + max-width: 100%; + background: rgba(0, 0, 0, .8); + padding: 1.25em +} + +#footer-text { + color: rgba(255, 255, 255, .8); + line-height: 1.44 +} + +#content { + margin-bottom: .625em +} + +.sect1 { + padding-bottom: .625em +} + +@media screen and (min-width: 768px) { + #content { + margin-bottom: 1.25em + } + + .sect1 { + padding-bottom: 1.25em + } +} + +.sect1:last-child { + padding-bottom: 0 +} + +.sect1 + .sect1 { + border-top: 1px solid #e7e7e9 +} + +#content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { + position: absolute; + z-index: 1001; + width: 1.5ex; + margin-left: -1.5ex; + display: block; + text-decoration: none !important; + visibility: hidden; + text-align: center; + font-weight: 400 +} + +#content h1 > a.anchor::before, h2 > a.anchor::before, h3 > a.anchor::before, #toctitle > a.anchor::before, .sidebarblock > .content > .title > a.anchor::before, h4 > a.anchor::before, h5 > a.anchor::before, h6 > a.anchor::before { + content: "\00A7"; + font-size: .85em; + display: block; + padding-top: .1em +} + +#content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { + visibility: visible +} + +#content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { + color: #ba3925; + text-decoration: none +} + +#content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { + color: #a53221 +} + +details, .audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { + margin-bottom: 1.25em +} + +details > summary:first-of-type { + cursor: pointer; + display: list-item; + outline: none; + margin-bottom: .75em +} + +.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { + text-rendering: optimizeLegibility; + text-align: left; + font-family: "Noto Serif", "DejaVu Serif", serif; + font-size: 1rem; + font-style: italic +} + +table.tableblock.fit-content > caption.title { + white-space: nowrap; + width: 0 +} + +.paragraph.lead > p, #preamble > .sectionbody > [class="paragraph"]:first-of-type p { + font-size: 1.21875em; + line-height: 1.6; + color: rgba(0, 0, 0, .85) +} + +table.tableblock #preamble > .sectionbody > [class="paragraph"]:first-of-type p { + font-size: inherit +} + +.admonitionblock > table { + border-collapse: separate; + border: 0; + background: none; + width: 100% +} + +.admonitionblock > table td.icon { + text-align: center; + width: 80px +} + +.admonitionblock > table td.icon img { + max-width: none +} + +.admonitionblock > table td.icon .title { + font-weight: bold; + font-family: "Open Sans", "DejaVu Sans", sans-serif; + text-transform: uppercase +} + +.admonitionblock > table td.content { + padding-left: 1.125em; + padding-right: 1.25em; + border-left: 1px solid #dddddf; + color: rgba(0, 0, 0, .6) +} + +.admonitionblock > table td.content > :last-child > :last-child { + margin-bottom: 0 +} + +.exampleblock > .content { + border-style: solid; + border-width: 1px; + border-color: #e6e6e6; + margin-bottom: 1.25em; + padding: 1.25em; + background: #fff; + -webkit-border-radius: 4px; + border-radius: 4px +} + +.exampleblock > .content > :first-child { + margin-top: 0 +} + +.exampleblock > .content > :last-child { + margin-bottom: 0 +} + +.sidebarblock { + border-style: solid; + border-width: 1px; + border-color: #dbdbd6; + margin-bottom: 1.25em; + padding: 1.25em; + background: #f3f3f2; + -webkit-border-radius: 4px; + border-radius: 4px +} + +.sidebarblock > :first-child { + margin-top: 0 +} + +.sidebarblock > :last-child { + margin-bottom: 0 +} + +.sidebarblock > .content > .title { + color: #7a2518; + margin-top: 0; + text-align: center +} + +.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { + margin-bottom: 0 +} + +.literalblock pre, .listingblock > .content > pre { + -webkit-border-radius: 4px; + border-radius: 4px; + word-wrap: break-word; + overflow-x: auto; + padding: 1em; + font-size: .8125em +} + +@media screen and (min-width: 768px) { + .literalblock pre, .listingblock > .content > pre { + font-size: .90625em + } +} + +@media screen and (min-width: 1280px) { + .literalblock pre, .listingblock > .content > pre { + font-size: 1em + } +} + +.literalblock pre, .listingblock > .content > pre:not(.highlight), .listingblock > .content > pre[class="highlight"], .listingblock > .content > pre[class^="highlight "] { + background: #f7f7f8 +} + +.literalblock.output pre { + color: #f7f7f8; + background: rgba(0, 0, 0, .9) +} + +.listingblock > .content { + position: relative +} + +.listingblock code[data-lang]::before { + display: none; + content: attr(data-lang); + position: absolute; + font-size: .75em; + top: .425rem; + right: .5rem; + line-height: 1; + text-transform: uppercase; + color: inherit; + opacity: .5 +} + +.listingblock:hover code[data-lang]::before { + display: block +} + +.listingblock.terminal pre .command::before { + content: attr(data-prompt); + padding-right: .5em; + color: inherit; + opacity: .5 +} + +.listingblock.terminal pre .command:not([data-prompt])::before { + content: "$" +} + +.listingblock pre.highlightjs { + padding: 0 +} + +.listingblock pre.highlightjs > code { + padding: 1em; + -webkit-border-radius: 4px; + border-radius: 4px +} + +.listingblock pre.prettyprint { + border-width: 0 +} + +.prettyprint { + background: #f7f7f8 +} + +pre.prettyprint .linenums { + line-height: 1.45; + margin-left: 2em +} + +pre.prettyprint li { + background: none; + list-style-type: inherit; + padding-left: 0 +} + +pre.prettyprint li code[data-lang]::before { + opacity: 1 +} + +pre.prettyprint li:not(:first-child) code[data-lang]::before { + display: none +} + +table.linenotable { + border-collapse: separate; + border: 0; + margin-bottom: 0; + background: none +} + +table.linenotable td[class] { + color: inherit; + vertical-align: top; + padding: 0; + line-height: inherit; + white-space: normal +} + +table.linenotable td.code { + padding-left: .75em +} + +table.linenotable td.linenos { + border-right: 1px solid currentColor; + opacity: .35; + padding-right: .5em +} + +pre.pygments .lineno { + border-right: 1px solid currentColor; + opacity: .35; + display: inline-block; + margin-right: .75em +} + +pre.pygments .lineno::before { + content: ""; + margin-right: -.125em +} + +.quoteblock { + margin: 0 1em 1.25em 1.5em; + display: table +} + +.quoteblock:not(.excerpt) > .title { + margin-left: -1.5em; + margin-bottom: .75em +} + +.quoteblock blockquote, .quoteblock p { + color: rgba(0, 0, 0, .85); + font-size: 1.15rem; + line-height: 1.75; + word-spacing: .1em; + letter-spacing: 0; + font-style: italic; + text-align: justify +} + +.quoteblock blockquote { + margin: 0; + padding: 0; + border: 0 +} + +.quoteblock blockquote::before { + content: "\201c"; + float: left; + font-size: 2.75em; + font-weight: bold; + line-height: .6em; + margin-left: -.6em; + color: #7a2518; + text-shadow: 0 1px 2px rgba(0, 0, 0, .1) +} + +.quoteblock blockquote > .paragraph:last-child p { + margin-bottom: 0 +} + +.quoteblock .attribution { + margin-top: .75em; + margin-right: .5ex; + text-align: right +} + +.verseblock { + margin: 0 1em 1.25em +} + +.verseblock pre { + font-family: "Open Sans", "DejaVu Sans", sans; + font-size: 1.15rem; + color: rgba(0, 0, 0, .85); + font-weight: 300; + text-rendering: optimizeLegibility +} + +.verseblock pre strong { + font-weight: 400 +} + +.verseblock .attribution { + margin-top: 1.25rem; + margin-left: .5ex +} + +.quoteblock .attribution, .verseblock .attribution { + font-size: .9375em; + line-height: 1.45; + font-style: italic +} + +.quoteblock .attribution br, .verseblock .attribution br { + display: none +} + +.quoteblock .attribution cite, .verseblock .attribution cite { + display: block; + letter-spacing: -.025em; + color: rgba(0, 0, 0, .6) +} + +.quoteblock.abstract blockquote::before, .quoteblock.excerpt blockquote::before, .quoteblock .quoteblock blockquote::before { + display: none +} + +.quoteblock.abstract blockquote, .quoteblock.abstract p, .quoteblock.excerpt blockquote, .quoteblock.excerpt p, .quoteblock .quoteblock blockquote, .quoteblock .quoteblock p { + line-height: 1.6; + word-spacing: 0 +} + +.quoteblock.abstract { + margin: 0 1em 1.25em; + display: block +} + +.quoteblock.abstract > .title { + margin: 0 0 .375em; + font-size: 1.15em; + text-align: center +} + +.quoteblock.excerpt > blockquote, .quoteblock .quoteblock { + padding: 0 0 .25em 1em; + border-left: .25em solid #dddddf +} + +.quoteblock.excerpt, .quoteblock .quoteblock { + margin-left: 0 +} + +.quoteblock.excerpt blockquote, .quoteblock.excerpt p, .quoteblock .quoteblock blockquote, .quoteblock .quoteblock p { + color: inherit; + font-size: 1.0625rem +} + +.quoteblock.excerpt .attribution, .quoteblock .quoteblock .attribution { + color: inherit; + text-align: left; + margin-right: 0 +} + +table.tableblock { + max-width: 100%; + border-collapse: separate +} + +p.tableblock:last-child { + margin-bottom: 0 +} + +td.tableblock > .content { + margin-bottom: 1.25em +} + +td.tableblock > .content > :last-child { + margin-bottom: -1.25em +} + +table.tableblock, th.tableblock, td.tableblock { + border: 0 solid #dedede +} + +table.grid-all > thead > tr > .tableblock, table.grid-all > tbody > tr > .tableblock { + border-width: 0 1px 1px 0 +} + +table.grid-all > tfoot > tr > .tableblock { + border-width: 1px 1px 0 0 +} + +table.grid-cols > * > tr > .tableblock { + border-width: 0 1px 0 0 +} + +table.grid-rows > thead > tr > .tableblock, table.grid-rows > tbody > tr > .tableblock { + border-width: 0 0 1px +} + +table.grid-rows > tfoot > tr > .tableblock { + border-width: 1px 0 0 +} + +table.grid-all > * > tr > .tableblock:last-child, table.grid-cols > * > tr > .tableblock:last-child { + border-right-width: 0 +} + +table.grid-all > tbody > tr:last-child > .tableblock, table.grid-all > thead:last-child > tr > .tableblock, table.grid-rows > tbody > tr:last-child > .tableblock, table.grid-rows > thead:last-child > tr > .tableblock { + border-bottom-width: 0 +} + +table.frame-all { + border-width: 1px +} + +table.frame-sides { + border-width: 0 1px +} + +table.frame-topbot, table.frame-ends { + border-width: 1px 0 +} + +table.stripes-all tr, table.stripes-odd tr:nth-of-type(odd), table.stripes-even tr:nth-of-type(even), table.stripes-hover tr:hover { + background: #f8f8f7 +} + +th.halign-left, td.halign-left { + text-align: left +} + +th.halign-right, td.halign-right { + text-align: right +} + +th.halign-center, td.halign-center { + text-align: center +} + +th.valign-top, td.valign-top { + vertical-align: top +} + +th.valign-bottom, td.valign-bottom { + vertical-align: bottom +} + +th.valign-middle, td.valign-middle { + vertical-align: middle +} + +table thead th, table tfoot th { + font-weight: bold +} + +tbody tr th { + display: table-cell; + line-height: 1.6; + background: #f7f8f7 +} + +tbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { + color: rgba(0, 0, 0, .8); + font-weight: bold +} + +p.tableblock > code:only-child { + background: none; + padding: 0 +} + +p.tableblock { + font-size: 1em +} + +ol { + margin-left: 1.75em +} + +ul li ol { + margin-left: 1.5em +} + +dl dd { + margin-left: 1.125em +} + +dl dd:last-child, dl dd:last-child > :last-child { + margin-bottom: 0 +} + +ol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { + margin-bottom: .625em +} + +ul.checklist, ul.none, ol.none, ul.no-bullet, ol.no-bullet, ol.unnumbered, ul.unstyled, ol.unstyled { + list-style-type: none +} + +ul.no-bullet, ol.no-bullet, ol.unnumbered { + margin-left: .625em +} + +ul.unstyled, ol.unstyled { + margin-left: 0 +} + +ul.checklist { + margin-left: .625em +} + +ul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { + width: 1.25em; + font-size: .8em; + position: relative; + bottom: .125em +} + +ul.checklist li > p:first-child > input[type="checkbox"]:first-child { + margin-right: .25em +} + +ul.inline { + display: -ms-flexbox; + display: -webkit-box; + display: flex; + -ms-flex-flow: row wrap; + -webkit-flex-flow: row wrap; + flex-flow: row wrap; + list-style: none; + margin: 0 0 .625em -1.25em +} + +ul.inline > li { + margin-left: 1.25em +} + +.unstyled dl dt { + font-weight: 400; + font-style: normal +} + +ol.arabic { + list-style-type: decimal +} + +ol.decimal { + list-style-type: decimal-leading-zero +} + +ol.loweralpha { + list-style-type: lower-alpha +} + +ol.upperalpha { + list-style-type: upper-alpha +} + +ol.lowerroman { + list-style-type: lower-roman +} + +ol.upperroman { + list-style-type: upper-roman +} + +ol.lowergreek { + list-style-type: lower-greek +} + +.hdlist > table, .colist > table { + border: 0; + background: none +} + +.hdlist > table > tbody > tr, .colist > table > tbody > tr { + background: none +} + +td.hdlist1, td.hdlist2 { + vertical-align: top; + padding: 0 .625em +} + +td.hdlist1 { + font-weight: bold; + padding-bottom: 1.25em +} + +.literalblock + .colist, .listingblock + .colist { + margin-top: -.5em +} + +.colist td:not([class]):first-child { + padding: .4em .75em 0; + line-height: 1; + vertical-align: top +} + +.colist td:not([class]):first-child img { + max-width: none +} + +.colist td:not([class]):last-child { + padding: .25em 0 +} + +.thumb, .th { + line-height: 0; + display: inline-block; + border: solid 4px #fff; + -webkit-box-shadow: 0 0 0 1px #ddd; + box-shadow: 0 0 0 1px #ddd +} + +.imageblock.left { + margin: .25em .625em 1.25em 0 +} + +.imageblock.right { + margin: .25em 0 1.25em .625em +} + +.imageblock > .title { + margin-bottom: 0 +} + +.imageblock.thumb, .imageblock.th { + border-width: 6px +} + +.imageblock.thumb > .title, .imageblock.th > .title { + padding: 0 .125em +} + +.image.left, .image.right { + margin-top: .25em; + margin-bottom: .25em; + display: inline-block; + line-height: 0 +} + +.image.left { + margin-right: .625em +} + +.image.right { + margin-left: .625em +} + +a.image { + text-decoration: none; + display: inline-block +} + +a.image object { + pointer-events: none +} + +sup.footnote, sup.footnoteref { + font-size: .875em; + position: static; + vertical-align: super +} + +sup.footnote a, sup.footnoteref a { + text-decoration: none +} + +sup.footnote a:active, sup.footnoteref a:active { + text-decoration: underline +} + +#footnotes { + padding-top: .75em; + padding-bottom: .75em; + margin-bottom: .625em +} + +#footnotes hr { + width: 20%; + min-width: 6.25em; + margin: -.25em 0 .75em; + border-width: 1px 0 0 +} + +#footnotes .footnote { + padding: 0 .375em 0 .225em; + line-height: 1.3334; + font-size: .875em; + margin-left: 1.2em; + margin-bottom: .2em +} + +#footnotes .footnote a:first-of-type { + font-weight: bold; + text-decoration: none; + margin-left: -1.05em +} + +#footnotes .footnote:last-of-type { + margin-bottom: 0 +} + +#content #footnotes { + margin-top: -.625em; + margin-bottom: 0; + padding: .75em 0 +} + +.gist .file-data > table { + border: 0; + background: #fff; + width: 100%; + margin-bottom: 0 +} + +.gist .file-data > table td.line-data { + width: 99% +} + +div.unbreakable { + page-break-inside: avoid +} + +.big { + font-size: larger +} + +.small { + font-size: smaller +} + +.underline { + text-decoration: underline +} + +.overline { + text-decoration: overline +} + +.line-through { + text-decoration: line-through +} + +.aqua { + color: #00bfbf +} + +.aqua-background { + background: #00fafa +} + +.black { + color: #000 +} + +.black-background { + background: #000 +} + +.blue { + color: #0000bf +} + +.blue-background { + background: #0000fa +} + +.fuchsia { + color: #bf00bf +} + +.fuchsia-background { + background: #fa00fa +} + +.gray { + color: #606060 +} + +.gray-background { + background: #7d7d7d +} + +.green { + color: #006000 +} + +.green-background { + background: #007d00 +} + +.lime { + color: #00bf00 +} + +.lime-background { + background: #00fa00 +} + +.maroon { + color: #600000 +} + +.maroon-background { + background: #7d0000 +} + +.navy { + color: #000060 +} + +.navy-background { + background: #00007d +} + +.olive { + color: #606000 +} + +.olive-background { + background: #7d7d00 +} + +.purple { + color: #600060 +} + +.purple-background { + background: #7d007d +} + +.red { + color: #bf0000 +} + +.red-background { + background: #fa0000 +} + +.silver { + color: #909090 +} + +.silver-background { + background: #bcbcbc +} + +.teal { + color: #006060 +} + +.teal-background { + background: #007d7d +} + +.white { + color: #bfbfbf +} + +.white-background { + background: #fafafa +} + +.yellow { + color: #bfbf00 +} + +.yellow-background { + background: #fafa00 +} + +span.icon > .fa { + cursor: default +} + +a span.icon > .fa { + cursor: inherit +} + +.admonitionblock td.icon [class^="fa icon-"] { + font-size: 2.5em; + text-shadow: 1px 1px 2px rgba(0, 0, 0, .5); + cursor: default +} + +.admonitionblock td.icon .icon-note::before { + content: "\f05a"; + color: #19407c +} + +.admonitionblock td.icon .icon-tip::before { + content: "\f0eb"; + text-shadow: 1px 1px 2px rgba(155, 155, 0, .8); + color: #111 +} + +.admonitionblock td.icon .icon-warning::before { + content: "\f071"; + color: #bf6900 +} + +.admonitionblock td.icon .icon-caution::before { + content: "\f06d"; + color: #bf3400 +} + +.admonitionblock td.icon .icon-important::before { + content: "\f06a"; + color: #bf0000 +} + +.conum[data-value] { + display: inline-block; + color: #fff !important; + background: rgba(0, 0, 0, .8); + -webkit-border-radius: 50%; + border-radius: 50%; + text-align: center; + font-size: .75em; + width: 1.67em; + height: 1.67em; + line-height: 1.67em; + font-family: "Open Sans", "DejaVu Sans", sans-serif; + font-style: normal; + font-weight: bold +} + +.conum[data-value] * { + color: #fff !important +} + +.conum[data-value] + b { + display: none +} + +.conum[data-value]::after { + content: attr(data-value) +} + +pre .conum[data-value] { + position: relative; + top: -.125em +} + +b.conum * { + color: inherit !important +} + +.conum:not([data-value]):empty { + display: none +} + +dt, th.tableblock, td.content, div.footnote { + text-rendering: optimizeLegibility +} + +h1, h2, p, td.content, span.alt { + letter-spacing: -.01em +} + +p strong, td.content strong, div.footnote strong { + letter-spacing: -.005em +} + +p, blockquote, dt, td.content, span.alt { + font-size: 1.0625rem +} + +p { + margin-bottom: 1.25rem +} + +.sidebarblock p, .sidebarblock dt, .sidebarblock td.content, p.tableblock { + font-size: 1em +} + +.exampleblock > .content { + background: #fffef7; + border-color: #e0e0dc; + -webkit-box-shadow: 0 1px 4px #e0e0dc; + box-shadow: 0 1px 4px #e0e0dc +} + +.print-only { + display: none !important +} + +@page { + margin: 1.25cm .75cm +} + +@media print { + * { + -webkit-box-shadow: none !important; + box-shadow: none !important; + text-shadow: none !important + } + + html { + font-size: 80% + } + + a { + color: inherit !important; + text-decoration: underline !important + } + + a.bare, a[href^="#"], a[href^="mailto:"] { + text-decoration: none !important + } + + a[href^="http:"]:not(.bare)::after, a[href^="https:"]:not(.bare)::after { + content: "(" attr(href) ")"; + display: inline-block; + font-size: .875em; + padding-left: .25em + } + + abbr[title]::after { + content: " (" attr(title) ")" + } + + pre, blockquote, tr, img, object, svg { + page-break-inside: avoid + } + + thead { + display: table-header-group + } + + svg { + max-width: 100% + } + + p, blockquote, dt, td.content { + font-size: 1em; + orphans: 3; + widows: 3 + } + + h2, h3, #toctitle, .sidebarblock > .content > .title { + page-break-after: avoid + } + + #toc, .sidebarblock, .exampleblock > .content { + background: none !important + } + + #toc { + border-bottom: 1px solid #dddddf !important; + padding-bottom: 0 !important + } + + body.book #header { + text-align: center + } + + body.book #header > h1:first-child { + border: 0 !important; + margin: 2.5em 0 1em + } + + body.book #header .details { + border: 0 !important; + display: block; + padding: 0 !important + } + + body.book #header .details span:first-child { + margin-left: 0 !important + } + + body.book #header .details br { + display: block + } + + body.book #header .details br + span::before { + content: none !important + } + + body.book #toc { + border: 0 !important; + text-align: left !important; + padding: 0 !important; + margin: 0 !important + } + + body.book #toc, body.book #preamble, body.book h1.sect0, body.book .sect1 > h2 { + page-break-before: always + } + + .listingblock code[data-lang]::before { + display: block + } + + #footer { + padding: 0 .9375em + } + + .hide-on-print { + display: none !important + } + + .print-only { + display: block !important + } + + .hide-for-print { + display: none !important + } + + .show-for-print { + display: inherit !important + } +} + +@media print, amzn-kf8 { + #header > h1:first-child { + margin-top: 1.25rem + } + + .sect1 { + padding: 0 !important + } + + .sect1 + .sect1 { + border: 0 + } + + #footer { + background: none + } + + #footer-text { + color: rgba(0, 0, 0, .6); + font-size: .9em + } +} + +@media amzn-kf8 { + #header, #content, #footnotes, #footer { + padding: 0 + } +} diff --git a/webgoat-container/src/main/resources/static/css/img/solution.svg b/webgoat-container/src/main/resources/static/css/img/solution.svg new file mode 100644 index 000000000..29b5e033a --- /dev/null +++ b/webgoat-container/src/main/resources/static/css/img/solution.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/webgoat-container/src/main/resources/static/css/main.css b/webgoat-container/src/main/resources/static/css/main.css index f6fd87812..5621c9408 100644 --- a/webgoat-container/src/main/resources/static/css/main.css +++ b/webgoat-container/src/main/resources/static/css/main.css @@ -2,149 +2,173 @@ Base styles ========================================================================== */ body { - color: #5D5F63; - background: #212121; - font-family: 'Open Sans', sans-serif; - padding: 0px; - margin: 0px; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; + color: #5D5F63; + background: #212121; + font-family: 'Open Sans', sans-serif; + padding: 0px; + margin: 0px; + line-height: 1; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; } + a:link, a:visited { - text-decoration: none; - outline: none; - /* color: #e84c3d; */ + text-decoration: none; + outline: none; + /* color: #e84c3d; */ } + a:hover, a:active { - outline: none; - text-decoration: none; - color: #16a086; + outline: none; + text-decoration: none; + color: #16a086; } + h1, h2, h3, h4, h5, h6 { - font-family: 'Source Sans Pro', Arial, sans-serif; + font-family: 'Source Sans Pro', Arial, sans-serif; } + p { - font-size: 14px; + font-size: 14px; } + hr { - margin-top: 10px; - margin-bottom: 10px; + margin-top: 10px; + margin-bottom: 10px; } + img { - max-width: 100%; + max-width: 100%; } + ::selection { - background: #fff7dd; + background: #fff7dd; } + ::-moz-selection { - background: #fff7dd; + background: #fff7dd; } + /* ========================================================================== Layout ========================================================================== */ #container { - width: 100%; - height: 100%; - z-index: 0; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; + width: 100%; + height: 100%; + z-index: 0; + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + -ms-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; } + /* Header */ #header { - z-index: 200; - background: #fff; - min-height: 80px; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - margin-right: 0; + z-index: 200; + background: #fff; + min-height: 80px; + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + -ms-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; + margin-right: 0; } + #header .brand { - float: left; - width: 240px; - height: 80px; - padding: 0; - position: relative; - background: url('img/logoBG.jpg') no-repeat 0px 0px; + float: left; + width: 240px; + height: 80px; + padding: 0; + position: relative; + background: url('img/logoBG.jpg') no-repeat 0px 0px; } + #header .logo { - color: #fff; - font-size: 1.7em; - text-transform: uppercase; - padding: 23px 0 0 75px; - display: inline-block; + color: #fff; + font-size: 1.7em; + text-transform: uppercase; + padding: 23px 0 0 75px; + display: inline-block; } + #header .logo span { - font-weight: 700; + font-weight: 700; } + #header .toggle-navigation button:hover, #header .toggle-navigation button:active, #header button#toggle-mail:hover, #header button#toggle-mail:active { - background: #e84c3d; + background: #e84c3d; } + #header .toggle-navigation button:hover i, #header button#toggle-mail:hover i { - color: #F6F6F6; + color: #F6F6F6; } + #header .toggle-navigation.toggle-left { - margin-top: 5px; - margin-left: 20px; - display: inline-block; + margin-top: 5px; + margin-left: 20px; + display: inline-block; } + #header .btn-default { - padding: 3px 9px; - background: #F6F6F6; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - -ms-border-radius: 50%; - -o-border-radius: 50%; - border-radius: 50%; - width: 35px; - height: 35px; + padding: 3px 9px; + background: #F6F6F6; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + -ms-border-radius: 50%; + -o-border-radius: 50%; + border-radius: 50%; + width: 35px; + height: 35px; } + #header .btn-default .fa-bars, #header .btn-default .fa-comment { - cursor: pointer; - color: #797979; + cursor: pointer; + color: #797979; } + #header .btn-default .fa-info, #header .btn-default .fa-envelope, #header .btn-default .fa-user { - color: #797979; + color: #797979; } + #header .user-nav button:hover, #header .user-nav button:active { - background: #e84c3d; + background: #e84c3d; } + #header .user-nav button:hover i { - color: #F6F6F6; + color: #F6F6F6; } + #header #lesson-title-wrapper { - display: inline-block; - margin:0 0 0 20px; + display: inline-block; + margin: 0 0 0 20px; } + #header .pull-right { - float: right !important; - margin-top:25px; - margin-right:20px; + float: right !important; + margin-top: 25px; + margin-right: 20px; } .btn-primary + .dropdown-menu > li > a:hover, .btn-primary + .dropdown-menu > li > a:active { - background-color: #16a086; + background-color: #16a086; } .sidebar > div > ul > li > ul > li > span.lesson-complete { @@ -152,45 +176,48 @@ img { margin-left: 1.5em;*/ margin-right: 5px; margin-top: -38px; /* << don't like doing this, but otherwise it does not line up correctly */ - color:#88FB88 /* #0F0 */ + color: #88FB88 /* #0F0 */ } /* ========================================================================== Main Content ========================================================================== */ .main-content-wrapper { - margin-left: 240px; - margin-right: 0; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - background: #f1f2f7; - min-height: 400px; + margin-left: 240px; + margin-right: 0; + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + -ms-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; + background: #f1f2f7; + min-height: 400px; } .main-content-wrapper #main-content { - /*background: url('img/webBg.png') no-repeat top left;*/ - border-top: solid thin #e7e8ec; - display: inline-block; - padding: 15px 15px 0 15px; - width: 100%; + /*background: url('img/webBg.png') no-repeat top left;*/ + border-top: solid thin #e7e8ec; + display: inline-block; + padding: 15px 15px 0 15px; + width: 100%; } + .main-content-wrapper #main-content .h1 { - margin: 0; - padding: 0px 10px 40px 10px; - float: left; - line-height: 10px; - font-weight: 300; - font-size: 42px; - font-family: 'Source Sans Pro', Arial, sans-serif; + margin: 0; + padding: 0px 10px 40px 10px; + float: left; + line-height: 10px; + font-weight: 300; + font-size: 42px; + font-family: 'Source Sans Pro', Arial, sans-serif; } + .main-content-toggle-left { - margin-left: 0; + margin-left: 0; } + .main-content-toggle-right { - margin-right: 240px; + margin-right: 240px; } /*========================================================================== @@ -198,83 +225,108 @@ img { ========================================================================= */ #lesson-content-wrapper { - padding:5px; + padding: 5px; } #lesson-content-wrapper table td, #lesson-content-wrapper table th { - padding:3px !important; + padding: 3px !important; +} + +div.lesson-page-solution { + position: relative; + border: 2px solid #425c2f; + border-radius: 12px; + padding: 7px; + margin-top: 7px; + padding: 5px; + background-image: url('img/solution.svg'); + background-repeat: no-repeat; + background-position: right 10px top; } div.lesson-image img { - border:2px solid #aaa; - border-radius:8px; + border: 2px solid #aaa; + border-radius: 8px; + max-width: 50%; + height: auto; + margin-top: 10px; + margin-bottom: 20px; } + /* ========================================================================== Buttons ========================================================================== */ .btn { - border: none; - font-size: 15px; - font-weight: normal; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; - padding: 8px 14px; - margin-bottom: 5px; - -webkit-font-smoothing: subpixel-antialiased; - -webkit-transition: border 0.25s linear, color 0.25s linear, background-color 0.25s linear; - transition: border 0.25s linear, color 0.25s linear, background-color 0.25s linear; + border: none; + font-size: 15px; + font-weight: normal; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; + padding: 8px 14px; + margin-bottom: 5px; + -webkit-font-smoothing: subpixel-antialiased; + -webkit-transition: border 0.25s linear, color 0.25s linear, background-color 0.25s linear; + transition: border 0.25s linear, color 0.25s linear, background-color 0.25s linear; } + .btn:hover, .btn:focus { - outline: none; + outline: none; } + .btn:active, .btn.active { - outline: none; - -webkit-box-shadow: none; - box-shadow: none; - outline: none!important; + outline: none; + -webkit-box-shadow: none; + box-shadow: none; + outline: none !important; } + .btn.disabled, .btn[disabled], .btn fieldset[disabled] .btn { - background-color: #bdc3c7; - color: rgba(255, 255, 255, 0.75); - opacity: 0.7; - filter: alpha(opacity=70); + background-color: #bdc3c7; + color: rgba(255, 255, 255, 0.75); + opacity: 0.7; + filter: alpha(opacity=70); } + /* Default Buttons*/ .btn-default, a.btn-default:link, a.btn-default:visited { - color: #ffffff; - background-color: #bdc3c7; - outline: none!important; + color: #ffffff; + background-color: #bdc3c7; + outline: none !important; } + a.btn-default:hover, a.btn-default:active { - color: #ffffff; - background-color: #cbd0d3; - border-color: #cbd0d3; + color: #ffffff; + background-color: #cbd0d3; + border-color: #cbd0d3; } + .btn-default:hover, .btn-default:focus, .btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default { - color: #ffffff; - background-color: #cbd0d3; - border-color: #cbd0d3; + color: #ffffff; + background-color: #cbd0d3; + border-color: #cbd0d3; } + .btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default { - background: #bdc3c7; - border-color: #bdc3c7; + background: #bdc3c7; + border-color: #bdc3c7; } + .btn-default.disabled, .btn-default[disabled], fieldset[disabled] .btn-default, @@ -290,36 +342,41 @@ fieldset[disabled] .btn-default:active, .btn-default.disabled.active, .btn-default[disabled].active, fieldset[disabled] .btn-default.active { - background-color: #bdc3c7; - border-color: #bdc3c7; + background-color: #bdc3c7; + border-color: #bdc3c7; } + .btn-primary, a.btn-primary:link, a.btn-primary:visited { - color: #fff; - background-color: #e84c3d; + color: #fff; + background-color: #e84c3d; } + a.btn-primary:hover, a.btn-primary:active { - color: #ffffff; - background-color: #C62F28; - border-color: #C62F28; + color: #ffffff; + background-color: #C62F28; + border-color: #C62F28; } + .btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary { - color: #ffffff; - background-color: #C62F28; - border-color: #C62F28; + color: #ffffff; + background-color: #C62F28; + border-color: #C62F28; } + .btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary { - background: #e84c3d; - border-color: #e84c3d; + background: #e84c3d; + border-color: #e84c3d; } + .btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, @@ -335,39 +392,45 @@ fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { - background-color: #e84c3d; - border-color: #e84c3d; + background-color: #e84c3d; + border-color: #e84c3d; } + .btn-info { - color: #ffffff; - background-color: #3598db; + color: #ffffff; + background-color: #3598db; } + .btn-info, a.btn-info:link, a.btn-info:visited { - color: #ffffff; - background-color: #3598db; + color: #ffffff; + background-color: #3598db; } + a.btn-info:hover, a.btn-info:active { - color: #ffffff; - background-color: #4ba3df; + color: #ffffff; + background-color: #4ba3df; } + .btn-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .open .dropdown-toggle.btn-info { - color: #ffffff; - background-color: #4ba3df; - border-color: #4ba3df; + color: #ffffff; + background-color: #4ba3df; + border-color: #4ba3df; } + .btn-info:active, .btn-info.active, .open .dropdown-toggle.btn-info { - background: #3598db; - border-color: #3598db; + background: #3598db; + border-color: #3598db; } + .btn-info.disabled, .btn-info[disabled], fieldset[disabled] .btn-info, @@ -383,28 +446,32 @@ fieldset[disabled] .btn-info:active, .btn-info.disabled.active, .btn-info[disabled].active, fieldset[disabled] .btn-info.active { - background-color: #3598db; - border-color: #3598db; + background-color: #3598db; + border-color: #3598db; } + .btn-danger { - color: #ffffff; - background-color: #e84c3d; + color: #ffffff; + background-color: #e84c3d; } + .btn-danger:hover, .btn-danger:focus, .btn-danger:active, .btn-danger.active, .open .dropdown-toggle.btn-danger { - color: #ffffff; - background-color: #eb6154; - border-color: #eb6154; + color: #ffffff; + background-color: #eb6154; + border-color: #eb6154; } + .btn-danger:active, .btn-danger.active, .open .dropdown-toggle.btn-danger { - background: #eb6154; - border-color: #eb6154; + background: #eb6154; + border-color: #eb6154; } + .btn-danger.disabled, .btn-danger[disabled], fieldset[disabled] .btn-danger, @@ -420,28 +487,32 @@ fieldset[disabled] .btn-danger:active, .btn-danger.disabled.active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger.active { - background-color: #e84c3d; - border-color: #e84c3d; + background-color: #e84c3d; + border-color: #e84c3d; } + .btn-success { - color: #ffffff; - background-color: #2dcc70; + color: #ffffff; + background-color: #2dcc70; } + .btn-success:hover, .btn-success:focus, .btn-success:active, .btn-success.active, .open .dropdown-toggle.btn-success { - color: #ffffff; - background-color: #3ed47d; - border-color: #3ed47d; + color: #ffffff; + background-color: #3ed47d; + border-color: #3ed47d; } + .btn-success:active, .btn-success.active, .open .dropdown-toggle.btn-success { - background: #2dcc70; - border-color: #2dcc70; + background: #2dcc70; + border-color: #2dcc70; } + .btn-success.disabled, .btn-success[disabled], fieldset[disabled] .btn-success, @@ -457,27 +528,30 @@ fieldset[disabled] .btn-success:active, .btn-success.disabled.active, .btn-success[disabled].active, fieldset[disabled] .btn-success.active { - background-color: #2dcc70; - border-color: #2dcc70; + background-color: #2dcc70; + border-color: #2dcc70; } + .btn-warning { - color: #ffffff; - background-color: #f1c40f; + color: #ffffff; + background-color: #f1c40f; } + .btn-warning:hover, .btn-warning:focus, .btn-warning:active, .btn-warning.active, .open .dropdown-toggle.btn-warning { - color: #ffffff; - background-color: #f1c40f; - border-color: #f1c40f; + color: #ffffff; + background-color: #f1c40f; + border-color: #f1c40f; } + .btn-warning:active, .btn-warning.active, .open .dropdown-toggle.btn-warning { - background: #f2ca27; - border-color: #f2ca27; + background: #f2ca27; + border-color: #f2ca27; } .btn-warning.disabled, @@ -495,310 +569,327 @@ fieldset[disabled] .btn-warning:active, .btn-warning.disabled.active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning.active { - background-color: #f1c40f; - border-color: #f1c40f; + background-color: #f1c40f; + border-color: #f1c40f; } + /* Button Sizes */ .btn-lg { - padding: 10px 16px; - font-size: 18px; - line-height: 1.33; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; } .btn-sm { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; } .btn-xs { - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; } + /* ========================================================================== Breadcrumbs ========================================================================== */ .breadcrumb { - background: none; + background: none; } .breadcrumb > li { - font-size: 12px; + font-size: 12px; } + /* ========================================================================== Icons ========================================================================== */ .fa-hover { - margin: 5px 0; + margin: 5px 0; } .fa-hover i { - font-size: 14px; - margin-right: 5px; - width: 20px; + font-size: 14px; + margin-right: 5px; + width: 20px; } + /* ========================================================================== Panels ========================================================================== */ .panel { - border: none; - box-shadow: none; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; + border: none; + box-shadow: none; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; } .panel > .panel-heading { - font-size: 13px; - font-weight: 400; - text-transform: uppercase; - padding: 15px; + font-size: 13px; + font-weight: 400; + text-transform: uppercase; + padding: 15px; } .panel .actions { - position: absolute; - right: 30px; - top: 18px; + position: absolute; + right: 30px; + top: 18px; } .panel .actions i { - font-size: 1em; - margin: 0 3px; + font-size: 1em; + margin: 0 3px; } .panel .actions i:hover { - cursor: pointer; + cursor: pointer; } .panel > .panel-footer { - font-size: 13px; - font-weight: 400; - text-transform: uppercase; - padding: 15px; + font-size: 13px; + font-weight: 400; + text-transform: uppercase; + padding: 15px; } .panel-default > .panel-heading { - border-color: #eff2f7; - background: #fafafa; - color: #767676; + border-color: #eff2f7; + background: #fafafa; + color: #767676; } .panel-default .actions i { - font-size: 1em; - color: #bdc3c7; - margin: 0 3px; + font-size: 1em; + color: #bdc3c7; + margin: 0 3px; } .panel-default .actions i:hover { - cursor: pointer; - color: #767676; + cursor: pointer; + color: #767676; } .panel-default > .panel-footer { - border-color: #eff2f7; - background: #fafafa; - color: #767676; + border-color: #eff2f7; + background: #fafafa; + color: #767676; } .panel-primary > .panel-heading { - color: #fff; - background-color: #e84c3d; - border-color: #e84c3d; + color: #fff; + background-color: #e84c3d; + border-color: #e84c3d; } .panel-primary { - border-color: #e84c3d; + border-color: #e84c3d; } .panel-primary > .panel-heading a, .panel-primary > .panel-heading a:hover { - color: #fff; + color: #fff; } .panel-solid-default > .panel-heading, .panel-solid-default > .panel-body, .panel-solid-default > .panel-footer { - background: #bdc3c7; - color: #fff; - border: none; + background: #bdc3c7; + color: #fff; + border: none; } .panel-solid-primary > .panel-heading, .panel-solid-primary > .panel-body, .panel-solid-primary > .panel-footer { - background: #e84c3d; - color: #fff; - border: none; + background: #e84c3d; + color: #fff; + border: none; } .panel-solid-success > .panel-heading, .panel-solid-success > .panel-body, .panel-solid-success > .panel-footer { - background: #2dcc70; - color: #fff; - border: none; + background: #2dcc70; + color: #fff; + border: none; } .panel-solid-warning > .panel-heading, .panel-solid-warning > .panel-body, .panel-solid-warning > .panel-footer { - background: #f1c40f; - color: #fff; - border: none; + background: #f1c40f; + color: #fff; + border: none; } .panel-solid-info > .panel-heading, .panel-solid-info > .panel-body, .panel-solid-info > .panel-footer { - background: #3598db; - color: #fff; - border: none; + background: #3598db; + color: #fff; + border: none; } .panel-solid-danger > .panel-heading, .panel-solid-danger > .panel-body, .panel-solid-danger > .panel-footer { - background: #e84c3d; - color: #fff; - border: none; + background: #e84c3d; + color: #fff; + border: none; } /* ========================================================================== Modal ========================================================================== */ .modal-footer .btn + .btn { - margin-bottom: 5px; + margin-bottom: 5px; } + .modal .modal-body.modal-scroll { - max-height: 375px; - overflow-y: scroll auto; + max-height: 375px; + overflow-y: scroll auto; } #about-modal { - opacity: 95%; + opacity: 95%; } .modal-header { - border-bottom:none !important + border-bottom: none !important } /* ========================================================================== Media Queries ========================================================================== */ @media only screen and (max-width: 767px) and (min-width: 480px) { - /* Main Content */ - #main-content .h1 { - font-size: 35px; - } + /* Main Content */ + #main-content .h1 { + font-size: 35px; + } } + @media only screen and (max-width: 660px) { - #header { - height: 160px; - } - #header .brand { - width: 100%; - } - #header .user-nav ul { - padding-left: 0; - } - #header .toggle-navigation.toggle-left { - float: left; - } - .sidebar { - margin-left: -240px; - } - .sidebar-toggle { - margin-left: 0; - width: 100%; - } - .main-content-wrapper { - margin-left: 0; - } - .main-content-toggle-left { - margin-left: 660px; - } - .sidebarRight { - top: 160px; - width: 100%; - } - .user-nav ul li { - font-size: 12px; - } + #header { + height: 160px; + } + + #header .brand { + width: 100%; + } + + #header .user-nav ul { + padding-left: 0; + } + + #header .toggle-navigation.toggle-left { + float: left; + } + + .sidebar { + margin-left: -240px; + } + + .sidebar-toggle { + margin-left: 0; + width: 100%; + } + + .main-content-wrapper { + margin-left: 0; + } + + .main-content-toggle-left { + margin-left: 660px; + } + + .sidebarRight { + top: 160px; + width: 100%; + } + + .user-nav ul li { + font-size: 12px; + } } + @media only screen and (max-width: 479px) { - /* Main Content */ - #main-content .h1 { - font-size: 22px; - } - #header .dropdown.messages { - display: none; - } + /* Main Content */ + #main-content .h1 { + font-size: 22px; + } + + #header .dropdown.messages { + display: none; + } } #buttonPanel { - padding:3px; - width:auto; + padding: 3px; + width: auto; } #topLinks { - float:right; - margin-right:5px; - margin-top:3px; + float: right; + margin-right: 5px; + margin-top: 3px; } .lesson-help, .lesson-help-button { - display: none; + display: none; } .table-nonfluid { - width:auto; - margin-bottom:15px; + width: auto; + margin-bottom: 15px; } cookie-container { - margin-bottom:4px; + margin-bottom: 4px; } .cookie-table, .param-table { - border:1px solid #eee; + border: 1px solid #eee; } .cookie-table tr td, .param-table tr td { - padding:3px ; - padding-left: 5px; - width:220px; - max-width: 240px; - font-size: x-small; - word-wrap: break-word; + padding: 3px; + padding-left: 5px; + width: 220px; + max-width: 240px; + font-size: x-small; + word-wrap: break-word; } .cookie-table th, .param-table th { - border:none; - border-right:1px solid #ccc; - padding-right:3px; + border: none; + border-right: 1px solid #ccc; + padding-right: 3px; } .cookie-table td, .param-table td { - border:none; - padding-left:3px; + border: none; + padding-left: 3px; } .developer-controls-table { - width: 100%; + width: 100%; } .developer-controls-table td { @@ -810,12 +901,12 @@ cookie-container { } #developer-control-container { - display: none; + display: none; } #menu-container a, .developer-controls-table a { - cursor: pointer; + cursor: pointer; } /* ========================================================================== @@ -823,106 +914,108 @@ cookie-container { ========================================================================== */ /* Sidebar */ .sidebar { - width: 240px; - /*height: 100%;*/ - background: #fff; - position: absolute; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; - z-index: 100; + width: 240px; + /*height: 100%;*/ + background: #fff; + position: absolute; + -webkit-transition: all 0.3s ease-in-out; + -moz-transition: all 0.3s ease-in-out; + -o-transition: all 0.3s ease-in-out; + -ms-transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; + z-index: 100; } #menu-container { - overflow-y:scroll auto; - overflow-x:hidden; + overflow-y: scroll auto; + overflow-x: hidden; } - + .sidebar-toggle { - margin-left: -240px; + margin-left: -240px; } #menu-container ul, #menu-container ul ul { - margin: -2px 0 0; - padding: 0; + margin: -2px 0 0; + padding: 0; } + #menu-container ul li { - list-style-type: none; - border-bottom: 1px solid rgba(255, 255, 255, 0.05); + list-style-type: none; + border-bottom: 1px solid rgba(255, 255, 255, 0.05); } #menu-container ul li a { - /*color: #aeb2b7;*/ - color: #222; - font-weight:bold; - text-decoration: none; - display: block; - padding: 5px 0 5px 15px; - font-size: 12px; - outline: none; - -webkit-transition: all 200ms ease-in; - -moz-transition: all 200ms ease-in; - -o-transition: all 200ms ease-in; - -ms-transition: all 200ms ease-in; - transition: all 200ms ease-in; + /*color: #aeb2b7;*/ + color: #222; + font-weight: bold; + text-decoration: none; + display: block; + padding: 5px 0 5px 15px; + font-size: 12px; + outline: none; + -webkit-transition: all 200ms ease-in; + -moz-transition: all 200ms ease-in; + -o-transition: all 200ms ease-in; + -ms-transition: all 200ms ease-in; + transition: all 200ms ease-in; } #menu-container ul li a span { - display: inline-block; + display: inline-block; } + #menu-container ul ul li { - /*background: #333;*/ - background: #aaa; - margin-bottom: 0; - margin-left: 0; - margin-right: 0; - border-bottom: none; + /*background: #333;*/ + background: #aaa; + margin-bottom: 0; + margin-left: 0; + margin-right: 0; + border-bottom: none; } #menu-container ul ul li a { - font-size: 11px; - padding-top: 5px; - padding-bottom: 5px; - /*color: #aeb2b7;*/ - color: #fff; - margin-left:8px; + font-size: 11px; + padding-top: 5px; + padding-bottom: 5px; + /*color: #aeb2b7;*/ + color: #fff; + margin-left: 8px; } #menu-container ul ul li.selected a { - color:#e84c3d + color: #e84c3d } #menu-container ul ul li.selected a:hover { - color:#ddd + color: #ddd } #menu-container ul li a i { - width: 20px; + width: 20px; } #menu-container ul li a i.fa-angle-right, #menu-container ul li a i.fa-angle-left { - padding-top: 3px; + padding-top: 3px; } #menu-container ul ul { - display: none; + display: none; } #menu-container li.active ul { - display: block; + display: block; } #menu-container ul li:hover, #menu-container ul li a:hover, #menu-container ul li.active > a { - background-color: #e84c3d; - color:#ddd; + background-color: #e84c3d; + color: #ddd; } #menu-container ul span.lesson-complete { @@ -930,7 +1023,7 @@ cookie-container { margin-left: -5px; /*margin-right: 5px;*/ padding-top: 15px; - display:inline-block; + display: inline-block; } /* @@ -940,26 +1033,26 @@ cookie-container { */ #menu-container ul li.stage { - padding-left:3px; + padding-left: 3px; } #menu-container li.selected, #menu-container a.selected { - color:#fff; - /* background-color:#000; */ - font-weight:550; + color: #fff; + /* background-color:#000; */ + font-weight: 550; } #menu-container ul ul.lessonsAndStages.keepOpen { - display: block + display: block } /* General View Controls */ .show-next-page:hover { - cursor:pointer; + cursor: pointer; } .page-nav-wrapper { - display:inline-block; + display: inline-block; width: 30px; } @@ -970,45 +1063,47 @@ cookie-container { min-width: 20px; text-align: center; font-weight: bold; - padding-top:2px; + padding-top: 2px; } .attack-link.solved-false { - background-color:#ac2925; - color:#fff; + background-color: #ac2925; + color: #fff; } .page-link { - color:#eee; + color: #eee; } .attack-link.solved-true { /*color:#88FB88;*/ - background-color:#247506; - color:#fff; + background-color: #247506; + color: #fff; } .attack-link.cur-page, .page-link.cur-page { - color:#fff; - font-weight:bold; + color: #fff; + font-weight: bold; } .page-link-wrapper { - display:inline-block; + display: inline-block; } .page-link-wrapper span { margin: 3px; } -@keyframes blink { - 50% { border-color: white; } +@keyframes blink { + 50% { + border-color: white; + } } .cur-page { animation: blink 1.5s 2 forwards; border: 3px solid blue; - color:#aaa; + color: #aaa; background-color: lightsalmon; } @@ -1021,13 +1116,13 @@ span.show-next-page, span.show-prev-page { } .show-prev-page:hover { - cursor:pointer; + cursor: pointer; } /* attack ... */ .attack-feedback { - font-weight:800; + font-weight: 800; } .attack-output { @@ -1036,7 +1131,7 @@ span.show-next-page, span.show-prev-page { /* HINTS */ #lesson-hint-container { - display: none; + display: none; } #lesson-hint { @@ -1047,69 +1142,69 @@ span.show-next-page, span.show-prev-page { border: 2px solid #24b054; } -#hintsViewTop{ - display: none; - background-color: #eee; +#hintsViewTop { + display: none; + background-color: #eee; } #show-prev-hint, #show-next-hint { - cursor: pointer; + cursor: pointer; } .info { - color:#e84c3d; - font-weight: bold; + color: #e84c3d; + font-weight: bold; } #help-controls { - padding-left: 4px; - padding-top: 4px + padding-left: 4px; + padding-top: 4px } .help-button { - margin-right:4px; + margin-right: 4px; } /* ATTACK DISPLAY */ .attack-container { - position: relative; - background-color: #f1f1f1; - border: 2px solid #a66; - border-radius: 12px; - padding: 7px; - margin-top:7px; - padding:5px; + position: relative; + background-color: #f1f1f1; + border: 2px solid #a66; + border-radius: 12px; + padding: 7px; + margin-top: 7px; + padding: 5px; } /* same look but not the behaviour */ .nonattack-container { - position: relative; - background-color: #f1f1f1; - border: 2px solid #a66; - border-radius: 12px; - padding: 7px; - margin-top:7px; - padding:5px; + position: relative; + background-color: #f1f1f1; + border: 2px solid #a66; + border-radius: 12px; + padding: 7px; + margin-top: 7px; + padding: 5px; } /* ERROR NOTIFICATION */ #error-notification-container { - display: none; - position: absolute; - right: 20px; - width: 35%; + display: none; + position: absolute; + right: 20px; + width: 35%; } #error-notification { - text-align: center; - border-radius: 4px; - color: #ffffff; - background-color: #eb6154; - border-color: #eb6154; - font-weight: bold; - font-size: 12px; - padding: 10px; + text-align: center; + border-radius: 4px; + color: #ffffff; + background-color: #eb6154; + border-color: #eb6154; + font-weight: bold; + font-size: 12px; + padding: 10px; } /* temp override @@ -1121,7 +1216,7 @@ span.show-next-page, span.show-prev-page { /* scoreboard */ div.scoreboard-title { - font-size:xx-large; + font-size: xx-large; } .scoreboard-table tr { @@ -1131,9 +1226,9 @@ div.scoreboard-username { background-color: #222; color: aliceblue; padding: 4px; - padding-left:8px; + padding-left: 8px; font-size: x-large; - border-radius:6px; + border-radius: 6px; } th.username { @@ -1160,7 +1255,7 @@ div.captured-flag { } .fa-flag { - color:red + color: red } .appseceu-banner { @@ -1171,13 +1266,222 @@ div.captured-flag { } #content { - position:relative; + position: relative; } .webwolf-enabled { - position:absolute; - top: 10px; - right: 25px; - width: 42px; - height: 47px; -} \ No newline at end of file + position: absolute; + top: 10px; + right: 25px; + width: 42px; + height: 47px; +} + +.solution { + position: absolute; + top: 10px; + right: 25px; + width: 42px; + height: 47px; +} + +/* Taken from asciidoctor page */ + +code { + font-family: "Droid Sans Mono", "DejaVu Sans Mono", monospace; + font-weight: 400; + color: rgba(0, 0, 0, .9) +} + +.admonitionblock td.icon [class^="fa icon-"] { + font-size: 2.5em; + text-shadow: 1px 1px 2px rgba(0, 0, 0, .5); + cursor: default +} + +.admonitionblock td.icon .icon-note::before { + content: "\f05a"; + color: #19407c +} + +.admonitionblock td.icon .icon-tip::before { + content: "\f0eb"; + text-shadow: 1px 1px 2px rgba(155, 155, 0, .8); + color: #111 +} + +.admonitionblock td.icon .icon-warning::before { + content: "\f071"; + color: #bf6900 +} + +.admonitionblock td.icon .icon-caution::before { + content: "\f06d"; + color: #bf3400 +} + +.admonitionblock td.icon .icon-important::before { + content: "\f06a"; + color: #bf0000 +} + +.quoteblock { + margin: 0 1em 1.25em 1.5em; + display: table +} + +.quoteblock:not(.excerpt) > .title { + margin-left: -1.5em; + margin-bottom: .75em +} + +.quoteblock blockquote, .quoteblock p { + color: rgba(0, 0, 0, .85); + font-size: 1.15rem; + line-height: 1.75; + word-spacing: .1em; + letter-spacing: 0; + font-style: italic; + text-align: justify +} + +.quoteblock blockquote { + margin: 0; + padding: 0; + border: 0 +} + +.quoteblock blockquote::before { + content: "\201c"; + float: left; + font-size: 2.75em; + font-weight: bold; + line-height: .6em; + margin-left: -.6em; + color: #7a2518; + text-shadow: 0 1px 2px rgba(0, 0, 0, .1) +} + +.quoteblock blockquote > .paragraph:last-child p { + margin-bottom: 0 +} + +.quoteblock .attribution { + margin-top: .75em; + margin-right: .5ex; + text-align: right +} + +.verseblock { + margin: 0 1em 1.25em +} + +.verseblock pre { + font-family: "Open Sans", "DejaVu Sans", sans; + font-size: 1.15rem; + color: rgba(0, 0, 0, .85); + font-weight: 300; + text-rendering: optimizeLegibility +} + +.verseblock pre strong { + font-weight: 400 +} + +.verseblock .attribution { + margin-top: 1.25rem; + margin-left: .5ex +} + +.quoteblock .attribution, .verseblock .attribution { + font-size: .9375em; + line-height: 1.45; + font-style: italic +} + +.quoteblock .attribution br, .verseblock .attribution br { + display: none +} + +.quoteblock .attribution cite, .verseblock .attribution cite { + display: block; + letter-spacing: -.025em; + color: rgba(0, 0, 0, .6) +} + +.quoteblock.abstract blockquote::before, .quoteblock.excerpt blockquote::before, .quoteblock .quoteblock blockquote::before { + display: none +} + +.quoteblock.abstract blockquote, .quoteblock.abstract p, .quoteblock.excerpt blockquote, .quoteblock.excerpt p, .quoteblock .quoteblock blockquote, .quoteblock .quoteblock p { + line-height: 1.6; + word-spacing: 0 +} + +.quoteblock.abstract { + margin: 0 1em 1.25em; + display: block +} + +.quoteblock.abstract > .title { + margin: 0 0 .375em; + font-size: 1.15em; + text-align: center +} + +.quoteblock.excerpt > blockquote, .quoteblock .quoteblock { + padding: 0 0 .25em 1em; + border-left: .25em solid #dddddf +} + +.quoteblock.excerpt, .quoteblock .quoteblock { + margin-left: 0 +} + +.quoteblock.excerpt blockquote, .quoteblock.excerpt p, .quoteblock .quoteblock blockquote, .quoteblock .quoteblock p { + color: inherit; + font-size: 1.0625rem +} + +.quoteblock.excerpt .attribution, .quoteblock .quoteblock .attribution { + color: inherit; + text-align: left; + margin-right: 0 +} + +.conum { + display: inline-block; + color: #fff !important; + background: rgba(0, 0, 0, .8); + -webkit-border-radius: 50%; + border-radius: 50%; + text-align: center; + font-size: .90em; + width: 1.67em; + height: 1.67em; + line-height: 1.67em; + font-family: "Open Sans", "DejaVu Sans", sans-serif; + font-style: normal; + font-weight: bold +} + +.conum * { + color: #fff !important +} + +.conum + b { + display: none +} + +.conum::after { + content: attr(data-value) +} + +pre .conum { + position: relative; + top: -.125em +} + +b.conum * { + color: inherit !important +} diff --git a/webgoat-container/src/main/resources/static/images/WebGoatFinancial/banklogo.jpg b/webgoat-container/src/main/resources/static/images/WebGoatFinancial/banklogo.jpg deleted file mode 100644 index a76f481c4..000000000 Binary files a/webgoat-container/src/main/resources/static/images/WebGoatFinancial/banklogo.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/catStarted.jpg b/webgoat-container/src/main/resources/static/images/buttons/catStarted.jpg deleted file mode 100644 index 447e39d5d..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/catStarted.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/cookies.jpg b/webgoat-container/src/main/resources/static/images/buttons/cookies.jpg deleted file mode 100644 index ce23a1af0..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/cookies.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/cookiesOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/cookiesOver.jpg deleted file mode 100644 index 6a6f918e7..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/cookiesOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/help.jpg b/webgoat-container/src/main/resources/static/images/buttons/help.jpg deleted file mode 100644 index 3d409d1fa..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/help.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/helpOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/helpOver.jpg deleted file mode 100644 index f5a6759dc..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/helpOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/hint.jpg b/webgoat-container/src/main/resources/static/images/buttons/hint.jpg deleted file mode 100644 index dc0213105..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/hint.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/hintLeft.jpg b/webgoat-container/src/main/resources/static/images/buttons/hintLeft.jpg deleted file mode 100644 index 11c9672e3..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/hintLeft.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/hintLeftOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/hintLeftOver.jpg deleted file mode 100644 index b2ffde62a..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/hintLeftOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/hintOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/hintOver.jpg deleted file mode 100644 index b40c5b77e..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/hintOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/hintRight.jpg b/webgoat-container/src/main/resources/static/images/buttons/hintRight.jpg deleted file mode 100644 index 6ad8a308f..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/hintRight.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/hintRightOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/hintRightOver.jpg deleted file mode 100644 index 0d3e6b084..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/hintRightOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/html.jpg b/webgoat-container/src/main/resources/static/images/buttons/html.jpg deleted file mode 100644 index 6a35166ca..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/html.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/htmlOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/htmlOver.jpg deleted file mode 100644 index f02407eb8..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/htmlOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/java.jpg b/webgoat-container/src/main/resources/static/images/buttons/java.jpg deleted file mode 100644 index c150194fd..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/java.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/javaOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/javaOver.jpg deleted file mode 100644 index f1c62fb4a..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/javaOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/lessonComplete.jpg b/webgoat-container/src/main/resources/static/images/buttons/lessonComplete.jpg deleted file mode 100644 index e46ad6e1f..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/lessonComplete.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/logout.jpg b/webgoat-container/src/main/resources/static/images/buttons/logout.jpg deleted file mode 100644 index c22f7acce..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/logout.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/logoutOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/logoutOver.jpg deleted file mode 100644 index bef8a9133..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/logoutOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/params.jpg b/webgoat-container/src/main/resources/static/images/buttons/params.jpg deleted file mode 100644 index 55a43fa6f..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/params.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/paramsOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/paramsOver.jpg deleted file mode 100644 index c51a7b5e9..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/paramsOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/plans.jpg b/webgoat-container/src/main/resources/static/images/buttons/plans.jpg deleted file mode 100644 index 11e2dfb38..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/plans.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/plansOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/plansOver.jpg deleted file mode 100644 index 6682c4f3c..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/plansOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/solutions.jpg b/webgoat-container/src/main/resources/static/images/buttons/solutions.jpg deleted file mode 100644 index 16f995d48..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/solutions.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/buttons/solutionsOver.jpg b/webgoat-container/src/main/resources/static/images/buttons/solutionsOver.jpg deleted file mode 100644 index 210c126e8..000000000 Binary files a/webgoat-container/src/main/resources/static/images/buttons/solutionsOver.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/header/header.jpg b/webgoat-container/src/main/resources/static/images/header/header.jpg deleted file mode 100644 index 8900b1327..000000000 Binary files a/webgoat-container/src/main/resources/static/images/header/header.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/header/header_ASP.jpg b/webgoat-container/src/main/resources/static/images/header/header_ASP.jpg deleted file mode 100644 index 0bf017439..000000000 Binary files a/webgoat-container/src/main/resources/static/images/header/header_ASP.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/header/header_CShrp.jpg b/webgoat-container/src/main/resources/static/images/header/header_CShrp.jpg deleted file mode 100644 index 81b610ecf..000000000 Binary files a/webgoat-container/src/main/resources/static/images/header/header_CShrp.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/header/header_coldFusion.jpg b/webgoat-container/src/main/resources/static/images/header/header_coldFusion.jpg deleted file mode 100644 index ecb3e78ff..000000000 Binary files a/webgoat-container/src/main/resources/static/images/header/header_coldFusion.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/header/header_dotNet.jpg b/webgoat-container/src/main/resources/static/images/header/header_dotNet.jpg deleted file mode 100644 index 30f59ffed..000000000 Binary files a/webgoat-container/src/main/resources/static/images/header/header_dotNet.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/icons/rightArrow.jpg b/webgoat-container/src/main/resources/static/images/icons/rightArrow.jpg deleted file mode 100644 index b89abbb19..000000000 Binary files a/webgoat-container/src/main/resources/static/images/icons/rightArrow.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/introduction/HowToUse_2.jpg b/webgoat-container/src/main/resources/static/images/introduction/HowToUse_2.jpg deleted file mode 100644 index 982f3f7bc..000000000 Binary files a/webgoat-container/src/main/resources/static/images/introduction/HowToUse_2.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/introduction/HowToUse_3.jpg b/webgoat-container/src/main/resources/static/images/introduction/HowToUse_3.jpg deleted file mode 100644 index e1e831404..000000000 Binary files a/webgoat-container/src/main/resources/static/images/introduction/HowToUse_3.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/introduction/UsefulTools-ZAP.png b/webgoat-container/src/main/resources/static/images/introduction/UsefulTools-ZAP.png deleted file mode 100644 index ad1c59350..000000000 Binary files a/webgoat-container/src/main/resources/static/images/introduction/UsefulTools-ZAP.png and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/introduction/UsefulTools-ZAP_1.png b/webgoat-container/src/main/resources/static/images/introduction/UsefulTools-ZAP_1.png deleted file mode 100644 index 77f1078ab..000000000 Binary files a/webgoat-container/src/main/resources/static/images/introduction/UsefulTools-ZAP_1.png and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/introduction/interface.png b/webgoat-container/src/main/resources/static/images/introduction/interface.png deleted file mode 100644 index 71320fb47..000000000 Binary files a/webgoat-container/src/main/resources/static/images/introduction/interface.png and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/introduction/wireshark.png b/webgoat-container/src/main/resources/static/images/introduction/wireshark.png deleted file mode 100644 index 9478d20bf..000000000 Binary files a/webgoat-container/src/main/resources/static/images/introduction/wireshark.png and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logo.png b/webgoat-container/src/main/resources/static/images/logo.png deleted file mode 100644 index b71450f80..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logo.png and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logos/aspect.jpg b/webgoat-container/src/main/resources/static/images/logos/aspect.jpg deleted file mode 100644 index c6f0defbf..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logos/aspect.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logos/macadamian.gif b/webgoat-container/src/main/resources/static/images/logos/macadamian.gif deleted file mode 100644 index 78026f3df..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logos/macadamian.gif and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logos/mandiant.png b/webgoat-container/src/main/resources/static/images/logos/mandiant.png deleted file mode 100644 index 7ae27d43d..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logos/mandiant.png and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logos/ounce.jpg b/webgoat-container/src/main/resources/static/images/logos/ounce.jpg deleted file mode 100644 index 459afb5a4..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logos/ounce.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logos/owasp.jpg b/webgoat-container/src/main/resources/static/images/logos/owasp.jpg deleted file mode 100644 index 3934b7a49..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logos/owasp.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logos/parasoft.jpg b/webgoat-container/src/main/resources/static/images/logos/parasoft.jpg deleted file mode 100644 index 2f13e5e05..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logos/parasoft.jpg and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logos/sages.png b/webgoat-container/src/main/resources/static/images/logos/sages.png deleted file mode 100644 index 9cf751ba6..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logos/sages.png and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logos/seleucus.png b/webgoat-container/src/main/resources/static/images/logos/seleucus.png deleted file mode 100644 index f95c1dce4..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logos/seleucus.png and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logos/softwaresecured.gif b/webgoat-container/src/main/resources/static/images/logos/softwaresecured.gif deleted file mode 100644 index 69e7c42cc..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logos/softwaresecured.gif and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/logos/zionsecurity.gif b/webgoat-container/src/main/resources/static/images/logos/zionsecurity.gif deleted file mode 100644 index fdfd67467..000000000 Binary files a/webgoat-container/src/main/resources/static/images/logos/zionsecurity.gif and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/menu_images/1x1.gif b/webgoat-container/src/main/resources/static/images/menu_images/1x1.gif deleted file mode 100644 index c95709f1a..000000000 Binary files a/webgoat-container/src/main/resources/static/images/menu_images/1x1.gif and /dev/null differ diff --git a/webgoat-container/src/main/resources/static/images/webBg.png b/webgoat-container/src/main/resources/static/images/webBg.png deleted file mode 100644 index be3fbad98..000000000 Binary files a/webgoat-container/src/main/resources/static/images/webBg.png and /dev/null differ diff --git a/webgoat-container/src/main/resources/templates/main_new.html b/webgoat-container/src/main/resources/templates/main_new.html index 7b4e8d89d..16ee995e9 100644 --- a/webgoat-container/src/main/resources/templates/main_new.html +++ b/webgoat-container/src/main/resources/templates/main_new.html @@ -16,6 +16,8 @@ + + diff --git a/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java b/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java index bd2d33b4f..65333bacc 100644 --- a/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java +++ b/webgoat-container/src/test/java/org/owasp/webgoat/assignments/AssignmentEndpointTest.java @@ -38,10 +38,6 @@ import org.springframework.web.servlet.i18n.FixedLocaleResolver; import java.util.Locale; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; - public class AssignmentEndpointTest { @Mock diff --git a/webgoat-lessons/path-traversal/src/test/java/org/owasp/webgoat/path_traversal/ProfileUploadFixTest.java b/webgoat-lessons/path-traversal/src/test/java/org/owasp/webgoat/path_traversal/ProfileUploadFixTest.java index c9f717b6d..2b2edddbf 100644 --- a/webgoat-lessons/path-traversal/src/test/java/org/owasp/webgoat/path_traversal/ProfileUploadFixTest.java +++ b/webgoat-lessons/path-traversal/src/test/java/org/owasp/webgoat/path_traversal/ProfileUploadFixTest.java @@ -1,27 +1,22 @@ package org.owasp.webgoat.path_traversal; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.io.File; + import org.hamcrest.CoreMatchers; -import org.junit.After; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.owasp.webgoat.plugins.LessonTest; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.mock.web.MockMultipartFile; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import java.io.File; - -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @RunWith(SpringJUnit4ClassRunner.class) public class ProfileUploadFixTest extends LessonTest { diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/xxe/Comments.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/xxe/Comments.java index c711e7f13..5daea1688 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/xxe/Comments.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/xxe/Comments.java @@ -33,8 +33,10 @@ import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import java.io.IOException; import java.io.StringReader; @@ -76,17 +78,18 @@ public class Comments { return allComments.stream().sorted(Comparator.comparing(Comment::getDateTime).reversed()).collect(Collectors.toList()); } - protected Comment parseXml(String xml) throws Exception { - JAXBContext jc = JAXBContext.newInstance(Comment.class); + /** + * Notice this parse method is not a "trick" to get the XXE working, we need to catch some of the exception which + * might happen during when users post message (we want to give feedback track progress etc). In real life the + * XmlMapper bean defined above will be used automatically and the Comment class can be directly used in the + * controller method (instead of a String) + */ + protected Comment parseXml(String xml) throws JAXBException, XMLStreamException { + var jc = JAXBContext.newInstance(Comment.class); + var xif = XMLInputFactory.newInstance(); + var xsr = xif.createXMLStreamReader(new StringReader(xml)); - XMLInputFactory xif = XMLInputFactory.newFactory(); - xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, true); - xif.setProperty(XMLInputFactory.IS_VALIDATING, false); - - xif.setProperty(XMLInputFactory.SUPPORT_DTD, true); - XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xml)); - - Unmarshaller unmarshaller = jc.createUnmarshaller(); + var unmarshaller = jc.createUnmarshaller(); return (Comment) unmarshaller.unmarshal(xsr); } diff --git a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/xxe/ContentTypeAssignment.java b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/xxe/ContentTypeAssignment.java index aec6b775a..91dc8c5f0 100644 --- a/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/xxe/ContentTypeAssignment.java +++ b/webgoat-lessons/xxe/src/main/java/org/owasp/webgoat/xxe/ContentTypeAssignment.java @@ -48,7 +48,7 @@ public class ContentTypeAssignment extends AssignmentEndpoint { @Autowired private Comments comments; - @PostMapping(path = "xxe/content-type", consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(path = "xxe/content-type") @ResponseBody public AttackResult createNewUser(@RequestBody String commentStr, @RequestHeader("Content-Type") String contentType) throws Exception { AttackResult attackResult = failed(this).build(); diff --git a/webgoat-lessons/xxe/src/main/resources/html/XXE.html b/webgoat-lessons/xxe/src/main/resources/html/XXE.html index f0706e8e3..5c05d929d 100644 --- a/webgoat-lessons/xxe/src/main/resources/html/XXE.html +++ b/webgoat-lessons/xxe/src/main/resources/html/XXE.html @@ -3,19 +3,17 @@
- -
- -
+
+
+
+
@@ -75,6 +73,16 @@
+
+
+
+
+
+ +
+
+
+
@@ -132,6 +140,11 @@
+
+
+
+
+
diff --git a/webgoat-lessons/xxe/src/main/resources/images/etc_password.png b/webgoat-lessons/xxe/src/main/resources/images/etc_password.png new file mode 100644 index 000000000..a250061ae Binary files /dev/null and b/webgoat-lessons/xxe/src/main/resources/images/etc_password.png differ diff --git a/webgoat-lessons/xxe/src/main/resources/images/xxe-parser.png b/webgoat-lessons/xxe/src/main/resources/images/xxe-parser.png new file mode 100644 index 000000000..1f9355418 Binary files /dev/null and b/webgoat-lessons/xxe/src/main/resources/images/xxe-parser.png differ diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc index e8cfe8f71..3915b08bc 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind.adoc @@ -4,8 +4,7 @@ In some cases you will see no output because although your attack might have wor Or the resource you are trying to read contains illegal XML character which causes the parser to fail. Let's start with an example, in this case we reference an external DTD which we control on our own server. -As an attacker you have WebWolf under your control (*this can be any server under your control.*), you can for example -use this server to ping it using `webWolfRootLink:landing[noLink]` +As an attacker you have WebWolf under your control (*this can be any server under your control.*), you can for example use this server to ping it using `webWolfRootLink:landing[noLink]` How do we use this endpoint to verify whether we can perform XXE? @@ -50,5 +49,4 @@ Now in WebWolf browse to 'Incoming requests' and you will see: } ---- -So with the XXE we are able to ping our own server which means XXE injection is possible. So with the XXE injection -we are basically able to reach the same effect as we did in the beginning with the curl command. +So with the XXE we are able to ping our own server which means XXE injection is possible. So with the XXE injection we are basically able to reach the same effect as we did in the beginning with the curl command. diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc index 5fc49e406..a6e060d9e 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_blind_assignment.adoc @@ -1,8 +1,6 @@ == Blind XXE assignment -In the previous page we showed you how you can ping a server with a XXE attack, in this assignment try to make a DTD -which will upload the contents of a file secret.txt from the WebGoat server to our WebWolf server. You can use WebWolf to serve your DTD. -The secret.txt is located on the WebGoat server in this location, so you do not need to scan all directories and files: +In the previous page we showed you how you can ping a server with a XXE attack, in this assignment try to make a DTD which will upload the contents of a file secret.txt from the WebGoat server to our WebWolf server. You can use WebWolf to serve your DTD. The secret.txt is located on the WebGoat server in this location, so you do not need to scan all directories and files: |=== diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type.adoc index 77d9cacc8..73e4a9edd 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type.adoc @@ -1,7 +1,6 @@ == Modern REST framework -In modern REST frameworks the server might be able to accepts data formats that you as a developer did not think about. -So this might result in JSON endpoints being vulnerable to XXE attacks. +In modern REST frameworks the server might be able to accepts data formats that you as a developer did not think about. So this might result in JSON endpoints being vulnerable to XXE attacks. Again same exercise but try to perform the same XML injection as we did in first assignment. diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type_solution.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type_solution.adoc new file mode 100644 index 000000000..52866ee4b --- /dev/null +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_changing_content_type_solution.adoc @@ -0,0 +1,71 @@ +=== Assignment solution + +The idea behind this assignment is that while it may look that the application is only accepting JSON but if we change the body of the message to XML the framework might process it. When you try entering a comment the body of request will be: + +[source, json] +---- +{"text":"My first comment"} +---- + +This is a normal json message, let's try to change the content-type of the request + +[source] +---- +POST http://localhost:8080/WebGoat/xxe/content-type HTTP/1.1 +Content-Type: application/xml + +{"text":"My first comment"} +---- + +this results in the following exception: + +[source] +---- +javax.xml.bind.UnmarshalException\n - with linked exception:\n[javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]\nMessage: Content is not allowed in prolog. +---- + +Depending on the XML parser you might get a better error message, in this case the message is a bit cryptic, it means that we are not sending valid xml. For example the Jackson library gives the following message: + +[source] +---- +JSON parse error: Unexpected character '{' (code 123) in prolog; expected + '<'\n at [row,col {unknown-source}]: [1,1]; nested exception is com.fasterxml.jackson.core.JsonParseException: + Unexpected character '{' (code 123) in prolog; expected '<'\n at [row,col {unknown-source}]: [1,1]“ +---- + +This error message appears because we are still sending a json message towards the endpoint, so if we intercept and change change the json message to a xml message: + +[souce] +---- +POST http://localhost:8080/WebGoat/xxe/content-type HTTP/1.1 +Content-Type: application/xml + +This is my first message +---- + +Again an error message from the endpoint: + +[source] +---- +"javax.xml.bind.UnmarshalException\\n - with linked exception:\\n[com.sun.istack.SAXParseException2; lineNumber: 1; columnNumber: 7; unexpected element (uri:\\\"\\\", local:\\\"text\\\"). Expected elements are <{}comment>] +---- + +The parser complains that the message is not a valid xml message and needs to be embedded in a `comment` tag: + +[source, xml] +---- +POST http://localhost:8080/WebGoat/xxe/content-type HTTP/1.1 +Content-Type: application/xml + +This is my first message +---- + +The endpoint no longer complains and if you refresh the page in WebGoat the posted comments appear. For the attack to work we need to post: + +[source, xml] +---- +POST http://localhost:8080/WebGoat/xxe/content-type HTTP/1.1 +Content-Type: application/xml + + ]>&root;This is my first message +---- diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_code.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_code.adoc new file mode 100644 index 000000000..67716cbe9 --- /dev/null +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_code.adoc @@ -0,0 +1,77 @@ +=== Find XXE with a code review + +Now we know how the injection work, let's look at why this can happen. In Java applications XML library configuration is not secure by default, and you have to change the settings. Suppose you find the following code snippet during a code review: + +[source, java] +---- +public XmlMapper xmlMapper() { + return new XmlMapper(XMLInputFactory.newInstance()) // <1> +} +---- + +.while having a look at the release notes of the Jackson library you read: +[quote, Jackson 2.7.8 (26-Sep-2016)] +211: Disable ``SUPPORT_DTD`` for ``XMLInputFactory`` unless explicitly overridden + +==== Question: is the parser vulnerable? + +This piece of code defines a new `XmlMapper` (`ObjectMapper`) which is a popular framework for reading and writing xml and json. If we follow the code one level deeper we find: + +[source, java] +---- +/** + * @since 2.4 + */ +public XmlMapper(XMLInputFactory inputF) { // <2> + this(new XmlFactory(inputF)); //<3> +} +---- +<2> This is the 'constructor' we called from the listing above (1) +<3> Call to another 'constructor' and initialize a new instance of `XmlFactory` + +Let's take a look at the source code of `XMLFactory` + +[source, java] +---- +public XmlFactory(XMLInputFactory xmlIn) { // <4> + this(xmlIn, null); } // <5> + +protected XmlFactory(XMLInputFactory xmlIn, XMLOutputFactory xmlOut, ...) { // <6> + if (xmlIn == null) { //<7> + xmlIn = XMLInputFactory.newInstance(); + // as per [dataformat-xml#190], disable external entity expansion by default + xmlIn.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); // <8> + // and ditto wrt [dataformat-xml#211], SUPPORT_DTD + xmlIn.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); // <9> + } +} +---- +<4> This is the 'constructor' definition of the new instance created in 3 +<5> Call to another 'constructor' defined in 6 +<8> XXE protection +<9> XXE protection + +In 7 we know `if (xmlIn == null)` will not be true because if we look at our declaration at the top we created our own instance `XMLInputFactory.newInstance()` which is not `null`. This means that we have a XML parser which is by default **not** secured against XXE injection. The interesting part at 8 and 9 is the extra protection nested inside the if statement. + +If we look at the Spring Boot framework for example how they initialize the same parser: + +[source, java] +---- +public ObjectMapper create() { + return new XmlMapper(xmlInputFactory()); // <1> +} + +private static XMLInputFactory xmlInputFactory() { + XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); + inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); + return inputFactory; +} +---- +<1> Call to a method which initializes the parser safely + +As you can see the explicitly define the ``XMLInputFactory`` through the private method ``xmlInputFactory()`` which actually sets the same properties to the parser as we saw in the previous listing. + +As you can see this it is not that easy to find out whether the parser is secure against the injection you really have to dig deep in the code, and the library to find out what the parser settings are. + +Take a look at https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html[XXE prevention sheet] for more ways to secure your parser. diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_intro.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_intro.adoc index 98e3af1f5..30a368348 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_intro.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_intro.adoc @@ -1,7 +1,6 @@ === What is a XML entity? -An XML Entity allows tags to be defined that will be replaced by content when the XML Document is parsed. -In general there are three types of entities: +An XML Entity allows tags to be defined that will be replaced by content when the XML Document is parsed. In general there are three types of entities: * internal entities * external entities @@ -9,30 +8,17 @@ In general there are three types of entities: An entity must be created in the Document Type Definition (DTD), let's start with an example: -[source] ----- - - - -]> -&js; ----- +[role="lesson-image"] +image::images/xxe-parser.png[XML parser] + +As you can see once the XML document is processed by the parser, it will replace the defined entity `js` with the defined constant "Jo Smith". As you can see this has many advantages as you can change `js` in one place to for example "John Smith". -So everywhere you use the entity `&js;` the parser will replace it with the value defined in the entity. === What is an XXE injection? -An XML External Entity attack is a type of attack against an application that parses XML input. This attack occurs when XML input containing a -reference to an external entity is processed by a weakly configured XML parser. This attack may lead to the disclosure of confidential data, -denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts. +An XML External Entity attack is a type of attack against an application that parses XML input. This attack occurs when XML input containing a reference to an external entity is processed by a weakly configured XML parser. This attack may lead to the disclosure of confidential data, denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts. -Attacks can include disclosing local files, which may contain sensitive data such as passwords or private user data, using file: schemes or relative -paths in the system identifier. Since the attack occurs relative to the application processing the XML document, an attacker may use this -trusted application to pivot to other internal systems, possibly disclosing other internal content via http(s) requests or launching a CSRF attack to -any unprotected internal services. In some situations, an XML processor library that is vulnerable to client-side memory corruption issues -may be exploited by dereferencing a malicious URI, possibly allowing arbitrary code execution under the application account. Other attacks can access -local resources that may not stop returning data, possibly impacting application availability if too many threads or processes are not released. +Attacks can include disclosing local files, which may contain sensitive data such as passwords or private user data, using file: schemes or relative paths in the system identifier. Since the attack occurs relative to the application processing the XML document, an attacker may use this trusted application to pivot to other internal systems, possibly disclosing other internal content via http(s) requests or launching a CSRF attack to any unprotected internal services. In some situations, an XML processor library that is vulnerable to client-side memory corruption issues may be exploited by dereferencing a malicious URI, possibly allowing arbitrary code execution under the application account. Other attacks can access local resources that may not stop returning data, possibly impacting application availability if too many threads or processes are not released. In general we can distinguish the following kind of XXE attacks: diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_mitigation.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_mitigation.adoc index 2e30c8a40..52e4e9bf4 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_mitigation.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_mitigation.adoc @@ -1,7 +1,6 @@ == XXE mitigation -In order to protect against XXE attacks you need to make sure you validate the input received from an untrusted client. -In the Java world you can also instruct your parser to ignore DTD completely, for example: +In order to protect against XXE attacks you need to make sure you validate the input received from an untrusted client. In the Java world you can also instruct your parser to ignore DTD completely, for example: [source] ---- @@ -18,12 +17,9 @@ xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); xif.setProperty(XMLInputFactory.SUPPORT_DTD, true); ---- -For more information about configuration, see https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet +For more information about configuration, see https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html[XXE prevention sheet] ==== Validate -Implement proper validation for the Content-type and Accept header do not simply rely on the framework to handle - the incoming request. Also if the client specifies a proper accept header return with a `406/Not Acceptable. - -` \ No newline at end of file +Implement proper validation for the Content-type and Accept header do not simply rely on the framework to handle the incoming request. If the client specifies a proper accept header return with a `406/Not Acceptable. \ No newline at end of file diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_overflow.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_overflow.adoc index af808281a..604bd70e3 100644 --- a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_overflow.adoc +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_overflow.adoc @@ -21,9 +21,7 @@ With the same XXE attack we can perform a DOS service attack towards the server. &lol9; ---- -When XML parser loads this document, it sees that it includes one root element, "lolz", that contains the text "&lol9;". However, "&lol9;" is a defined -entity that expands to a string containing ten "&lol8;" strings. Each "&lol8;" string is a defined entity that expands to ten "&lol7;" strings, and so on. -After all the entity expansions have been processed, this small (< 1 KB) block of XML will actually take up almost 3 gigabytes of memory. +When XML parser loads this document, it sees that it includes one root element, "lolz", that contains the text "&lol9;". However, "&lol9;" is a defined entity that expands to a string containing ten "&lol8;" strings. Each "&lol8;" string is a defined entity that expands to ten "&lol7;" strings, and so on. After all the entity expansions have been processed, this small (< 1 KB) block of XML will actually take up almost 3 gigabytes of memory. This is called a "Billion laughs", more information can be found here: https://en.wikipedia.org/wiki/Billion_laughs diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_simple_introduction.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_simple_introduction.adoc new file mode 100644 index 000000000..613e46b70 --- /dev/null +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_simple_introduction.adoc @@ -0,0 +1,60 @@ +=== XXE example + +Let's look at an example of an XXE injection, in the previous section we saw that XML entities can be used as follows: + +[source, xml] +---- + + + +]> +&js; +---- + +=== External DTD declaration + +Defining these entities also makes it possible to define another DTD in an external file, for example: + +[source, xml] +---- + + + + webgoat@webgoat.org + webwolf@webwolf.org + Your app is great, but contains flaws + Hi, your application contains some SQL injections + +---- + +and the `email.dtd` can be defined as follows: + +[source, dtd] +---- + + + + + +---- + +=== XXE + +If a XML parser is configured to allow external DTD or entities we can change the following XML snippet with the following: + +[source, xml] +---- + + +]> +&js; +---- + +Now what happens? We defined an include from the local filesystem, the XML parser will load the file and will add the contents wherever the entity is referenced. Let's assume the XML message is returned to the user the message will be: + +[role="lesson-image"] +image::images/etc_password.png[Password] + +NOTE: The extra document type definition(DOCTYPE) is something you can always add to the xml document and if the parser settings are enabled to allow external entities to be processed you are off to a good start for finding a XXE injection. \ No newline at end of file diff --git a/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_simple_solution.adoc b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_simple_solution.adoc new file mode 100644 index 000000000..a3469d573 --- /dev/null +++ b/webgoat-lessons/xxe/src/main/resources/lessonPlans/en/XXE_simple_solution.adoc @@ -0,0 +1,52 @@ +=== Assignment solution + +The goal of the exercise is to list the root of the file system. If we first try a normal post we see the following request: + +[source, xml] +---- +POST /WebGoat/xxe/simple +Content-Type: application/xml + +This is my first comment, nice picture +---- + +The web page is making a xhr request to post a xml message, after that the comment is displayed in the comment section. Now let's try change the request a bit as shown in the previous section: + +[source, xml] +---- +POST /WebGoat/xxe/simple +Content-Type: application/xml + + ]>&root; +---- + +So instead of including a specific file we make a reference to the root of the filesystem with `file:///`. If we just copy and paste this in the comment text box you will get an error in the response body + +[source,json] +---- +{ + "lessonCompleted" : false, + "feedback" : "Sorry the solution is not correct, please try again.", + "output" : "...javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,44]\\nMessage: The processing instruction target matching \\\"[xX][mM][lL]\\\" is not allowed.]" + "assignment" : "SimpleXXE", + "attemptWasMade" : true +} +---- + +This is due to the fact that the JavaScript is taking the input and creates the following message: + +[source%linenums, xml] +---- +POST /WebGoat/xxe/simple +Content-Type: application/xml + + + + + ]>&root; + + +---- +Line 7 contains the input entered in text box if we would use the comment form. + +To solve the lesson you have to intercept the complete the outgoing request and replace the complete body with the solution. See our lessons about intercepting HTTP traffic. \ No newline at end of file