From d1f32ddaf9f51b037f8221460cfba10bdcd2e141 Mon Sep 17 00:00:00 2001 From: vjeantet Date: Wed, 23 Sep 2020 22:39:42 +0200 Subject: add checklist kind of pages --- assets/sass/checklist.scss | 70 ++++++ assets/sass/layout.scss | 4 +- assets/sass/main.scss | 16 +- assets/sass/shortcodes/notice.scss | 66 ++--- .../_layout/article-sidebar-after/_index.md | 3 + exampleSite/content/checklist/01_appmetadata.md | 16 ++ .../content/checklist/02_vulnerabilityreporting.md | 25 ++ exampleSite/content/checklist/03_https.md | 135 ++++++++++ exampleSite/content/checklist/04_authz.md | 119 +++++++++ .../04_authz_AuthenticationCookiesandSessions.md | 104 ++++++++ .../content/checklist/04_authz_Authorization.md | 44 ++++ ...authz_AuthorizationRelatedWebVulnerabilities.md | 123 +++++++++ .../content/checklist/04_authz_OAuth2Login.md | 31 +++ .../04_authz_UsernamePasswordAuthentication.md | 142 +++++++++++ exampleSite/content/checklist/05_commonvuln.md | 81 ++++++ .../checklist/05_commonvuln_BrowserPlugins.md | 49 ++++ .../checklist/05_commonvuln_CrossSiteScripting.md | 136 ++++++++++ .../content/checklist/05_commonvuln_FileUploads.md | 109 ++++++++ ...05_commonvuln_PersistenceBackEndsandQuerying.md | 67 +++++ .../checklist/05_commonvuln_UseofCryptography.md | 11 + exampleSite/content/checklist/06_testing.md | 111 +++++++++ .../content/checklist/__article-sidebar-after.md | 12 + exampleSite/content/checklist/_index.md | 267 ++++++++++++++++++++ .../00-adding-content/page-checklist/_index.md | 34 +++ ...t.scss_830e2c6732622c34cf9ed8a208896bac.content | 42 ++++ ...list.scss_830e2c6732622c34cf9ed8a208896bac.json | 1 + ...t.scss_f300667da4f5b5f84e1a9e0702b2fdde.content | 4 +- ...n.scss_97a9b8e6852415b29a37632934745b8b.content | 15 +- ...e.scss_f300667da4f5b5f84e1a9e0702b2fdde.content | 19 +- i18n/en.toml | 11 +- i18n/fr.toml | 11 +- layouts/index.json | 2 + layouts/partials/_checklist-footer.html | 8 + layouts/partials/_checklist-header.html | 16 ++ layouts/partials/_mdinclude.html | 18 +- layouts/partials/body-article-content.html | 16 +- layouts/partials/body-article-sidepage.html | 5 +- layouts/partials/body-footer.html | 2 +- layouts/partials/body-header.html | 2 +- layouts/partials/body-sidebar.html | 4 +- layouts/partials/html-head.html | 11 + layouts/shortcodes/alert.html | 2 +- layouts/shortcodes/attachments.html | 2 +- layouts/shortcodes/c/check.html | 29 +++ layouts/shortcodes/c/choices.html | 31 +++ layouts/shortcodes/c/list.html | 34 +++ layouts/shortcodes/c/show.html | 12 + layouts/shortcodes/c/switch.html | 8 + layouts/shortcodes/c/text.html | 19 ++ layouts/shortcodes/children.html | 2 +- layouts/shortcodes/columns.html | 2 +- layouts/shortcodes/include.html | 9 + layouts/shortcodes/notice.html | 2 +- layouts/shortcodes/panel.html | 2 +- layouts/shortcodes/tabs.html | 2 +- static/js/checklist.js | 276 +++++++++++++++++++++ 56 files changed, 2330 insertions(+), 64 deletions(-) create mode 100644 assets/sass/checklist.scss create mode 100644 exampleSite/content/_layout/article-sidebar-after/_index.md create mode 100644 exampleSite/content/checklist/01_appmetadata.md create mode 100644 exampleSite/content/checklist/02_vulnerabilityreporting.md create mode 100644 exampleSite/content/checklist/03_https.md create mode 100644 exampleSite/content/checklist/04_authz.md create mode 100644 exampleSite/content/checklist/04_authz_AuthenticationCookiesandSessions.md create mode 100644 exampleSite/content/checklist/04_authz_Authorization.md create mode 100644 exampleSite/content/checklist/04_authz_AuthorizationRelatedWebVulnerabilities.md create mode 100644 exampleSite/content/checklist/04_authz_OAuth2Login.md create mode 100644 exampleSite/content/checklist/04_authz_UsernamePasswordAuthentication.md create mode 100644 exampleSite/content/checklist/05_commonvuln.md create mode 100644 exampleSite/content/checklist/05_commonvuln_BrowserPlugins.md create mode 100644 exampleSite/content/checklist/05_commonvuln_CrossSiteScripting.md create mode 100644 exampleSite/content/checklist/05_commonvuln_FileUploads.md create mode 100644 exampleSite/content/checklist/05_commonvuln_PersistenceBackEndsandQuerying.md create mode 100644 exampleSite/content/checklist/05_commonvuln_UseofCryptography.md create mode 100644 exampleSite/content/checklist/06_testing.md create mode 100644 exampleSite/content/checklist/__article-sidebar-after.md create mode 100644 exampleSite/content/checklist/_index.md create mode 100644 exampleSite/content/content-and-customization/00-adding-content/page-checklist/_index.md create mode 100644 exampleSite/resources/_gen/assets/scss/sass/checklist.scss_830e2c6732622c34cf9ed8a208896bac.content create mode 100644 exampleSite/resources/_gen/assets/scss/sass/checklist.scss_830e2c6732622c34cf9ed8a208896bac.json create mode 100644 layouts/partials/_checklist-footer.html create mode 100644 layouts/partials/_checklist-header.html create mode 100644 layouts/shortcodes/c/check.html create mode 100644 layouts/shortcodes/c/choices.html create mode 100644 layouts/shortcodes/c/list.html create mode 100644 layouts/shortcodes/c/show.html create mode 100644 layouts/shortcodes/c/switch.html create mode 100644 layouts/shortcodes/c/text.html create mode 100644 layouts/shortcodes/include.html create mode 100644 static/js/checklist.js diff --git a/assets/sass/checklist.scss b/assets/sass/checklist.scss new file mode 100644 index 0000000..a2eb688 --- /dev/null +++ b/assets/sass/checklist.scss @@ -0,0 +1,70 @@ +body { + article section.page div.content { + div.checklist-header { + .form-control-file { + position: relative; + width: 100%; + height: 100%; + min-height: 6em; + outline: none; + visibility: hidden; + cursor: pointer; + background-color: #c61c23; + box-shadow: 0 0 5px solid currentColor; + + &:before { + content: attr(data-title); + position: absolute; + top: 0.5em; + left: 0; + width: 100%; + min-height: 4em; + line-height: 0.5em; + padding-top: 1.5em; + opacity: 1; + visibility: visible; + text-align: center; + border: 0.25em dashed currentColor; + transition: all 0.3s cubic-bezier(.25, .8, .25, 1); + overflow: hidden; + } + + &:hover { + &:before { + border-style: solid; + box-shadow: inset 0px 0px 0px 0.25em currentColor; + } + } + } + } + + + + div.checklist-footer { + margin-top: 2em; + margin-bottom: 2em; + text-align: center; + } + } + + + + #TableOfContents > ul li { + input { + margin-right: 0.3em; + } + + &:not(.cl-ready):not(.cl-done):not(.cl-doing) { + input{ + visibility: hidden; + } + } + + &.cl-ready,&.cl-doing,&.cl-done { + input { + visibility: visible; + } + } + } + +} \ No newline at end of file diff --git a/assets/sass/layout.scss b/assets/sass/layout.scss index 20d01ba..eb1c611 100644 --- a/assets/sass/layout.scss +++ b/assets/sass/layout.scss @@ -108,7 +108,7 @@ body:not(.render_raw) { margin-top: 0.5em; margin-left: 0.2em; ul{ - padding-left: 20px; + padding-left: 10px; } nav{ @@ -116,7 +116,7 @@ body:not(.render_raw) { position: absolute; z-index: 5; border: 1px solid ; - padding: 3px 30px; + padding: 1em 30px; border-radius: 3px; min-width: 25%; max-width: 50%; diff --git a/assets/sass/main.scss b/assets/sass/main.scss index e237708..40b2b75 100644 --- a/assets/sass/main.scss +++ b/assets/sass/main.scss @@ -299,6 +299,8 @@ article section.page { font-size: smaller; color:$c_dark2; ul{ + padding-left-left: 0px; + list-style-type: none; li a{ color:$c_saturate3; } @@ -306,6 +308,7 @@ article section.page { nav{ background-color: white; + opacity: 0.95; } } @@ -399,6 +402,11 @@ article section.page div.content{ text-decoration: underline; } + p { + margin-top: 1rem; + margin-bottom: 1rem; + } + h1 { color:$c_dark1; @@ -414,7 +422,13 @@ article section.page div.content{ font-weight:700; letter-spacing:-0.95px; - } // TABLE + } + + h3,h4 { + margin-top: 0.5em; + } + + // TABLE table { width: 100%; margin-bottom: 2em; diff --git a/assets/sass/shortcodes/notice.scss b/assets/sass/shortcodes/notice.scss index e6291c5..eb2dff9 100644 --- a/assets/sass/shortcodes/notice.scss +++ b/assets/sass/shortcodes/notice.scss @@ -9,38 +9,48 @@ $color_dark : #343a40 ; $color_white : #fff ; $color_transparent : transparent ; +div.notices { + margin-top: 1rem; + margin-bottom: 1rem; +} - div.notices p { - /*box-shadow: inset 4px 0 0 black;*/ - /*border-radius: .2rem;*/ - background: white; - padding: .5rem 1rem .5rem 1rem; - margin-top: 0px; - box-sizing: border-box; - box-shadow: inset 4px 0 0 black; - background-color: lighten(black,90%); - font-size: smaller; - } +div.notices > * { + background: white; + margin-top: 0px!important; + margin-bottom: 0px!important; + box-sizing: border-box; + box-shadow: inset 4px 0 0 black; + background-color: lighten(black,90%); + font-size: smaller; +} +div.notices > *:not(ul) { + /*box-shadow: inset 4px 0 0 black;*/ + /*border-radius: .2rem;*/ + padding: .5rem 1rem .5rem 1rem; +} +div.notices > ul { + +} - div.notices label{ - font-size: 0.5em; - position: absolute; - margin-left: 0em; - margin-top: -1.8em; - font-weight: bold; - font-variant: small-caps; - letter-spacing: 0.6em; - } +div.notices label{ + font-size: 0.5em; + position: absolute; + margin-left: 0em; + margin-top: -1.8em; + font-weight: bold; + font-variant: small-caps; + letter-spacing: 0.6em; +} - div.notices.note { - p { - box-shadow: inset 4px 0 0 $color_primary; - background: transparentize($color_primary, 0.95); - color: darken($color_primary,20%) !important; - } - label{color: $color_primary;} +div.notices.note { + p { + box-shadow: inset 4px 0 0 $color_primary; + background: transparentize($color_primary, 0.95); + color: darken($color_primary,20%) !important; } + label{color: $color_primary;} +} div.notices.primary { p { @@ -79,7 +89,7 @@ div.notices.danger { } div.notices.warning { - p { + >* { box-shadow: inset 4px 0 0 $color_warning; background: transparentize($color_warning, 0.95); color: darken($color_warning,20%) !important; diff --git a/exampleSite/content/_layout/article-sidebar-after/_index.md b/exampleSite/content/_layout/article-sidebar-after/_index.md new file mode 100644 index 0000000..ec380ec --- /dev/null +++ b/exampleSite/content/_layout/article-sidebar-after/_index.md @@ -0,0 +1,3 @@ +--- +--- + diff --git a/exampleSite/content/checklist/01_appmetadata.md b/exampleSite/content/checklist/01_appmetadata.md new file mode 100644 index 0000000..d0fadee --- /dev/null +++ b/exampleSite/content/checklist/01_appmetadata.md @@ -0,0 +1,16 @@ +--- +title: App Metadata +hidden: true +--- + +The name of the application: {{}} + + +A brief description: +{{}} +Lorem placeholder +{{}} + + +What frameworks (if any) does this application require? +{{}} \ No newline at end of file diff --git a/exampleSite/content/checklist/02_vulnerabilityreporting.md b/exampleSite/content/checklist/02_vulnerabilityreporting.md new file mode 100644 index 0000000..1c2e997 --- /dev/null +++ b/exampleSite/content/checklist/02_vulnerabilityreporting.md @@ -0,0 +1,25 @@ +--- +hidden: true +--- +Because no system is entirely free of security issues, it's important to provide ways for external users to offer input and report vulnerabilities. + +**Do you have an easily discoverable way for external researchers to report security vulnerabilities in your systems?** +{{}} + * (yes) Yes, we have a published security email contact, or we provide another way for users to report security issues. Incoming reports are timely reviewed and triaged. + * (no) No, we do not currently offer a way to report security vulnerabilities for priority handling. +{{}} + + +{{}} +{{%notice warning%}} +**Warning — possible medium-risk issue**\ +\ +Make it easy for others to let you know about security issues in your products. That way you'll learn about vulnerabilities earlier and can respond to them quickly. Also, without an easy way to report issues directly to you, external researchers might publish issues widely instead. +\ +\ +If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved: +{{}} +Lorem placeholder +{{}} +{{%/notice%}} +{{}} \ No newline at end of file diff --git a/exampleSite/content/checklist/03_https.md b/exampleSite/content/checklist/03_https.md new file mode 100644 index 0000000..98d0141 --- /dev/null +++ b/exampleSite/content/checklist/03_https.md @@ -0,0 +1,135 @@ +--- +hidden: true +--- + + +**Select the option that best describes your web application:** +{{}} +* (https) The web application is reachable exclusively over HTTPS. Even if the user manually edits the URL to start with `http://`, it won't work or it will redirect to `https://`. +* (http_https) The web application is flexible — users can reach it over HTTP or over HTTPS. +* (http_only) The web application supports HTTP only, and can't be reached over HTTPS even if you edit the URL. +{{}} + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +It's often extremely easy for attackers to eavesdrop on packets transmitted between users and web applications (for example, on public Wi-Fi networks). To avoid exposing sensitive data in transit, any application that allows users to log in — or contains anything but public data — should be available solely over HTTPS. It's also fine to use a web server that listens on port 80 (plain HTTP) and redirects users to the SSL version; this method can make it easier for users to access the application. +\ +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below.** +{{}} + +{{%/notice%}} +{{}} + +{{}} + +### Configuring SSL/TLS + +**Have you recently reviewed your SSL configuration to ensure that only secure protocols and ciphers are offered to clients?** + +{{}} +* (yes) Yes, we regularly review the cipher suite advertised by the server and the protocols it uses. +* (not_sure) We're not sure whether our SSL/TLS configuration is secure. +{{}} + +{{}} +{{%notice%}} +**Tip**\ +\ +Detailed guidance on SSL/TLS and cipher suites is beyond the scope of this questionnaire. A very good and well-maintained resource is [Mozilla's SSL/TLS configuration wiki page](https://wiki.mozilla.org/Security/Server_Side_TLS), which gives up-to-date recommendations for the most common use cases. Another good resource for reviewing the security of your SSL/TLS server is [SSL Labs' server test](https://www.ssllabs.com/ssltest/). +{{%/notice%}} +{{}} + + +**Does your server offer [forward secrecy](https://en.wikipedia.org/wiki/Forward_secrecy) for clients that support it?** + +{{}} +* (yes) Yes, the server supports ECDHE and DHE ciphers that offer forward secrecy. +* (no) No, no ciphers providing forward secrecy are enabled. +{{}} +{{}} +{{%notice%}} +**Tip**\ +\ +In ciphers that support forward secrecy, an ephemeral key is negotiated for each connection, using the Diffie-Hellman algorithm. This key is used for a limited period of time, after which it is "forgotten." Even if the private SSL key is later compromised, an attacker who recorded conversations between the server and clients won't be able to decrypt those conversations without also breaking the associated ephemeral keys. Enabling ciphers that offer forward secrecy can protect your users against future disclosure of the information transmitted between them and your server. +{{%/notice%}} +{{}} + + +**Are your SSL/TLS private keys appropriately protected on your web servers?** +{{}} +* (yes) Yes, we have taken all necessary steps to protect our private keys. +* (no) I'm not sure how well protected they are. +{{}} +{{}} +{{%notice%}} +**Tip**\ +\ +Make sure private SSL/TLS keys are, at a minimum, protected through file system permissions. It's important to make sure the user account that's used to serve web pages does not have access; otherwise, a vulnerability in the web app could easily lead to a compromise of the keys. If you are using an SSL certificate with a wildcard CN (e.g., *.example.net), ensure that the private key is well protected on all the servers it resides on (not just your most important server). +{{%/notice%}} +{{}} + + +**Where is the SSL connection between the user and your application terminated?** +{{}} +* (appserver) At the application server +* (loadbalancer) At the load balancer +* (somewhere) Somewhere else +{{}} + +{{}} +**Provide more details on the termination point:** +{{}} +{{}} + + +{{}} +**How is traffic between the load balancer and the application servers protected?** +{{}} +* (encrypted) Traffic is encrypted and certificates between load balancer and application servers are validated. +* (unencrypted-trusted) Traffic is unencrypted, but all networks transited between load balancers and application servers are owned and exclusively used by us. +* (unencrypted-untrusted) Traffic is unencrypted, and traffic has to transit through networks not owned and exclusively used by us. +* (other) Through other means. +{{}} +{{}} + +{{}} +{{%notice%}} +**Tip**\ +\ +Because user traffic appears to transit networks behind your load balancer that are not fully owned and operated by you, we strongly recommend that you establish another SSL/TLS connection between the load balancer and the servers that actually serve the application. Otherwise, an attacker who can listen in on the traffic behind your load balancers will be able to see unencrypted user data. +{{%/notice%}} +{{}} + +{{}} +**Describe how the traffic is protected:** +{{}} +{{}} + + + +**Applications served over SSL may still be vulnerable to attacks if resources (often JavaScript, style sheets, or other active content) are included over plain HTTP. This defeats the purpose of SSL, because the active content loaded through plain HTTP will have access to the DOM of content protected by SSL. Make sure no resources are included from plain HTTP sites. Typically, browsers will help identify cases where resources from non-SSL sites are included, by displaying [mixed content](https://developer.mozilla.org/en-US/docs/Security/MixedContent) warnings.** + +**To avoid these issues, do you have checks in place to ensure that all references to resources either point to SSL or are protocol-relative?** +{{}} +* (yes) Yes, we are very careful and have specific controls in place to prevent mixed-content issues. +* (no) It wouldn't be too difficult for something to fall through the cracks and introduce mixed-content bugs. +{{}} + +{{}} +{{%notice warning%}} +**Warning — possible medium-risk issue**\ +\ +Mixed content is a big deal, and it's becoming more problematic as an increasing number of users roam on public Wi-Fi and other insecure networks. We recommend cleaning up your codebase to avoid this kind of issue, and establishing procedures to help guard against new instances. +\ +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below.** +{{}} +{{%/notice%}} +{{}} + + + +{{}} diff --git a/exampleSite/content/checklist/04_authz.md b/exampleSite/content/checklist/04_authz.md new file mode 100644 index 0000000..bf9b5d6 --- /dev/null +++ b/exampleSite/content/checklist/04_authz.md @@ -0,0 +1,119 @@ +--- +hidden: true +--- + +**To get started, tell us a little about your application so we can ask you the right questions.** +{{}} +* (login_required) Our application requires regular users to log in. Most features aren't available without logging in. +* (isolated_admin_ui) In addition to an interface for regular users, our application provides an administration interface. +* (rbac_model) Our application features complex user management. Various roles can be assigned to user accounts. +{{}} + +{{}} +**Briefly describe the different roles your application provides. If your application also offers custom role definitions, be sure to mention that.** +{{}} +{{}} + + + + +{{}} +**Is your application integrated with any of the following single sign-on (SSO) mechanisms?** +{{}} +* (SAML2) SAML 2.0 +* (OpenIDConnectOAuth2) OpenID Connect / OAuth2 Login +* (OpenID2) OpenID 2.0 +* (LDAP) LDAP / Active Directory +* (other) Other +* (none) None of the above +{{}} + +{{}} +**What other SSO mechanisms does the application support?** +{{}} +{{}} + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +OpenID 2.0 has been replaced by OpenID Connect (also called OAuth2 Login). We recommend updating your application's SSO integration to support OpenID Connect. +{{%/notice%}} +{{}} + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +Integrating with LDAP and/or Active Directory has a significant downside: any application that integrates with it has to receive the user's SSO password. As a result, a vulnerability in any integrated application puts the password at risk for all other applications. We recommend using an SSO mechanism that does not require the password to be sent anywhere other than a central authentication system. +{{%/notice%}} +{{}} + +{{}} +### OAuth2 Login +{{%include 04_authz_OAuth2Login.md%}} +{{}} + + + + + +**Does any part of the application employ username/password-based authentication?** +{{}} +* (yes) Yes +* (no) No, all authentication is based on single sign-on (SSO). +{{}} + +{{}} +### Username/Password Authentication +{{%include 04_authz_UsernamePasswordAuthentication.md%}} +{{}} + +{{}} + + + + + + + + + + + + + +{{}} +### Authentication Cookies and Sessions +{{%include 04_authz_AuthenticationCookiesandSessions.md%}} +{{}} + + + + +{{}} +### Authorization +{{%include 04_authz_Authorization.md%}} +{{}} + + + + + + +{{}} +### Authorization-Related Web Vulnerabilities +{{%include 04_authz_AuthorizationRelatedWebVulnerabilities.md %}} +{{}} + + + + + + + + + + + + diff --git a/exampleSite/content/checklist/04_authz_AuthenticationCookiesandSessions.md b/exampleSite/content/checklist/04_authz_AuthenticationCookiesandSessions.md new file mode 100644 index 0000000..38c07b6 --- /dev/null +++ b/exampleSite/content/checklist/04_authz_AuthenticationCookiesandSessions.md @@ -0,0 +1,104 @@ +--- +hidden: true +--- +**Cookies can be decorated with a special keyword, `HttpOnly`. If this keyword is set, the browser will not allow JavaScript to access the cookie. Even if the application has a cross-site scripting vulnerability, this keyword makes it much harder for an attacker to steal the session cookie.** + +{{}} +* (handled) The `HttpOnly` keyword is set for all our authentication cookies. +* (no) Our application does not make use of this defense-in-depth mechanism. +{{}} + +{{}} +{{%notice warning%}} +**Warning — possible medium-risk issue**\ +\ +Setting the `HttpOnly` attribute is a very simple defense-in-depth mechanism. We highly recommended making use of it. +\ +**If there are specific reasons why this is not possible in your case please explain below** +{{}} +{{%/notice%}} +{{}} + + +**Session IDs can be constructed in many ways. Select the methods used in your application:** +{{}} +* (framework) The web application framework we use has a built-in session ID mechanism. +* (randomalphanum) Our session IDs are randomly generated strings or numbers. +* (signedcookie) We store a signed token as a cookie to indicate that the user is successfully logged in. +* (other) We use some other mechanism. +{{}} + +{{}} +**Describe the mechanism you're using** +{{}} +{{}} + +{{}} +**What's the name of the framework that generates your session IDs** +{{}} +{{}} + +{{}} +**Do sessions automatically time out after a specified period of inactivity** +{{}} +* (yes) Yes +* (no) No +{{}} + +{{}} +**How long is the session timeout?** +{{}} +{{}} + +{{}} + +{{}} +{{%notice warning%}} +**Warning — possible medium-risk issue**\ +\ +If you don't specify a session timeout, an attacker who has stolen a session ID once will have a permanent back door to the application. Be sure to implement a timeout — even if it's fairly long, it's still better than no timeout at all). +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} + + + +{{}} +**Does the application use a secure [cryptographic pseudo random number generator](https://en.wikipedia.org/wiki/Pseudorandom_number_generator#Cryptographically_secure_pseudorandom_number_generators) (PRNG) to generate session IDs? The PRNG should not allow the state of the generator to be recalculated from its output, and the entropy of the session ID should be sufficient to make brute-forcing infeasible.** +{{}} +* (yes) Yes, we use a PRNG that meets these criteria +* (no) No, we don't use a PRNG, or our PRNG doesn't meet these criteria. +{{}} + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +If you're not using a cryptographic PRNG, an attacker can recalculate the state of the generator in order to guess subsequent session IDs and steal those users' sessions. Many programming languages already have a secure PRNG built in (e.g., Java has `java.security.SecureRandom`; C# has `System.Security.Cryptography.RNGCryptoServiceProvider`; Python has `os.urandom`), and in most cases it is as easy to use as a less secure option.\ +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} + +{{}} + + +**Does your application offer a "log out" button or link that, when clicked, not only terminates the session (deletes cookies from the client) but also invalidates the entire session ID?** +{{}} +* (yes) Yes +* (no) No +{{}} + +{{}} +{{%notice warning%}} +**Warning — possible medium-risk issue**\ +\ +Unless sessions are invalidated on logout, an attacker who has stolen a session ID will have access to the user's data until the session expires. Make sure all logout actions invalidate the session ID.\ +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} \ No newline at end of file diff --git a/exampleSite/content/checklist/04_authz_Authorization.md b/exampleSite/content/checklist/04_authz_Authorization.md new file mode 100644 index 0000000..13df6ae --- /dev/null +++ b/exampleSite/content/checklist/04_authz_Authorization.md @@ -0,0 +1,44 @@ +--- +hidden: true +--- +In most applications, certain information should only be accessible to certain users. For example, in most applications that require authentication, only the currently logged-in user should be able to change master data (such as the username, the associated email address, or the account password). When an application has data that should not be available to other users or should be restricted to certain roles, authorization must be enforced on the server side. + + +**Horizontal Access Control: Horizontal access control refers to isolation between users of the same role. For example, consider an application that allows users to access their payroll statements. The application must ensure that a user cannot access another user's statements; i.e., if the user's statement for the month of May is found at `statement.html?id=8372&month=5`, it shouldn't be possible to see someone else's pay stub simply by loading `statement.html?id=8373&month=5`.** +{{}} +* (handled) Our application enforces these restrictions on the server side. We have processes in place to make sure nothing slips through the cracks. +* (no) It's possible that we missed checks like this in a few places. +{{}} + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +Applications must have controls in place that help protect all data from unauthorized access. We recommend that you thoroughly audit your code for vulnerabilities resulting from inadequate access control.\ +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} + + + + + +**Vertical Access Control: When an application supports multiple roles, users should not be able to gain privileges or perform unauthorized actions by loading pages or features that should only be available to users in a different role. Throughout your application, have you ensured that users can perform only those actions that are appropriate for their roles?** +{{}} +* (handled) Our application enforces these restrictions on the server side. We have processes in place to make sure nothing slips through the cracks. +* (no) It's possible that we missed checks like this in a few places. +{{}} + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +Applications must have controls in place that protect all functionality from unauthorized access. We recommend that you thoroughly audit your code for vulnerabilities resulting from inadequate access control.\ +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} + diff --git a/exampleSite/content/checklist/04_authz_AuthorizationRelatedWebVulnerabilities.md b/exampleSite/content/checklist/04_authz_AuthorizationRelatedWebVulnerabilities.md new file mode 100644 index 0000000..c0c4512 --- /dev/null +++ b/exampleSite/content/checklist/04_authz_AuthorizationRelatedWebVulnerabilities.md @@ -0,0 +1,123 @@ +--- +hidden: true +--- +#### Cross Site Request Forgery +Applications must protect all state-changing actions against cross-site request forgery (XSRF). In this attack, a malicious user forces the victim to send a request to the application, for example by luring the user to a page under the attacker's control. Because the browser automatically attaches available authentication cookies, the request will appear to be authorized if the user is logged in to the application. + +For example, consider an online banking application that allows users to transfer money to another account. The URL for transfers might look something like this: + +`https://www.example.com/bank-transfer.html?dest_account=123456&amount=99.90&submit=true` + +If an attacker manages to lure the victim to a malicious site, the site could include HTML that causes such a request to be sent: + +`` + +If the user is logged in to the online banking portal, the application will receive that request and check for authentication cookies — which will be present, since the request was sent from the authorized user's browser. + +**Does your application protect all state-changing actions against XSRF?** +{{}} +* (yes) Yes, all state-changing actions are protected. We have a way to ensure that no actions are missed (such as enforcing XSRF-token checks in a central place). +* (no) Some actions might not be protected against XSRF. +{{}} + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +Web applications used to process private or confidential information should protect against XSRF. We recommend that you thoroughly audit your code for XSRF vulnerabilities, and put procedures in place so that future code is also protected.\ +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} + +{{}} +**What strategy do you use to protect against XSRF?** +{{}} +* (token) We protect requests that change the state with tokens that are bound to the user they were generated for, and that expire after a certain amount of time. +* (header) We use a custom fixed header that we add to requests. +* (post) The application does one of the following: verifies the referrer header; requires all state-changing actions to be POST requests; employs another mechanism to protect against XSRF +{{}} +{{}} + +{{}} +{{%notice%}} +**Tip**\ +\ +Various browser plugins (such as Flash and Java) have had security vulnerabilities that allowed an attacker to set arbitrary custom headers on cross-domain requests. We highly recommend the use of tokens instead of headers. +{{%/notice%}} +{{}} + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +Unfortunately, using POST requests does not protect against XSRF. Attackers can perform cross-domain POST requests by submitting a form with the appropriate `action` parameter, via JavaScript. Referrer checks are similarly ineffective because attackers can get around them through open redirects.\ +\ +**If you are using an alternative, effective method to protect against XSRF, describe it:** +{{}} +{{%/notice%}} +{{}} + + + + + + + + +#### Cross-Site Script Inclusion +**Many web applications use AJAX to exchange data in the background, using a syntax that can be automatically interpreted as JavaScript by the user's browser. Unfortunately, this leads to [cross-site script inclusion](http://capec.mitre.org/data/definitions/111.html) (XSSI) vulnerabilities: the JavaScript can be included from a different origin, and any variables set at the other origin can be read.** + +For example, consider a contact management application that transmits the user's contacts in a JSON file (contacts.js): + +`var contacts = {"name": "John Doe", "address": "jdoe@example.com", ... }` + +An attacker can include the following script from their own site, so that when the user visits the attacker's site while logged in to the contact management application, the attacker can read the variable contacts and get access to all of the victim's contact information. + +`` + +**Do either of the following statements describe your application?** +{{}} +* (jsonp) Our application makes use of [JSONP](http://en.wikipedia.org/wiki/JSONP). +* (no) Our application uses another format that sets variables or calls functions with non-public information. +{{}} + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +Web applications that transmit private information must be protected against XSSI, to prevent attackers from stealing the private data.\ +\ +**If you are using an alternative, effective method to protect against XSSI, describe it:** +{{}} +{{%/notice%}} +{{}} + + + + + + +#### Clickjacking +**Depending on the nature of your application and the actions that can be taken in it, you may need to protect against [clickjacking](https://www.owasp.org/index.php/Clickjacking).** + +**If you don't typically need to frame web pages, your application should use the [X-Frame-Options response header](https://developer.mozilla.org/en/the_x-frame-options_response_header) to tell the browser not to render any page that's framed from a different origin:** + +`X-Frame-Options: SAMEORIGIN` + +{{}} +* (handled) Our application employs protections against clickjacking (such as using the `X-Frame-Options` header). +* (no) Our application does not have such protections. +{{}} + +{{}} +{{%notice%}} +**Tip**\ +\ +Clickjacking is difficult to address. But in high-risk applications, clickjacking protection is essential.\ +\ +**Explain why you consider clickjacking protection unnecessary** +{{}} +{{%/notice%}} +{{}} \ No newline at end of file diff --git a/exampleSite/content/checklist/04_authz_OAuth2Login.md b/exampleSite/content/checklist/04_authz_OAuth2Login.md new file mode 100644 index 0000000..850e23e --- /dev/null +++ b/exampleSite/content/checklist/04_authz_OAuth2Login.md @@ -0,0 +1,31 @@ +--- +hidden: true +--- + +**Implementing OAuth2 Login / OpenID Connect from scratch is fairly complex and error-prone, and mistakes can result in security vulnerabilities. Select the option that best describes your implementation:** +{{}} +* (very_secure) Very secure: We're using a standard OAuth2 library, and we update it when security fixes are released. +* (secure) Secure: We implemented OAuth2 on our own, but our employees are experts and we're convinced that it is implemented securely. +* (own_impl) Not sure: We implemented OAuth2 on our own, and it seemed simple at the time. I'm not sure about the security of our implementation +{{}} + + +{{}} +{{%notice%}} +**Tip**\ +\ +If your employees really are OAuth2 experts, you're probably fine. But note that even standard libraries have had vulnerabilities due to the intricacies of the standard. Be sure to ask your penetration testing provider to take a look at the OAuth2 implementation. +{{%/notice%}} +{{}} + + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +Implementing OAuth2 on your own is extremely dangerous. Even the experts on the OAuth2 standards panel concluded that the only way to securely implement it is through a well-known and well-tested library. Some of these libraries are very easy to use (e.g., the [Google Identity Toolkit](https://developers.google.com/identity/toolkit/)), so replacing your custom implementation should be feasible.\ +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} \ No newline at end of file diff --git a/exampleSite/content/checklist/04_authz_UsernamePasswordAuthentication.md b/exampleSite/content/checklist/04_authz_UsernamePasswordAuthentication.md new file mode 100644 index 0000000..74f5679 --- /dev/null +++ b/exampleSite/content/checklist/04_authz_UsernamePasswordAuthentication.md @@ -0,0 +1,142 @@ +--- +hidden: true +--- +**What username/password-based logins does the application use? For example, if there's a separate administrator authentication, mention that.** +{{}} + +**Does your application allow users to change their passwords?** +{{}} +* (yes) Yes +* (no) No +{{}} +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +Allowing users to change their passwords is important. A user might be recovering from a compromise, or might have accidentally typed the password elsewhere. +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} + + +**Does the application enforce minimum password security requirements (e.g., a certain length, character classes, etc.)?** +{{}} +* (yes) Yes +* (no) No +{{}} +{{}} +{{%notice warning%}} +**Warning — possible medium-risk issue**\ +\ +Please help protect users from themselves by enforcing certain minimum password requirements. It's up to you to determine the details of these requirements, but they should account for the sensitivity of the information and should conform to industry standards. +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} + + + + +#### Password Storage +**How does the application store passwords?** +{{}} +* (plaintext) In plain text (unencrypted) +* (reversible) Using reversible encryption (e.g., DES, 3DES, AES, etc.). +* (hashnosalted) Using a secure cryptographic one-way hash function (such as SHA-256) of the password, without the use of a salt +* (hashsalted) Using a secure cryptographic one-way hash function (such as SHA-256) of the salted password +* (keyderivationcypher) Using a dedicated password-based key derivation function, such as bcrypt, PBKDF2 or scrypt +* (none) None of the above +{{}} + +{{}} +**Explain how your application stores passwords:** +{{}} +{{}} + +{{}} +{{%alert danger%}}**Warning — possible critical-risk issue**{{%/alert%}} +{{%notice danger%}} +Passwords should be stored in such a way that the original passwords cannot be easily recovered, even if an attacker manages to get access to the storage location (e.g., through a SQL injection vulnerability). At a minimum, passwords should be secured using a cryptographic one-way hash function and a salt. We strongly recommended using password-based key derivation function like bcrypt PBKDF2 or scrypt instead; they were specifically designed for this use case and make it significantly harder for attackers to crack password hashes.\ +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} + + + + + + + +#### Setting an Initial Password +**How do users get their initial passwords?** +{{}} +* (selfset) Users self-register and set their passwords online directly within the application. +* (linktoset) The initial password or a link to set the initial password is sent to users by email. +* (physical) The initial password is provided in a (physical) letter sent to a verified address. +* (none) None of the above. +{{}} + +{{}} +**Explain how users get their initial passwords:** +{{}} +{{}} + +{{}} +{{%notice%}} +**Tip**\ +\ +If passwords are sent by email, make sure users are required to change their initial passwords when they first log in. +{{%/notice%}} +{{}} + + +**When the user gets their initial password, will their account be prepopulated with any confidential information? For example, in an online payroll portal, a user can typically access previous pay statements even when the account is brand new.** +{{}} +* (yes) Yes, when users log in for the first time, confidential information will already be present. +* (no) No, at the initial login, no confidential information will be available to the user. +{{}} + + + + +#### Account Recovery +**When the user gets their initial password, will their account be prepopulated with any confidential information? For example, in an online payroll portal, a user can typically access previous pay statements even when the account is brand new.** +{{}} +* (questions) The user is asked questions that were set up when the account was created. +* (resetlink) A password reset link is sent via email to the user's registered email address. +* (newpassbymail) A new password is sent via email to the user's registered email address. +* (none) None of the above. +{{}} + +{{}} +**Describe your password recovery mechanism:** +{{}} +{{}} + +{{}} +{{%notice danger%}} +**Warning — possible high-risk issue**\ +\ +Recovery questions alone should not be sufficient for resetting a password. The answers to these questions are often not as secret as they might seem; in particular, friends and family can often easily guess the answers. +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +\ +{{}} +{{%/notice%}} +{{}} + +{{}} +{{%notice warning%}} +**Warning — possible medium-risk issue**\ +\ +Sending passwords by email is rarely a good idea. Email is generally unencrypted, so it should not be used for sensitive information. Instead, we recommend sending a token that can be used to set the actual password. Although an attacker with the token could still reset the password, the user would at least become aware of the reset when they later attempted to log in. +\ +**If you have compensating controls in place or feel that this issue does not constitute a risk in your specific circumstances, please explain below. If you're working to address this issue, include an estimate of when it will be resolved:** +{{}} +{{%/notice%}} +{{}} + diff --git a/exampleSite/content/checklist/05_commonvuln.md b/exampleSite/content/checklist/05_commonvuln.md new file mode 100644 index 0000000..9073924 --- /dev/null +++ b/exampleSite/content/checklist/05_commonvuln.md @@ -0,0 +1,81 @@ +--- +hidden: true +--- + +**Certain features can result in security issues, if used incorrectly. To help us identify potential issues, select the statements that describe your application:** +{{}} +* (db) The application uses a database back end, or any other persistence back end that can be queried with SQL or a related language (e.g., GQL, FQL, SOQL, etc.). +* (plugin) The application requires a plugin, such as Java, Flash, Silverlight, etc. +* (upload) The application has a file upload feature. +* (3rdpartycontent) The application loads active content, such as scripts, applets, or style sheets, from third-party servers (i.e., any server that is not under your direct control). +* (xml) The application processes or manipulates user-provided XML. +* (crypto) The application uses cryptography to encrypt data or protect its integrity. +{{}} + +{{}} +{{%notice warning%}} +**Warning — possible medium-risk issue**\ +\ +Loading content from other sites is dangerous under certain circumstances; security issues in the other sites might also affect the security of your application. Scripts, for example, have full access to the DOM of the site on which they're included — so if one of the servers that hosts your third-party JavaScript gets compromised, the attacker also gains access to all of your users' data, simply by injecting a bit of code.\ +\ +Unless you trust the third party completely (not only to not do something malicious, but also to be secure enough to adequately protect their infrastructure against attackers), it's best not to load scripts or style sheets (e.g., via ` + + +
+ + +
+{{end}} \ No newline at end of file diff --git a/layouts/partials/_mdinclude.html b/layouts/partials/_mdinclude.html index 820a5e3..812b8c9 100644 --- a/layouts/partials/_mdinclude.html +++ b/layouts/partials/_mdinclude.html @@ -1,9 +1,12 @@ -{{- template "extrapage" dict "name" .name "page" .context "tip" .tip -}} -{{- define "extrapage" -}} - {{ $header := print .name "." .page.Lang }} - {{ range where .page.Site.Pages "File.BaseFileName" $header }} +{{- template "pageBlock" dict "name" .name "page" .context -}} +{{- template "siteBlock" dict "name" .name "page" .context "tip" .tip -}} + +{{- define "siteBlock" -}} + {{ $path := printf "_layout/%s/_index.%s.md" .name .page.Lang}} + {{ range where .page.Site.Pages "File.BaseFileName" $path }} {{ .Content }} {{else}} + {{ $path = printf "_layout/%s/_index.md" .name }} {{ if .page.Site.GetPage "page" (print .name ".md") }} {{(.page.Site.GetPage "page" (print .name ".md")).Content}} {{else}} @@ -11,3 +14,10 @@ {{end}} {{end}} {{- end -}} + +{{- define "pageBlock" -}} +{{ $path := printf "%s__%s.md" .page.Dir .name}} + {{ with .page.Site.GetPage $path }} + {{ .Content }} + {{end}} +{{- end -}} diff --git a/layouts/partials/body-article-content.html b/layouts/partials/body-article-content.html index 0eedee2..f4d9698 100644 --- a/layouts/partials/body-article-content.html +++ b/layouts/partials/body-article-content.html @@ -20,6 +20,7 @@ {{ $isSubPage := .Params.subpage }} {{ $subpages := (where (where (where .Sections.ByWeight "Params.subpage" true) "Params.hidden" "ne" true ) "Kind" "section")}} {{ $pages := (where (where .CurrentSection.Pages.ByWeight "Kind" "page") "Params.hidden" "ne" true ) }} + {{if $isSubPage }}

{{.Parent.Title}}{{$pagetitle}}

@@ -40,7 +41,7 @@ {{ if gt (len $elements) 0}}