diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 9405730420f..902c74186fb 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -1.64.0 +1.65.0 diff --git a/app/assets/javascripts/badges/components/badge_settings.vue b/app/assets/javascripts/badges/components/badge_settings.vue index 75a522efe7e..531f84ad272 100644 --- a/app/assets/javascripts/badges/components/badge_settings.vue +++ b/app/assets/javascripts/badges/components/badge_settings.vue @@ -2,7 +2,7 @@ import { mapState, mapActions } from 'vuex'; import createFlash from '~/flash'; import { s__ } from '~/locale'; -import GlModal from '~/vue_shared/components/gl_modal.vue'; +import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue'; import Badge from './badge.vue'; import BadgeForm from './badge_form.vue'; import BadgeList from './badge_list.vue'; @@ -13,7 +13,7 @@ export default { Badge, BadgeForm, BadgeList, - GlModal, + GlModal: DeprecatedModal2, }, computed: { ...mapState(['badgeInModal', 'isEditing']), diff --git a/app/assets/javascripts/blob/template_selector.js b/app/assets/javascripts/blob/template_selector.js index 9e69c7d7164..02216e4e93d 100644 --- a/app/assets/javascripts/blob/template_selector.js +++ b/app/assets/javascripts/blob/template_selector.js @@ -1,6 +1,7 @@ /* eslint-disable class-methods-use-this */ import $ from 'jquery'; +import '~/gl_dropdown'; export default class TemplateSelector { constructor({ dropdown, data, pattern, wrapper, editor, $input } = {}) { diff --git a/app/assets/javascripts/create_item_dropdown.js b/app/assets/javascripts/create_item_dropdown.js index fa0f04c7d82..95b890b04c1 100644 --- a/app/assets/javascripts/create_item_dropdown.js +++ b/app/assets/javascripts/create_item_dropdown.js @@ -1,4 +1,5 @@ import _ from 'underscore'; +import '~/gl_dropdown'; export default class CreateItemDropdown { /** diff --git a/app/assets/javascripts/environments/components/stop_environment_modal.vue b/app/assets/javascripts/environments/components/stop_environment_modal.vue index 2cc3412e075..1ea4e30a7c1 100644 --- a/app/assets/javascripts/environments/components/stop_environment_modal.vue +++ b/app/assets/javascripts/environments/components/stop_environment_modal.vue @@ -1,7 +1,7 @@ + + diff --git a/app/assets/javascripts/vue_shared/components/gl_modal.vue b/app/assets/javascripts/vue_shared/components/gl_modal.vue index 438851e5ac7..4b91d4c00e3 100644 --- a/app/assets/javascripts/vue_shared/components/gl_modal.vue +++ b/app/assets/javascripts/vue_shared/components/gl_modal.vue @@ -1,117 +1,6 @@ - - diff --git a/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue b/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue index 7f0345c7ec0..478e44d104c 100644 --- a/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue +++ b/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue @@ -52,7 +52,7 @@ export default { this.$emit('projectClicked', project); }, isSelected(project) { - return Boolean(_.findWhere(this.selectedProjects, { id: project.id })); + return Boolean(_.find(this.selectedProjects, { id: project.id })); }, onInput: _.debounce(function debouncedOnInput() { this.$emit('searched', this.searchQuery); diff --git a/changelogs/unreleased/add-dast-full-scan-domain-validation.yml b/changelogs/unreleased/add-dast-full-scan-domain-validation.yml new file mode 100644 index 00000000000..a643a5e33a6 --- /dev/null +++ b/changelogs/unreleased/add-dast-full-scan-domain-validation.yml @@ -0,0 +1,5 @@ +--- +title: Add DAST full scan domain validation +merge_request: 16680 +author: +type: added diff --git a/changelogs/unreleased/gitaly-version-v1.65.0.yml b/changelogs/unreleased/gitaly-version-v1.65.0.yml new file mode 100644 index 00000000000..ca1106f8874 --- /dev/null +++ b/changelogs/unreleased/gitaly-version-v1.65.0.yml @@ -0,0 +1,5 @@ +--- +title: Upgrade to Gitaly v1.65.0 +merge_request: 17135 +author: +type: changed diff --git a/doc/development/fe_guide/components.md b/doc/development/fe_guide/components.md index b96d92e2d88..f8765f9e202 100644 --- a/doc/development/fe_guide/components.md +++ b/doc/development/fe_guide/components.md @@ -3,7 +3,6 @@ ## Contents - [Dropdowns](#dropdowns) -- [Modals](#modals) ## Dropdowns @@ -39,25 +38,3 @@ See also the [corresponding UX guide](https://design.gitlab.com/#/components/dro ``` [bootstrap-dropdowns]: https://getbootstrap.com/docs/3.3/javascript/#dropdowns - -## Modals - -See also the [corresponding UX guide](https://design.gitlab.com/#/components/modals). - -We have a reusable Vue component for modals: [vue_shared/components/gl_modal.vue](https://gitlab.com/gitlab-org/gitlab/blob/master/app/assets/javascripts/vue_shared/components/gl_modal.vue) - -Here is an example of how to use it: - -```html - - {{ s__('ModalExample|You’re about to let the dogs out.') }} - -``` - -![example modal](img/gl-modal.png) diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md index afeef2a04ba..e90f219337b 100644 --- a/doc/user/application_security/dast/index.md +++ b/doc/user/application_security/dast/index.md @@ -84,7 +84,7 @@ There are two ways to define the URL to be scanned by DAST: - Set the `DAST_WEBSITE` [variable](../../../ci/yaml/README.md#variables). - Add it in an `environment_url.txt` file at the root of your project. -If both values are set, the `DAST_WEBSITE` value will take precedence. +If both values are set, the `DAST_WEBSITE` value will take precedence. The included template will create a `dast` job in your CI/CD pipeline and scan your project's source code for possible vulnerabilities. @@ -132,6 +132,115 @@ variables: DAST_FULL_SCAN_ENABLED: "true" ``` +#### Domain validation + +The DAST job can be run anywhere, which means you can accidentally hit live web servers +and potentially damage them. You could even take down your production environment. +For that reason, you should use domain validation. + +Domain validation is not required by default. It can be required by setting the [environment variable](#available-variables) `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` to true. + +```yaml +include: + template: DAST.gitlab-ci.yml + +variables: + DAST_FULL_SCAN_ENABLED: "true" + DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED: "true" +``` + +Since ZAP full scan actively attacks the target application, DAST sends a ping to the target (normally defined in `DAST_WEBSITE` or `environment_url.txt`) beforehand. + +If `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` is false or unset, the scan will _proceed_ unless the response to the ping +includes a `Gitlab-DAST-Permission` header with a value of `deny`. + +If `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` is true, the scan will _exit_ unless the response to the ping +includes a `Gitlab-DAST-Permission` header with a value of `allow`. + +Here are some examples of adding the `Gitlab-DAST-Permission` header to a response in Rails, Django, and Node (with Express). + +##### Ruby on Rails + +Here's how you would add a [custom header in Ruby on Rails](https://guides.rubyonrails.org/action_controller_overview.html#setting-custom-headers): + +```ruby +class DastWebsiteTargetController < ActionController::Base + def dast_website_target + response.headers['Gitlab-DAST-Permission'] = 'allow' + + head :ok + end +end +``` + +##### Django + +Here's how you would add a [custom header in Django](https://docs.djangoproject.com/en/2.2/ref/request-response/#setting-header-fields): + +```python +class DastWebsiteTargetView(View): + def head(self, *args, **kwargs): + response = HttpResponse() + response['Gitlab-Dast-Permission'] = 'allow' + + return response +``` + +##### Node (with Express) + +Here's how you would add a [custom header in Node (with Express)](http://expressjs.com/en/5x/api.html#res.append): + +```javascript +app.get('/dast-website-target', function(req, res) { + res.append('Gitlab-DAST-Permission', 'allow') + res.send('Respond to DAST ping') +}) +``` + +##### Domain validation header via a proxy + +It's also possible to add the `Gitlab-DAST-Permission` header via a proxy. + +###### NGINX + +The following config allows NGINX to act as a reverse proxy and add the `Gitlab-DAST-Permission` [header](http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header): + +``` +# default.conf +server { + listen 80; + server_name localhost; + + location / { + proxy_pass http://test-application; + add_header Gitlab-DAST-Permission allow; + } +} +``` + +###### Apache + +Apache can also be used as a [reverse proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html) +to add the Gitlab-DAST-Permission [header](https://httpd.apache.org/docs/current/mod/mod_headers.html). + +To do so, add the following lines to `httpd.conf`: + +``` +# httpd.conf +LoadModule proxy_module modules/mod_proxy.so +LoadModule proxy_connect_module modules/mod_proxy_connect.so +LoadModule proxy_http_module modules/mod_proxy_http.so + + + ProxyPass "/" "http://test-application.com/" + ProxyPassReverse "/" "http://test-application.com/" + Header set Gitlab-DAST-Permission "allow" + +``` + +[This snippet](https://gitlab.com/gitlab-org/security-products/dast/snippets/1894732) contains a complete `httpd.conf` file +configured to act as a remote proxy and add the `Gitlab-DAST-Permission` header. + ### Customizing the DAST settings The DAST settings can be changed through environment variables by using the @@ -194,6 +303,7 @@ variable value. | `DAST_AUTH_EXCLUDE_URLS` | no | The URLs to skip during the authenticated scan; comma-separated, no spaces in between. | | `DAST_TARGET_AVAILABILITY_TIMEOUT` | no | Time limit in seconds to wait for target availability. Scan is attempted nevertheless if it runs out. Integer. Defaults to `60`. | | `DAST_FULL_SCAN_ENABLED` | no | Switches the tool to execute [ZAP Full Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Full-Scan) instead of [ZAP Baseline Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Baseline-Scan). Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. | +| `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` | no | Requires [domain validation](#domain-validation) when running DAST full scans. Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. | ## Security Dashboard diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 8aec921f9af..9be6cbca00c 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -10627,6 +10627,9 @@ msgstr "" msgid "One or more of your dependency files are not supported, and the dependency list may be incomplete. Below is a list of supported file types." msgstr "" +msgid "Only 'Reporter' roles and above on tiers Premium / Silver and above can see Cycle Analytics." +msgstr "" + msgid "Only Project Members" msgstr "" @@ -17984,6 +17987,9 @@ msgstr "" msgid "You don't have any recent searches" msgstr "" +msgid "You don’t have access to Cycle Analytics for this group" +msgstr "" + msgid "You don’t have access to Productivity Analytics in this group" msgstr "" diff --git a/spec/javascripts/vue_shared/components/gl_modal_spec.js b/spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js similarity index 95% rename from spec/javascripts/vue_shared/components/gl_modal_spec.js rename to spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js index 19af8b5d2f7..64fb984d9fc 100644 --- a/spec/javascripts/vue_shared/components/gl_modal_spec.js +++ b/spec/javascripts/vue_shared/components/deprecated_modal_2_spec.js @@ -1,11 +1,11 @@ import $ from 'jquery'; import Vue from 'vue'; -import GlModal from '~/vue_shared/components/gl_modal.vue'; +import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue'; import mountComponent from 'spec/helpers/vue_mount_component_helper'; -const modalComponent = Vue.extend(GlModal); +const modalComponent = Vue.extend(DeprecatedModal2); -describe('GlModal', () => { +describe('DeprecatedModal2', () => { let vm; afterEach(() => { @@ -153,17 +153,17 @@ describe('GlModal', () => { let template; if (slotName) { template = ` - + - + `; } else { - template = `${slotContent}`; + template = `${slotContent}`; } return Vue.extend({ components: { - GlModal, + DeprecatedModal2, }, template, });