Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
bb4eeef95a
commit
1dace033aa
|
|
@ -1,6 +1,4 @@
|
|||
---
|
||||
GraphQL/ResolverMethodLength:
|
||||
Exclude:
|
||||
- 'app/graphql/types/ci/detailed_status_type.rb'
|
||||
- 'app/graphql/types/ci/runner_type.rb'
|
||||
- 'app/graphql/types/ci/stage_type.rb'
|
||||
|
|
|
|||
|
|
@ -129,7 +129,6 @@ Layout/SpaceInsideParens:
|
|||
- 'spec/lib/gitlab/health_checks/simple_check_shared.rb'
|
||||
- 'spec/lib/gitlab/highlight_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/attributes_permitter_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/file_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/project/export_task_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/project/tree_saver_spec.rb'
|
||||
|
|
|
|||
|
|
@ -65,16 +65,6 @@ Lint/AmbiguousOperatorPrecedence:
|
|||
- 'lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb'
|
||||
- 'lib/gitlab/database/postgres_hll/buckets.rb'
|
||||
- 'lib/gitlab/database/query_analyzers/prevent_cross_database_modification.rb'
|
||||
- 'lib/gitlab/i18n/po_linter.rb'
|
||||
- 'lib/gitlab/import_export/project/relation_factory.rb'
|
||||
- 'lib/gitlab/memory/instrumentation.rb'
|
||||
- 'lib/gitlab/metrics/prometheus.rb'
|
||||
- 'lib/gitlab/middleware/rails_queue_duration.rb'
|
||||
- 'lib/gitlab/pagination/gitaly_keyset_pager.rb'
|
||||
- 'lib/gitlab/quick_actions/issuable_actions.rb'
|
||||
- 'lib/gitlab/relative_positioning.rb'
|
||||
- 'lib/gitlab/template_parser/parser.rb'
|
||||
- 'lib/gitlab/tree_summary.rb'
|
||||
- 'lib/omni_auth/strategies/bitbucket.rb'
|
||||
- 'qa/qa/ee/page/project/secure/pipeline_security.rb'
|
||||
- 'qa/qa/resource/api_fabricator.rb'
|
||||
|
|
|
|||
|
|
@ -1790,7 +1790,6 @@ RSpec/ContextWording:
|
|||
- 'spec/lib/gitlab/import_export/command_line_util_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/decompressed_archive_size_validator_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/file_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/group/object_builder_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/group/relation_factory_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/group/tree_restorer_spec.rb'
|
||||
|
|
|
|||
|
|
@ -3507,7 +3507,6 @@ RSpec/FeatureCategory:
|
|||
- 'spec/lib/gitlab/import_export/design_repo_restorer_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/design_repo_saver_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/duration_measuring_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/file_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/group/object_builder_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/group/relation_factory_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/group/tree_saver_spec.rb'
|
||||
|
|
|
|||
|
|
@ -2200,7 +2200,6 @@ RSpec/NamedSubject:
|
|||
- 'spec/lib/gitlab/import_export/decompressed_archive_size_validator_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/duration_measuring_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/file_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/group/relation_tree_restorer_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/import_failure_service_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/importer_spec.rb'
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ Style/NumericLiteralPrefix:
|
|||
- 'spec/lib/gitlab/grape_logging/loggers/cloudflare_logger_spec.rb'
|
||||
- 'spec/lib/gitlab/grape_logging/loggers/queue_duration_logger_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/command_line_util_spec.rb'
|
||||
- 'spec/lib/gitlab/import_export/file_importer_spec.rb'
|
||||
- 'spec/lib/gitlab/jwt_authenticatable_spec.rb'
|
||||
- 'spec/lib/gitlab/puma_logging/json_formatter_spec.rb'
|
||||
- 'spec/lib/gitlab/relative_positioning/range_spec.rb'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { GlEmptyState, GlLink, GlSprintf, GlAlert } from '@gitlab/ui';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import { PROMO_URL } from '~/lib/utils/url_utility';
|
||||
import { I18N_CLUSTERS_EMPTY_STATE } from '../constants';
|
||||
|
||||
export default {
|
||||
|
|
@ -15,8 +16,7 @@ export default {
|
|||
clustersHelpUrl: helpPagePath('user/infrastructure/clusters/index', {
|
||||
anchor: 'certificate-based-kubernetes-integration-deprecated',
|
||||
}),
|
||||
blogPostUrl:
|
||||
'https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/',
|
||||
blogPostUrl: `${PROMO_URL}/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/`,
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
<script>
|
||||
import { GlDrawer, GlButton } from '@gitlab/ui';
|
||||
import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
|
||||
import { getContentWrapperHeight } from '~/lib/utils/dom_utils';
|
||||
import { __ } from '~/locale';
|
||||
import ListSelector from '~/vue_shared/components/list_selector/index.vue';
|
||||
|
||||
export default {
|
||||
DRAWER_Z_INDEX,
|
||||
components: {
|
||||
GlDrawer,
|
||||
GlButton,
|
||||
ListSelector,
|
||||
},
|
||||
props: {
|
||||
isOpen: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
exclusions: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
getDrawerHeaderHeight() {
|
||||
return getContentWrapperHeight();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleSelectExclusion(exclusion) {
|
||||
this.exclusions.push({ ...exclusion });
|
||||
},
|
||||
handleRemoveExclusion(id) {
|
||||
const exclusionIndex = this.exclusions.findIndex((exclusion) => exclusion.id === id);
|
||||
this.exclusions.splice(exclusionIndex, 1);
|
||||
},
|
||||
async handleAddExclusions() {
|
||||
this.isLoading = true;
|
||||
this.$emit('add', this.exclusions);
|
||||
this.exclusions = [];
|
||||
this.isLoading = false;
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
addExclusions: __('Add exclusions'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<gl-drawer
|
||||
:header-height="getDrawerHeaderHeight"
|
||||
:z-index="$options.DRAWER_Z_INDEX"
|
||||
:open="isOpen"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<template #title>
|
||||
<h2 class="gl-font-size-h2 gl-mt-0" data-testid="title">{{ $options.i18n.addExclusions }}</h2>
|
||||
</template>
|
||||
|
||||
<template #default>
|
||||
<list-selector
|
||||
type="projects"
|
||||
class="gl-m-5 gl-p-0!"
|
||||
:selected-items="exclusions"
|
||||
@select="handleSelectExclusion"
|
||||
@delete="handleRemoveExclusion"
|
||||
/>
|
||||
|
||||
<gl-button
|
||||
class="gl-ml-5"
|
||||
variant="confirm"
|
||||
:loading="isLoading"
|
||||
data-testid="add-button"
|
||||
@click="handleAddExclusions"
|
||||
>
|
||||
{{ $options.i18n.addExclusions }}
|
||||
</gl-button>
|
||||
</template>
|
||||
</gl-drawer>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
<script>
|
||||
import { GlButton, GlEmptyState } from '@gitlab/ui';
|
||||
import { sortBy } from 'lodash';
|
||||
import { s__, __ } from '~/locale';
|
||||
import globalToast from '~/vue_shared/plugins/global_toast';
|
||||
import ExclusionsTabs from './exclusions_tabs.vue';
|
||||
import ExclusionsListItem from './exclusions_list_item.vue';
|
||||
import AddExclusionsDrawer from './add_exclusions_drawer.vue';
|
||||
import ConfirmRemovalModal from './remove_exclusion_confirmation_modal.vue';
|
||||
|
||||
export default {
|
||||
name: 'ExclusionsList',
|
||||
components: {
|
||||
GlButton,
|
||||
GlEmptyState,
|
||||
ExclusionsTabs,
|
||||
ExclusionsListItem,
|
||||
AddExclusionsDrawer,
|
||||
ConfirmRemovalModal,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isDrawerOpen: false,
|
||||
isConfirmRemovalModalOpen: false,
|
||||
exclusions: [],
|
||||
exclusionToRemove: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
formattedExclusions() {
|
||||
return sortBy(
|
||||
this.exclusions.map((exclusion) => ({
|
||||
...exclusion,
|
||||
icon: exclusion.type,
|
||||
})),
|
||||
'name',
|
||||
);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.loadExclusions();
|
||||
},
|
||||
methods: {
|
||||
loadExclusions() {
|
||||
// TODO: add backend call for GET/Query (follow-up)
|
||||
this.exclusions = [];
|
||||
},
|
||||
handleAddExclusions(exclusions) {
|
||||
// TODO: add backend call for POST/Mutate (follow-up)
|
||||
this.exclusions.push(...exclusions);
|
||||
this.isDrawerOpen = false;
|
||||
},
|
||||
showRemoveModal(exclusion) {
|
||||
this.exclusionToRemove = exclusion;
|
||||
this.isConfirmRemovalModalOpen = true;
|
||||
},
|
||||
hideRemoveModal() {
|
||||
this.isConfirmRemovalModalOpen = false;
|
||||
},
|
||||
confirmRemoveExclusion() {
|
||||
const { exclusionToRemove } = this;
|
||||
// TODO: add backend call for DELETE/Mutate (follow-up)
|
||||
this.exclusions = this.exclusions.filter((item) => item.id !== exclusionToRemove.id);
|
||||
|
||||
globalToast(this.$options.i18n.exclusionRemoved, {
|
||||
action: {
|
||||
text: __('Undo'),
|
||||
onClick: (_, toast) => {
|
||||
this.handleAddExclusions([exclusionToRemove]);
|
||||
toast.hide();
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
toggleDrawer() {
|
||||
this.isDrawerOpen = !this.isDrawerOpen;
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
exclusionRemoved: s__('Integrations|Project exclusion removed'),
|
||||
emptyText: s__('Integrations|There are no exclusions'),
|
||||
addExclusions: s__('Integrations|Add exclusions'),
|
||||
helpText: s__('Integrations|Projects in this list no longer require commits to be signed.'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<exclusions-tabs />
|
||||
|
||||
<div
|
||||
class="gl-display-flex gl-justify-content-space-between gl-bg-gray-10 gl-p-4 gl-py-5 gl-border-b gl-align-items-center"
|
||||
>
|
||||
<span>{{ $options.i18n.helpText }}</span>
|
||||
<gl-button variant="confirm" @click="isDrawerOpen = true">{{
|
||||
$options.i18n.addExclusions
|
||||
}}</gl-button>
|
||||
</div>
|
||||
|
||||
<gl-empty-state v-if="!exclusions.length" :title="$options.i18n.emptyText" />
|
||||
|
||||
<exclusions-list-item
|
||||
v-for="(exclusion, index) in formattedExclusions"
|
||||
v-else
|
||||
:key="index"
|
||||
:exclusion="exclusion"
|
||||
@remove="() => showRemoveModal(exclusion)"
|
||||
/>
|
||||
|
||||
<add-exclusions-drawer
|
||||
:is-open="isDrawerOpen"
|
||||
@close="isDrawerOpen = false"
|
||||
@add="handleAddExclusions"
|
||||
/>
|
||||
|
||||
<confirm-removal-modal
|
||||
v-if="exclusionToRemove && isConfirmRemovalModalOpen"
|
||||
:visible="isConfirmRemovalModalOpen"
|
||||
:name="exclusionToRemove.name"
|
||||
:type="exclusionToRemove.type"
|
||||
@primary="confirmRemoveExclusion"
|
||||
@hide="hideRemoveModal"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<script>
|
||||
import { GlButton, GlIcon, GlAvatar } from '@gitlab/ui';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
name: 'ExclusionsListItem',
|
||||
components: {
|
||||
GlButton,
|
||||
GlAvatar,
|
||||
GlIcon,
|
||||
},
|
||||
props: {
|
||||
exclusion: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
i18n: { remove: __('Remove') },
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="gl-display-flex gl-justify-content-space-between gl-p-4 gl-py-3 gl-pl-7 gl-border-b gl-align-items-center gl-gap-3"
|
||||
>
|
||||
<gl-icon :name="exclusion.icon" class="gl-text-secondary" />
|
||||
<gl-avatar
|
||||
:alt="exclusion.name"
|
||||
:entity-name="exclusion.name"
|
||||
:size="32"
|
||||
:src="exclusion.avatarUrl"
|
||||
shape="rect"
|
||||
fallback-on-error
|
||||
/>
|
||||
<span class="gl-display-flex gl-flex-direction-column gl-flex-grow-1">
|
||||
<span class="gl-font-weight-bold">{{ exclusion.name }}</span>
|
||||
</span>
|
||||
|
||||
<gl-button
|
||||
icon="remove"
|
||||
:aria-label="$options.i18n.remove"
|
||||
category="tertiary"
|
||||
@click="() => $emit('remove')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<script>
|
||||
import { GlNavItem, GlTabs, GlTab } from '@gitlab/ui';
|
||||
import { s__ } from '~/locale';
|
||||
import { settingsTabTitle } from '~/integrations/constants';
|
||||
|
||||
export default {
|
||||
name: 'ExclusionsTabs',
|
||||
components: {
|
||||
GlNavItem,
|
||||
GlTabs,
|
||||
GlTab,
|
||||
},
|
||||
inject: {
|
||||
editPath: {
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
settingsTabTitle,
|
||||
projectsTabTitle: s__('Integrations|Exclusions'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<gl-tabs content-class="gl-p-0">
|
||||
<template #tabs-start>
|
||||
<gl-nav-item role="presentation" link-classes="gl-tab-nav-item" :href="editPath">{{
|
||||
$options.i18n.settingsTabTitle
|
||||
}}</gl-nav-item>
|
||||
</template>
|
||||
|
||||
<gl-tab active>
|
||||
<template #title>
|
||||
{{ $options.i18n.projectsTabTitle }}
|
||||
</template>
|
||||
</gl-tab>
|
||||
</gl-tabs>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<script>
|
||||
import { GlModal, GlSprintf } from '@gitlab/ui';
|
||||
import { sprintf, s__, __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
name: 'RemoveExclusionConfirmationModal',
|
||||
components: {
|
||||
GlModal,
|
||||
GlSprintf,
|
||||
},
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
modalTitle() {
|
||||
return sprintf(this.$options.i18n.title, { type: this.type });
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
body: s__(
|
||||
"Integrations|You're removing an exclusion for %{name}. Are you sure you want to continue?",
|
||||
),
|
||||
title: s__('Integrations|Confirm %{type} exclusion removal'),
|
||||
},
|
||||
modalOptions: {
|
||||
actionPrimary: {
|
||||
text: s__('Integrations|Remove exclusion'),
|
||||
attributes: { variant: 'danger' },
|
||||
},
|
||||
actionSecondary: {
|
||||
text: __('Cancel'),
|
||||
attributes: { category: 'secondary' },
|
||||
},
|
||||
modalId: 'confirm-remove-exclusion',
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<gl-modal v-bind="$options.modalOptions" :title="modalTitle" :visible="visible" v-on="$listeners">
|
||||
<gl-sprintf :message="$options.i18n.body">
|
||||
<template #name>
|
||||
<strong>{{ name }}</strong>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</gl-modal>
|
||||
</template>
|
||||
|
|
@ -1,3 +1,33 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import initIntegrationOverrides from '~/integrations/overrides';
|
||||
import ExclusionsList from '~/integrations/beyond_identity/components/exclusions_list.vue';
|
||||
|
||||
const initBeyondIdentityExclusions = () => {
|
||||
const el = document.querySelector('.js-vue-beyond-identity-exclusions');
|
||||
|
||||
if (!el) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { editPath } = el.dataset;
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
|
||||
apolloProvider: new VueApollo({
|
||||
defaultClient: createDefaultClient(),
|
||||
}),
|
||||
provide: {
|
||||
editPath,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement(ExclusionsList);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
initBeyondIdentityExclusions();
|
||||
|
||||
initIntegrationOverrides();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import {
|
|||
validateAdditionalProperties,
|
||||
} from './utils';
|
||||
|
||||
const elementsWithBinding = new WeakMap();
|
||||
|
||||
const InternalEvents = {
|
||||
/**
|
||||
*
|
||||
|
|
@ -52,23 +54,30 @@ const InternalEvents = {
|
|||
/**
|
||||
* Attaches event handlers for data-attributes powered events.
|
||||
*
|
||||
* @param {HTMLElement} parent - element containing data-attributes
|
||||
* @returns {Object} handler - object containing name of the event and its corresponding function
|
||||
* @param {HTMLElement} parent - element containing data-attributes to which the event listener
|
||||
* will be attached.
|
||||
* @returns {Function|null} A dispose function that can be called to remove the event listener and
|
||||
* unmark the element, or null if no event handler was attached.
|
||||
*/
|
||||
bindInternalEventDocument(parent = document) {
|
||||
if (!Tracker.enabled() || parent.internalEventsTrackingBound) {
|
||||
return [];
|
||||
if (!Tracker.enabled() || elementsWithBinding.has(parent)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
parent.internalEventsTrackingBound = true;
|
||||
elementsWithBinding.set(parent, true);
|
||||
|
||||
const handler = {
|
||||
name: 'click',
|
||||
func: (e) => InternalEventHandler(e, this.trackEvent.bind(this)),
|
||||
const eventName = 'click';
|
||||
const eventFunc = (e) => InternalEventHandler(e, this.trackEvent.bind(this));
|
||||
|
||||
parent.addEventListener(eventName, eventFunc);
|
||||
|
||||
const dispose = () => {
|
||||
elementsWithBinding.delete(parent);
|
||||
|
||||
parent.removeEventListener(eventName, eventFunc);
|
||||
};
|
||||
parent.addEventListener(handler.name, handler.func);
|
||||
return handler;
|
||||
|
||||
return dispose;
|
||||
},
|
||||
/**
|
||||
* Attaches internal event handlers for load events.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { GlAlert, GlLink } from '@gitlab/ui';
|
||||
import { s__, sprintf } from '~/locale';
|
||||
import { PROMO_URL } from '~/lib/utils/url_utility';
|
||||
|
||||
export default {
|
||||
name: 'IncubationAlert',
|
||||
|
|
@ -41,6 +42,7 @@ export default {
|
|||
learnMoreLabel: s__('Incubation|Learn more about incubating features'),
|
||||
feedbackLabel: s__('Incubation|Give feedback on this feature'),
|
||||
},
|
||||
learnMoreUrl: `${PROMO_URL}/handbook/engineering/incubation/`,
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
@ -54,7 +56,7 @@ export default {
|
|||
@dismiss="dismissAlert"
|
||||
>
|
||||
{{ $options.i18n.contentLabel }}
|
||||
<gl-link href="https://about.gitlab.com/handbook/engineering/incubation/" target="_blank">{{
|
||||
<gl-link :href="$options.learnMoreUrl" target="_blank">{{
|
||||
$options.i18n.learnMoreLabel
|
||||
}}</gl-link>
|
||||
</gl-alert>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { __ } from '~/locale';
|
|||
import UserItem from './user_item.vue';
|
||||
import GroupItem from './group_item.vue';
|
||||
import DeployKeyItem from './deploy_key_item.vue';
|
||||
import ProjectItem from './project_item.vue';
|
||||
|
||||
export const CONFIG = {
|
||||
users: {
|
||||
|
|
@ -23,4 +24,10 @@ export const CONFIG = {
|
|||
filterKey: 'name',
|
||||
component: DeployKeyItem,
|
||||
},
|
||||
projects: {
|
||||
title: __('Projects'),
|
||||
icon: 'project',
|
||||
filterKey: 'id',
|
||||
component: ProjectItem,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
<script>
|
||||
import { GlCard, GlIcon, GlCollapsibleListbox, GlSearchBoxByType } from '@gitlab/ui';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import { parseBoolean, convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
||||
import { createAlert } from '~/alert';
|
||||
import { __ } from '~/locale';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import groupsAutocompleteQuery from '~/graphql_shared/queries/groups_autocomplete.query.graphql';
|
||||
import Api from '~/api';
|
||||
import { getProjects } from '~/rest_api';
|
||||
import { CONFIG } from './constants';
|
||||
|
||||
const I18N = {
|
||||
|
|
@ -49,6 +50,7 @@ export default {
|
|||
isProjectNamespace: 'true',
|
||||
selected: [],
|
||||
items: [],
|
||||
isLoading: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -60,23 +62,44 @@ export default {
|
|||
? this.$options.i18n.projectGroups
|
||||
: this.$options.i18n.allGroups;
|
||||
},
|
||||
searchPlaceholder() {
|
||||
return sprintf(__('Search to add %{title}'), {
|
||||
title: this.config.title.toLowerCase(),
|
||||
});
|
||||
},
|
||||
emptyPlaceholder() {
|
||||
return sprintf(__('No %{title} have been added.'), {
|
||||
title: this.config.title.toLowerCase(),
|
||||
});
|
||||
},
|
||||
filteredItems() {
|
||||
// Filter out selected items
|
||||
return this.items.filter(
|
||||
(item) => !this.selectedItems.some((selectedItem) => selectedItem.id === item.id),
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async handleSearchInput(search) {
|
||||
async handleSearchInput(search = this.searchValue) {
|
||||
this.$refs.results.open();
|
||||
this.$refs.search.focusInput();
|
||||
|
||||
const searchMethod = {
|
||||
users: this.fetchUsersBySearchTerm,
|
||||
groups: this.fetchGroupsBySearchTerm,
|
||||
deployKeys: this.fetchDeployKeysBySearchTerm,
|
||||
projects: this.fetchProjectsBySearchTerm,
|
||||
};
|
||||
|
||||
try {
|
||||
this.isLoading = true;
|
||||
this.items = await searchMethod[this.type](search);
|
||||
} catch (e) {
|
||||
createAlert({
|
||||
message: this.$options.i18n.apiErrorMessage,
|
||||
});
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
async fetchUsersBySearchTerm(search) {
|
||||
|
|
@ -108,11 +131,23 @@ export default {
|
|||
// TODO - implement API request (follow-up)
|
||||
// https://gitlab.com/gitlab-org/gitlab/-/issues/432494
|
||||
},
|
||||
async fetchProjectsBySearchTerm(search) {
|
||||
const response = await getProjects(search, { membership: false });
|
||||
const projects = response?.data || [];
|
||||
|
||||
return projects.map((project) => ({
|
||||
...this.convertToCamelCase(project),
|
||||
text: project.name,
|
||||
value: project.id,
|
||||
type: 'project',
|
||||
}));
|
||||
},
|
||||
getItemByKey(key) {
|
||||
return this.items.find((item) => item[this.config.filterKey] === key);
|
||||
},
|
||||
handleSelectItem(key) {
|
||||
this.$emit('select', this.getItemByKey(key));
|
||||
this.$refs.results.close();
|
||||
},
|
||||
handleDeleteItem(key) {
|
||||
this.$emit('delete', key);
|
||||
|
|
@ -121,6 +156,9 @@ export default {
|
|||
this.items = [];
|
||||
this.searchValue = '';
|
||||
},
|
||||
convertToCamelCase(data) {
|
||||
return convertObjectPropsToCamelCase(data);
|
||||
},
|
||||
},
|
||||
namespaceOptions: [
|
||||
{ text: I18N.projectGroups, value: 'true' },
|
||||
|
|
@ -143,24 +181,25 @@ export default {
|
|||
<div class="gl-display-flex gl-gap-3" :class="{ 'gl-mb-4': selectedItems.length }">
|
||||
<gl-collapsible-listbox
|
||||
ref="results"
|
||||
v-model="selected"
|
||||
class="list-selector gl-display-block gl-flex-grow-1"
|
||||
:items="items"
|
||||
multiple
|
||||
@shown="$refs.search.focusInput()"
|
||||
:items="filteredItems"
|
||||
@select="handleSelectItem"
|
||||
@shown="handleSearchInput"
|
||||
>
|
||||
<template #toggle>
|
||||
<gl-search-box-by-type
|
||||
ref="search"
|
||||
v-model="searchValue"
|
||||
:placeholder="searchPlaceholder"
|
||||
autofocus
|
||||
debounce="500"
|
||||
:is-loading="isLoading"
|
||||
@input="handleSearchInput"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #list-item="{ item }">
|
||||
<component :is="config.component" :data="item" @select="handleSelectItem" />
|
||||
<component :is="config.component" :data="item" />
|
||||
</template>
|
||||
</gl-collapsible-listbox>
|
||||
|
||||
|
|
@ -173,15 +212,19 @@ export default {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<component
|
||||
:is="config.component"
|
||||
v-for="(item, index) of selectedItems"
|
||||
:key="index"
|
||||
:class="{ 'gl-border-t': index > 0 }"
|
||||
class="gl-p-3"
|
||||
:data="item"
|
||||
can-delete
|
||||
@delete="handleDeleteItem"
|
||||
/>
|
||||
<div v-if="selectedItems.length">
|
||||
<component
|
||||
:is="config.component"
|
||||
v-for="(item, index) of selectedItems"
|
||||
:key="index"
|
||||
:class="{ 'gl-border-t': index > 0 }"
|
||||
class="gl-p-3"
|
||||
:data="convertToCamelCase(item)"
|
||||
can-delete
|
||||
@delete="handleDeleteItem"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-else class="gl-mt-5 gl-text-secondary">{{ emptyPlaceholder }}</div>
|
||||
</gl-card>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
<script>
|
||||
import { GlAvatar, GlButton } from '@gitlab/ui';
|
||||
import { sprintf, __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
name: 'ProjectItem',
|
||||
components: {
|
||||
GlAvatar,
|
||||
GlButton,
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
canDelete: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
deleteButtonLabel() {
|
||||
return sprintf(__('Remove exclusion for %{name}'), { name: this.name });
|
||||
},
|
||||
name() {
|
||||
return this.data.name;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span class="gl-display-flex gl-align-items-center gl-gap-3" @click="$emit('select', name)">
|
||||
<gl-avatar
|
||||
:alt="name"
|
||||
:entity-name="name"
|
||||
:size="32"
|
||||
shape="rect"
|
||||
:src="data.avatarUrl"
|
||||
fallback-on-error
|
||||
/>
|
||||
<span class="gl-display-flex gl-flex-direction-column gl-flex-grow-1 gl-max-w-30">
|
||||
<span class="gl-font-weight-bold">{{ name }}</span>
|
||||
<span class="gl-text-gray-600">{{ data.nameWithNamespace }}</span>
|
||||
</span>
|
||||
|
||||
<gl-button
|
||||
v-if="canDelete"
|
||||
icon="remove"
|
||||
:aria-label="deleteButtonLabel"
|
||||
category="tertiary"
|
||||
@click="$emit('delete', data.id)"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -202,7 +202,6 @@ export default {
|
|||
data-testid="item-status-icon"
|
||||
>
|
||||
<gl-icon
|
||||
class="gl-text-secondary"
|
||||
:class="statusIconClass"
|
||||
:name="statusIconName"
|
||||
:aria-label="stateTimestampTypeText"
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
#js-index-ml-models{ data: { view_model: view_model } }
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Projects
|
||||
module Ml
|
||||
class ModelsIndexComponent < ViewComponent::Base
|
||||
include Rails.application.routes.url_helpers
|
||||
include API::Helpers::RelatedResourcesHelpers
|
||||
|
||||
attr_reader :paginator, :model_count, :project, :user
|
||||
|
||||
def initialize(project:, current_user:, paginator:, model_count:)
|
||||
@project = project
|
||||
@paginator = paginator
|
||||
@model_count = model_count
|
||||
@user = current_user
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def view_model
|
||||
vm = {
|
||||
models: models_view_model,
|
||||
page_info: page_info_view_model,
|
||||
model_count: model_count,
|
||||
create_model_path: create_model_path,
|
||||
can_write_model_registry: user.can?(:write_model_registry, project),
|
||||
mlflow_tracking_url: mlflow_tracking_url
|
||||
}
|
||||
|
||||
Gitlab::Json.generate(vm.deep_transform_keys { |k| k.to_s.camelize(:lower) })
|
||||
end
|
||||
|
||||
def models_view_model
|
||||
paginator.records.map(&:present).map do |m|
|
||||
{
|
||||
name: m.name,
|
||||
path: m.path,
|
||||
version: m.latest_version_name,
|
||||
version_count: m.version_count,
|
||||
version_package_path: m.latest_package_path,
|
||||
version_path: m.latest_version_path
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def create_model_path
|
||||
new_project_ml_model_path(project)
|
||||
end
|
||||
|
||||
def page_info_view_model
|
||||
{
|
||||
has_next_page: paginator.has_next_page?,
|
||||
has_previous_page: paginator.has_previous_page?,
|
||||
start_cursor: paginator.cursor_for_previous_page,
|
||||
end_cursor: paginator.cursor_for_next_page
|
||||
}
|
||||
end
|
||||
|
||||
def mlflow_tracking_url
|
||||
path = api_v4_projects_ml_mlflow_api_2_0_mlflow_registered_models_create_path(id: project.id)
|
||||
|
||||
path = path.delete_suffix('registered-models/create')
|
||||
|
||||
expose_url(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1 +0,0 @@
|
|||
#js-mount-show-ml-model{ data: { view_model: view_model } }
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Projects
|
||||
module Ml
|
||||
class ShowMlModelComponent < ViewComponent::Base
|
||||
attr_reader :model, :current_user
|
||||
|
||||
def initialize(model:, current_user:)
|
||||
@model = model.present
|
||||
@current_user = current_user
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def view_model
|
||||
vm = {
|
||||
model: {
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
path: model.path,
|
||||
description: model.description,
|
||||
latest_version: latest_version_view_model,
|
||||
version_count: model.version_count,
|
||||
candidate_count: model.candidate_count
|
||||
}
|
||||
}
|
||||
|
||||
Gitlab::Json.generate(vm.deep_transform_keys { |k| k.to_s.camelize(:lower) })
|
||||
end
|
||||
|
||||
def latest_version_view_model
|
||||
return unless model.latest_version
|
||||
|
||||
model_version = model.latest_version.present
|
||||
|
||||
{
|
||||
version: model_version.version,
|
||||
description: model_version.description,
|
||||
path: model_version.path,
|
||||
project_path: project_path(model_version.project),
|
||||
package_id: model_version.package_id,
|
||||
**::Ml::CandidateDetailsPresenter.new(model_version.candidate, current_user).present
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1 +0,0 @@
|
|||
#js-mount-show-ml-model-version{ data: { view_model: view_model } }
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Projects
|
||||
module Ml
|
||||
class ShowMlModelVersionComponent < ViewComponent::Base
|
||||
attr_reader :model_version, :model, :current_user
|
||||
|
||||
def initialize(model_version:, current_user:)
|
||||
@model_version = model_version.present
|
||||
@model = model_version.model.present
|
||||
@current_user = current_user
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def view_model
|
||||
vm = {
|
||||
model_version: {
|
||||
id: model_version.id,
|
||||
version: model_version.version,
|
||||
path: model_version.path,
|
||||
description: model_version.description,
|
||||
project_path: project_path(model_version.project),
|
||||
package_id: model_version.package_id,
|
||||
model: {
|
||||
name: model.name,
|
||||
path: model.path
|
||||
},
|
||||
**candidate_data
|
||||
}
|
||||
}
|
||||
|
||||
Gitlab::Json.generate(vm.deep_transform_keys { |k| k.to_s.camelize(:lower) })
|
||||
end
|
||||
|
||||
def candidate_data
|
||||
::Ml::CandidateDetailsPresenter.new(model_version.candidate, current_user).present
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -146,9 +146,7 @@ module Types
|
|||
.group(:id) # rubocop: disable CodeReuse/ActiveRecord
|
||||
.index_by(&:id)
|
||||
|
||||
ids.each do |id|
|
||||
loader.call(id, counts[id]&.count)
|
||||
end
|
||||
ids.each { |id| loader.call(id, counts[id]&.count) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -51,10 +51,6 @@ module Ci
|
|||
job_timeout_source: 4
|
||||
}
|
||||
|
||||
def self.use_partition_id_filter?
|
||||
Ci::Pipeline.use_partition_id_filter?
|
||||
end
|
||||
|
||||
def update_timeout_state
|
||||
timeout = timeout_with_highest_precedence
|
||||
|
||||
|
|
|
|||
|
|
@ -24,9 +24,5 @@ module Ci
|
|||
def name=(value)
|
||||
super(value&.truncate(MAX_JOB_NAME_LENGTH))
|
||||
end
|
||||
|
||||
def self.use_partition_id_filter?
|
||||
Ci::Pipeline.use_partition_id_filter?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -20,9 +20,5 @@ module Ci
|
|||
validates :data, json_schema: { filename: 'ci_job_annotation_data' }
|
||||
validates :name, presence: true,
|
||||
length: { maximum: 255 }
|
||||
|
||||
def self.use_partition_id_filter?
|
||||
Ci::Pipeline.use_partition_id_filter?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -156,10 +156,6 @@ module Ci
|
|||
service.update_statistics
|
||||
end
|
||||
|
||||
def self.use_partition_id_filter?
|
||||
Ci::Pipeline.use_partition_id_filter?
|
||||
end
|
||||
|
||||
def local_store?
|
||||
[nil, ::JobArtifactUploader::Store::LOCAL].include?(self.file_store)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -588,10 +588,6 @@ module Ci
|
|||
::Gitlab::Ci::PipelineObjectHierarchy.new(relation, options: options)
|
||||
end
|
||||
|
||||
def self.use_partition_id_filter?
|
||||
true
|
||||
end
|
||||
|
||||
def uses_needs?
|
||||
processables.where(scheduling_type: :dag).any?
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,9 +25,5 @@ module Ci
|
|||
def hook_attrs
|
||||
{ key: key, value: value }
|
||||
end
|
||||
|
||||
def self.use_partition_id_filter?
|
||||
Ci::Pipeline.use_partition_id_filter?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,9 +26,5 @@ module Ci
|
|||
.pluck(:build_id, :runner_manager_id)
|
||||
.to_h
|
||||
end
|
||||
|
||||
def self.use_partition_id_filter?
|
||||
Ci::Pipeline.use_partition_id_filter?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -137,10 +137,6 @@ module Ci
|
|||
end
|
||||
end
|
||||
|
||||
def self.use_partition_id_filter?
|
||||
Ci::Pipeline.use_partition_id_filter?
|
||||
end
|
||||
|
||||
# rubocop: disable Metrics/CyclomaticComplexity -- breaking apart hurts readability, consider refactoring issue #439268
|
||||
def set_status(new_status)
|
||||
retry_optimistic_lock(self, name: 'ci_stage_set_status') do
|
||||
|
|
|
|||
|
|
@ -247,10 +247,6 @@ class CommitStatus < Ci::ApplicationRecord
|
|||
false
|
||||
end
|
||||
|
||||
def self.use_partition_id_filter?
|
||||
Ci::Pipeline.use_partition_id_filter?
|
||||
end
|
||||
|
||||
def locking_enabled?
|
||||
will_save_change_to_status?
|
||||
end
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ module Ci
|
|||
scope :failed_or_canceled, -> { with_status(:failed, :canceled, :canceling) }
|
||||
scope :complete, -> { with_status(completed_statuses) }
|
||||
scope :incomplete, -> { without_statuses(completed_statuses) }
|
||||
scope :complete_or_manual, -> { with_status(completed_with_manual_statuses) }
|
||||
scope :waiting_for_resource_or_upcoming, -> { with_status(:created, :scheduled, :waiting_for_resource) }
|
||||
|
||||
scope :cancelable, -> do
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ module Members
|
|||
return [] if current_user.nil?
|
||||
|
||||
private_invited_groups = private_invited_group_members.map(&:source).uniq
|
||||
private_invited_groups.select { |group| current_user.can?(:read_group, group) }
|
||||
Group.groups_user_can(private_invited_groups, current_user, :read_group)
|
||||
end
|
||||
strong_memoize_attr(:authorized_groups)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
- custom_settings_title = @integration.title == 'Beyond Identity' && Feature.enabled?(:beyond_identity_exclusions) ? s_('Integrations|Exclusions') : s_('Integrations|Projects using custom settings')
|
||||
- if integration.instance_level?
|
||||
.tabs.gl-tabs
|
||||
%div
|
||||
= gl_tabs_nav({ class: 'gl-mb-5' }) do
|
||||
= gl_tab_link_to _('Settings'), scoped_edit_integration_path(integration, project: @project, group: @group)
|
||||
= gl_tab_link_to s_('Integrations|Projects using custom settings'), scoped_overrides_integration_path(integration)
|
||||
= gl_tab_link_to custom_settings_title, scoped_overrides_integration_path(integration)
|
||||
|
||||
= yield
|
||||
|
||||
|
|
|
|||
|
|
@ -5,4 +5,8 @@
|
|||
%h1.page-title.gl-font-size-h-display
|
||||
= @integration.title
|
||||
|
||||
.js-vue-integration-overrides{ data: integration_overrides_data(@integration, project: @project, group: @group) }
|
||||
- if @integration.title == 'Beyond Identity' && Feature.enabled?(:beyond_identity_exclusions)
|
||||
.js-vue-beyond-identity-exclusions{ data: integration_overrides_data(@integration) }
|
||||
|
||||
- else
|
||||
.js-vue-integration-overrides{ data: integration_overrides_data(@integration, project: @project, group: @group) }
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ module Projects
|
|||
tracker.fail_op!
|
||||
|
||||
raise
|
||||
ensure
|
||||
remove_extracted_import
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -47,20 +49,29 @@ module Projects
|
|||
def extract_import_file
|
||||
Gitlab::ImportExport::FileImporter.import(
|
||||
importable: project,
|
||||
archive_file: project.import_export_upload.import_file.path,
|
||||
shared: shared_export_data
|
||||
archive_file: nil,
|
||||
shared: project.import_export_shared,
|
||||
tmpdir: tmpdir
|
||||
)
|
||||
end
|
||||
|
||||
def remove_extracted_import
|
||||
FileUtils.rm_rf(tmpdir)
|
||||
end
|
||||
|
||||
def tmpdir
|
||||
@tmpdir ||= Dir.mktmpdir('export_archives')
|
||||
end
|
||||
|
||||
def process_import
|
||||
tree_restorer = Gitlab::ImportExport::Project::RelationTreeRestorer.new(
|
||||
user: current_user,
|
||||
shared: shared_export_data,
|
||||
shared: project.import_export_shared,
|
||||
relation_reader: relation_reader,
|
||||
object_builder: Gitlab::ImportExport::Project::ObjectBuilder,
|
||||
members_mapper: members_mapper,
|
||||
relation_factory: Gitlab::ImportExport::Project::RelationFactory,
|
||||
reader: Gitlab::ImportExport::Reader.new(shared: shared_export_data),
|
||||
reader: Gitlab::ImportExport::Reader.new(shared: project.import_export_shared),
|
||||
importable: project,
|
||||
importable_attributes: relation_reader.consume_attributes('project'),
|
||||
importable_path: 'project',
|
||||
|
|
@ -72,7 +83,7 @@ module Projects
|
|||
|
||||
def relation_reader
|
||||
@relation_reader ||= Gitlab::ImportExport::Json::NdjsonReader.new(
|
||||
File.join(shared_export_data.export_path, 'tree')
|
||||
File.join(tmpdir, 'tree')
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -87,10 +98,6 @@ module Projects
|
|||
importable: project
|
||||
)
|
||||
end
|
||||
|
||||
def shared_export_data
|
||||
@shared ||= project.import_export_shared
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ identifiers:
|
|||
- project
|
||||
product_section: dev
|
||||
product_stage: manage
|
||||
product_group: import
|
||||
product_group: import_and_integrate
|
||||
milestone: "15.10"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112062
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ identifiers:
|
|||
- user
|
||||
product_section: dev
|
||||
product_stage: manage
|
||||
product_group: import
|
||||
product_group: import_and_integrate
|
||||
milestone: "15.11"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117057
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: beyond_identity_exclusions
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/454372
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/150664
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/457893
|
||||
milestone: '17.0'
|
||||
group: group::source code
|
||||
type: beta
|
||||
default_enabled: false
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
- title: 'The GitLab legacy requirement IID is deprecated in favor of work item IID'
|
||||
announcement_milestone: '15.9'
|
||||
removal_milestone: '17.0'
|
||||
removal_milestone: '18.0'
|
||||
breaking_change: true
|
||||
reporter: mmacfarlane
|
||||
body: |
|
||||
We will be transitioning to a new IID as a result of moving requirements to a [work item type](https://docs.gitlab.com/ee/development/work_items.html#work-items-and-work-item-types). Users should begin using the new IID as support for the legacy IID and existing formatting will end in GitLab 17.0. The legacy requirement IID remains available until its removal in GitLab 17.0.
|
||||
We will be transitioning to a new IID as a result of moving requirements to a [work item type](https://docs.gitlab.com/ee/development/work_items.html#work-items-and-work-item-types). Users should begin using the new IID as support for the legacy IID and existing formatting will end in GitLab 18.0. The legacy requirement IID remains available until its removal in GitLab 18.0.
|
||||
|
||||
stage: plan
|
||||
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/390263
|
||||
|
|
|
|||
|
|
@ -18691,6 +18691,7 @@ Represents a product analytics dashboard.
|
|||
| <a id="customizabledashboarderrors"></a>`errors` | [`[String!]`](#string) | Errors on yaml definition. |
|
||||
| <a id="customizabledashboardpanels"></a>`panels` | [`CustomizableDashboardPanelConnection!`](#customizabledashboardpanelconnection) | Panels shown on the dashboard. (see [Connections](#connections)) |
|
||||
| <a id="customizabledashboardslug"></a>`slug` | [`String!`](#string) | Slug of the dashboard. |
|
||||
| <a id="customizabledashboardstatus"></a>`status` **{warning-solid}** | [`String`](#string) | **Introduced** in GitLab 17.0. **Status**: Experiment. Status of the dashboard. |
|
||||
| <a id="customizabledashboardtitle"></a>`title` | [`String!`](#string) | Title of the dashboard. |
|
||||
| <a id="customizabledashboarduserdefined"></a>`userDefined` | [`Boolean!`](#boolean) | Indicates whether the dashboard is user-defined or provided by GitLab. |
|
||||
|
||||
|
|
|
|||
|
|
@ -1435,7 +1435,7 @@ job:
|
|||
|
||||
#### `artifacts:access`
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145206) in GitLab 16.10.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145206) in GitLab 16.11.
|
||||
|
||||
Use `artifacts:access` to determine who can access the job artifacts.
|
||||
|
||||
|
|
|
|||
|
|
@ -269,3 +269,148 @@ For Haml:
|
|||
```haml
|
||||
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle', data: { event_tracking: 'action', event_label: 'group_runner_form', event_property: dynamic_property_var, event_value: 2 }}) do
|
||||
```
|
||||
|
||||
#### Frontend testing
|
||||
|
||||
If you are using the `trackEvent` method in any of your code, whether it is in raw JavaScript or a Vue component, you can use the `useMockInternalEventsTracking` helper method to assert if `trackEvent` is called.
|
||||
|
||||
For example, if we need to test the below Vue component,
|
||||
|
||||
```vue
|
||||
<script>
|
||||
import { GlButton } from '@gitlab/ui';
|
||||
import { InternalEvents } from '~/tracking';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlButton,
|
||||
},
|
||||
mixins: [InternalEvents.mixin()],
|
||||
methods: {
|
||||
handleButtonClick() {
|
||||
// some application logic
|
||||
// when some event happens fire tracking call
|
||||
this.trackEvent('click_view_runners_button', {
|
||||
label: 'group_runner_form',
|
||||
property: 'property_value',
|
||||
value: 3,
|
||||
});
|
||||
},
|
||||
},
|
||||
i18n: {
|
||||
button1: __('Sample Button'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div style="display: flex; height: 90vh; align-items: center; justify-content: center">
|
||||
<gl-button class="sample-button" @click="handleButtonClick">
|
||||
{{ $options.i18n.button1 }}
|
||||
</gl-button>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
Below would be the test case for above component.
|
||||
|
||||
```javascript
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import DeleteApplication from '~/admin/applications/components/delete_application.vue';
|
||||
import { useMockInternalEventsTracking } from 'helpers/tracking_internal_events_helper';
|
||||
|
||||
describe('DeleteApplication', () => {
|
||||
/** @type {import('helpers/vue_test_utils_helper').ExtendedWrapper} */
|
||||
let wrapper;
|
||||
|
||||
const createComponent = () => {
|
||||
wrapper = shallowMountExtended(DeleteApplication);
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
describe('sample button 1', () => {
|
||||
const { bindInternalEventDocument } = useMockInternalEventsTracking();
|
||||
it('should call trackEvent method when clicked on sample button', async () => {
|
||||
const { trackEventSpy } = bindInternalEventDocument(wrapper.element);
|
||||
|
||||
await wrapper.find('.sample-button').vm.$emit('click');
|
||||
|
||||
expect(trackEventSpy).toHaveBeenCalledWith(
|
||||
'click_view_runners_button',
|
||||
{
|
||||
label: 'group_runner_form',
|
||||
property: 'property_value',
|
||||
value: 3,
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
If you are using tracking attributes for in Vue/View templates like below,
|
||||
|
||||
```vue
|
||||
<script>
|
||||
import { GlButton } from '@gitlab/ui';
|
||||
import { InternalEvents } from '~/tracking';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlButton,
|
||||
},
|
||||
mixins: [InternalEvents.mixin()],
|
||||
i18n: {
|
||||
button1: __('Sample Button'),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div style="display: flex; height: 90vh; align-items: center; justify-content: center">
|
||||
<gl-button
|
||||
class="sample-button"
|
||||
data-event-tracking="click_view_runners_button"
|
||||
data-event-label="group_runner_form"
|
||||
>
|
||||
{{ $options.i18n.button1 }}
|
||||
</gl-button>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
Below would be the test case for above component.
|
||||
|
||||
```javascript
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import DeleteApplication from '~/admin/applications/components/delete_application.vue';
|
||||
import { useMockInternalEventsTracking } from 'helpers/tracking_internal_events_helper';
|
||||
|
||||
describe('DeleteApplication', () => {
|
||||
/** @type {import('helpers/vue_test_utils_helper').ExtendedWrapper} */
|
||||
let wrapper;
|
||||
|
||||
const createComponent = () => {
|
||||
wrapper = shallowMountExtended(DeleteApplication);
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
describe('sample button', () => {
|
||||
const { bindInternalEventDocument } = useMockInternalEventsTracking();
|
||||
it('should call trackEvent method when clicked on sample button', () => {
|
||||
const { triggerEvent, trackEventSpy } = bindInternalEventDocument(wrapper.element);
|
||||
triggerEvent('.sample-button');
|
||||
expect(trackEventSpy).toHaveBeenCalledWith('click_view_runners_button', {
|
||||
label: 'group_runner_form',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
|
|
|||
|
|
@ -455,6 +455,20 @@ From GitLab 18.0 and later, the runner registration methods implemented by the n
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### The GitLab legacy requirement IID is deprecated in favor of work item IID
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">15.9</span>
|
||||
- Removal in GitLab <span class="milestone">18.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/390263).
|
||||
</div>
|
||||
|
||||
We will be transitioning to a new IID as a result of moving requirements to a [work item type](https://docs.gitlab.com/ee/development/work_items.html#work-items-and-work-item-types). Users should begin using the new IID as support for the legacy IID and existing formatting will end in GitLab 18.0. The legacy requirement IID remains available until its removal in GitLab 18.0.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### The `Project.services` GraphQL field is deprecated
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
@ -1997,20 +2011,6 @@ Instead, GitHub repositories can be imported by using the [API](https://docs.git
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### The GitLab legacy requirement IID is deprecated in favor of work item IID
|
||||
|
||||
<div class="deprecation-notes">
|
||||
- Announced in GitLab <span class="milestone">15.9</span>
|
||||
- Removal in GitLab <span class="milestone">17.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/390263).
|
||||
</div>
|
||||
|
||||
We will be transitioning to a new IID as a result of moving requirements to a [work item type](https://docs.gitlab.com/ee/development/work_items.html#work-items-and-work-item-types). Users should begin using the new IID as support for the legacy IID and existing formatting will end in GitLab 17.0. The legacy requirement IID remains available until its removal in GitLab 17.0.
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||
|
||||
### The Visual Reviews tool is deprecated
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Application information disclosure
|
||||
|
||||
## Description
|
||||
|
||||
Application information disclosure check. This includes information such as version numbers, database error messages, stack traces.
|
||||
|
||||
## Remediation
|
||||
|
||||
Application information disclosure is an application weakness where an application reveals sensitive data, such as technical details of the web application or environment. Application data may be used by an attacker to exploit the target web application, its hosting network, or its users. Therefore, leakage of sensitive data should be limited or prevented whenever possible. Information disclosure, in its most common form, is the result of one or more of the following conditions: a failure to scrub out HTML or script comments containing sensitive information or improper application or server configurations.
|
||||
|
||||
Failure to scrub HTML or script comments prior to a push to the production environment can result in the leak of sensitive, contextual, information such as server directory structure, SQL query structure, and internal network information. Often a developer will leave comments within the HTML and script code to help facilitate the debugging or integration process during the pre-production phase. Although there is no harm in allowing developers to include inline comments within the content they develop, these comments should all be removed prior to the content's public release.
|
||||
|
||||
Software version numbers and verbose error messages (such as ASP.NET version numbers) are examples of improper server configurations. This information is useful to an attacker by providing detailed insight as to the framework, languages, or pre-built functions being utilized by a web application. Most default server configurations provide software version numbers and verbose error messages for debugging and troubleshooting purposes. Configuration changes can be made to disable these features, preventing the display of this information.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A05_2021-Security_Misconfiguration)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/200.html)
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Authentication token
|
||||
|
||||
## Description
|
||||
|
||||
Perform various authentication token checks such as removing the token or changing to an invalid value.
|
||||
|
||||
## Remediation
|
||||
|
||||
API tokens must be unpredictable (random enough) to prevent guessing attacks, where an attacker is able to guess or predict a valid API Token through statistical analysis techniques. For this purpose, a good PRNG (Pseudo Random Number Generator) must be used.
|
||||
|
||||
The authentication token may have been:
|
||||
|
||||
- modified to an invalid value.
|
||||
- removed from request.
|
||||
- not match length requirements.
|
||||
- configured as a signature.
|
||||
|
||||
An API operation failed to property restrict access using an authentication token. This allows an attacker to bypass authentication gaining access to information or even the ability to modify data.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/285.html)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Cleartext authentication
|
||||
|
||||
## Description
|
||||
|
||||
This check looks for cleartext authentication such as HTTP Basic auth with no-TLS.
|
||||
|
||||
## Remediation
|
||||
|
||||
Authentication credentials are transported via unencrypted channel (HTTP). This exposes the transmitted credentials to any attacker who can monitor (sniff) the network traffic during transmission. Sensitive information such as credentials should always be transmitted via encrypted channels such as HTTPS.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A02_2021-Cryptographic_Failures)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/319.html)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# CORS
|
||||
|
||||
## Description
|
||||
|
||||
Check for CORS misconfiguration including overly permissive white-lists of accepted Origin headers or failure to validate Origin header. Also checks for allowing credentials on potentially invalid or dangerous Origins and missing headers that could potentially result in cache poisoning.
|
||||
|
||||
## Remediation
|
||||
|
||||
A misconfigured CORS implementation may be overly permissive in which domains should be trusted and at what level of trust. This could allow an untrusted domain to forge the Origin header and launch various types of attacks such as cross-site request forgery or cross-site scripting. An attacker could potentially steal a victim's credentials or send malicious requests on behalf of a victim. The victim may not even be aware that an attack is being launched.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/942.html)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# DNS rebinding
|
||||
|
||||
## Description
|
||||
|
||||
Check for DNS rebinding. This check verifies that the host checks that the HOST header of the request exists and matches the expected name of the host to avoid attacks via malicious DNS entries.
|
||||
|
||||
## Remediation
|
||||
|
||||
DNS rebinding allows a malicious host to spoof or redirect a request to an alternate IP address, potentially allowing an attacker to bypass security authentication or authorization. DNS resolution on its own does not properly constitute a valid authentication mechanism. Servers should validate that the Host header of the request matches the expected hostname of the server. In cases where the hostname is missing or does not match the expected value, the server should return a 400. The X-Forwarded-Host header is sometimes used instead of the Host header in cases where the request is being forwarded. In these cases, the X-Forwarded-Host header should also be validated if it is being used to determine the Host of the original request.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A05_2021-Security_Misconfiguration)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/350.html)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Framework debug mode
|
||||
|
||||
## Description
|
||||
|
||||
Checks to see if debug mode is enabled in various frameworks such as Flask and ASP.NET. This check has a low false positive rate.
|
||||
|
||||
## Remediation
|
||||
|
||||
The Flask or ASP .NET framework was identified with debug mode enabled. This allows an attacker the ability to download any file on the file system and other capabilities. This is a high severity issue that is easy for an attacker to exploit.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A05_2021-Security_Misconfiguration)
|
||||
- [CWE-23: Relative Path Traversal](https://cwe.mitre.org/data/definitions/23.html)
|
||||
- [CWE-285: Improper Authorization](https://cwe.mitre.org/data/definitions/285.html)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Heartbleed OpenSSL vulnerability
|
||||
|
||||
## Description
|
||||
|
||||
Check for Heartbleed OpenSSL vulnerability.
|
||||
|
||||
## Remediation
|
||||
|
||||
The Heartbleed vulnerability is a serious bug in the popular OpenSSL cryptographic library. OpenSSL is used to encrypt and decrypt communications and secure the Internet traffic. This vulnerability allows the attacker to steal protected information, which should not be accessible under other circumstance such as secret keys that are used to encrypt sensitive information.
|
||||
|
||||
Anyone on with access to the target API can use the Heartbleed vulnerability to read the memory from protected systems taking advantage of vulnerable versions of OpenSSL library.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/119.html)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# HTML injection
|
||||
|
||||
## Description
|
||||
|
||||
Check for XSS via HTML injection into all fields that support strings. This includes portions of the HTTP request such as path, query, headers and also body parameters such as XML fields, JSON fields, etc. Detection is performed by monitoring responses for the injected value in to known HTML enabled fields.
|
||||
|
||||
## Remediation
|
||||
|
||||
Cross-site scripting (XSS) is an attack technique that involves echoing attacker-supplied code into a user's browser instance. A browser instance can be a standard web browser client, or a browser object embedded in a software product such as the browser within WinAmp, an RSS reader, or an email client. The code itself is usually written in HTML/JavaScript, but may also extend to VBScript, ActiveX, Java, Flash, or any other browser-supported technology.
|
||||
|
||||
When an attacker gets a user's browser to execute his/her code, the code will run within the security context (or zone) of the hosting web site. With this level of privilege, the code has the ability to read, modify and transmit any sensitive data accessible by the browser. A Cross-site Scripted user could have his/her account hijacked (cookie theft), their browser redirected to another location, or possibly shown fraudulent content delivered by the web site they are visiting. Cross-site Scripting attacks essentially compromise the trust relationship between a user and the web site. Applications utilizing browser object instances which load content from the file system may execute code under the local machine zone allowing for system compromise.
|
||||
|
||||
There are three types of Cross-site Scripting attacks: non-persistent, persistent and DOM-based.
|
||||
|
||||
Non-persistent attacks and DOM-based attacks require a user to either visit a specially crafted link laced with malicious code, or visit a malicious web page containing a web form, which when posted to the vulnerable site, will mount the attack. Using a malicious form will oftentimes take place when the vulnerable resource only accepts HTTP POST requests. In such a case, the form can be submitted automatically, without the victim's knowledge (e.g. by using JavaScript). Upon clicking on the malicious link or submitting the malicious form, the XSS payload will get echoed back and will get interpreted by the user's browser and execute. Another technique to send almost arbitrary requests (GET and POST) is by using an embedded client, such as Adobe Flash.
|
||||
|
||||
Persistent attacks occur when the malicious code is submitted to a web site where it's stored for a period of time. Examples of an attacker's favorite targets often include message board posts, web mail messages, and web chat software. The unsuspecting user is not required to interact with any additional site/link (e.g. an attacker site or a malicious link sent via email), just simply view the web page containing the code.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A03_2021-Injection)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/79.html)
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# API security testing vulnerability checks
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/457449) from **DAST API vulnerability checks** to **API security testing vulnerability checks** in GitLab 17.0.
|
||||
|
||||
[API security testing](../index.md) provides vulnerability checks that are used to
|
||||
scan for vulnerabilities in the API under test.
|
||||
|
||||
## Passive checks
|
||||
|
||||
| Check | Severity | Type | Profiles |
|
||||
|:-----------------------------------------------------------------------------|:---------|:--------|:---------|
|
||||
| [Application information check](application_information_check.md) | Medium | Passive | Passive, Passive-Quick, Active-Quick, Active Full, Quick, Full |
|
||||
| [Cleartext authentication check](cleartext_authentication_check.md) | High | Passive | Passive, Passive-Quick, Active-Quick, Active Full, Quick, Full |
|
||||
| [JSON hijacking](json_hijacking_check.md) | Medium | Passive | Passive, Passive-Quick, Active-Quick, Active Full, Quick, Full |
|
||||
| [Sensitive information](sensitive_information_disclosure_check.md) | High | Passive | Passive, Passive-Quick, Active-Quick, Active Full, Quick, Full |
|
||||
| [Session cookie](session_cookie_check.md) | Medium | Passive | Passive, Passive-Quick, Active-Quick, Active Full, Quick, Full |
|
||||
|
||||
## Active checks
|
||||
|
||||
| Check | Severity | Type | Profiles |
|
||||
|:-----------------------------------------------------------------------------|:---------|:--------|:---------|
|
||||
| [CORS](cors_check.md) | Medium | Active | Active Full, Full |
|
||||
| [DNS rebinding](dns_rebinding_check.md) | Medium | Active | Active Full, Full |
|
||||
| [Framework debug mode](framework_debug_mode_check.md) | High | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [Heartbleed OpenSSL vulnerability](heartbleed_open_ssl_check.md) | High | Active | Active Full, Full |
|
||||
| [HTML injection check](html_injection_check.md) | Medium | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [Insecure HTTP methods](insecure_http_methods_check.md) | Medium | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [JSON injection](json_injection_check.md) | Medium | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [Open redirect](open_redirect_check.md) | Medium | Active | Active Full, Full |
|
||||
| [OS command injection](os_command_injection_check.md) | High | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [Path traversal](path_traversal_check.md) | High | Active | Active Full, Full |
|
||||
| [Sensitive file](sensitive_file_disclosure_check.md) | Medium | Active | Active Full, Full |
|
||||
| [Shellshock](shellshock_check.md) | High | Active | Active Full, Full |
|
||||
| [SQL injection](sql_injection_check.md) | High | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [TLS configuration](tls_server_configuration_check.md) | High | Active | Active Full, Full |
|
||||
| [Authentication token](authentication_token_check.md) | High | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [XML external entity](xml_external_entity_check.md) | High | Active | Active Full, Full |
|
||||
| [XML injection](xml_injection_check.md) | Medium | Active | Active-Quick, Active Full, Quick, Full |
|
||||
|
||||
## API security testing checks by profile
|
||||
|
||||
### Passive-Quick
|
||||
|
||||
- [Application information check](application_information_check.md)
|
||||
- [Cleartext authentication check](cleartext_authentication_check.md)
|
||||
- [JSON hijacking](json_hijacking_check.md)
|
||||
- [Sensitive information](sensitive_information_disclosure_check.md)
|
||||
- [Session cookie](session_cookie_check.md)
|
||||
|
||||
### Active-Quick
|
||||
|
||||
- [Application information check](application_information_check.md)
|
||||
- [Cleartext authentication check](cleartext_authentication_check.md)
|
||||
- [Framework debug mode](framework_debug_mode_check.md)
|
||||
- [HTML injection check](html_injection_check.md)
|
||||
- [Insecure HTTP methods](insecure_http_methods_check.md)
|
||||
- [JSON hijacking](json_hijacking_check.md)
|
||||
- [JSON injection](json_injection_check.md)
|
||||
- [OS command injection](os_command_injection_check.md)
|
||||
- [Sensitive information](sensitive_information_disclosure_check.md)
|
||||
- [Session cookie](session_cookie_check.md)
|
||||
- [SQL injection](sql_injection_check.md)
|
||||
- [Authentication token](authentication_token_check.md)
|
||||
- [XML injection](xml_injection_check.md)
|
||||
|
||||
### Active-Full
|
||||
|
||||
- [Application information check](application_information_check.md)
|
||||
- [Cleartext authentication check](cleartext_authentication_check.md)
|
||||
- [CORS](cors_check.md)
|
||||
- [DNS rebinding](dns_rebinding_check.md)
|
||||
- [Framework debug mode](framework_debug_mode_check.md)
|
||||
- [Heartbleed OpenSSL vulnerability](heartbleed_open_ssl_check.md)
|
||||
- [HTML injection check](html_injection_check.md)
|
||||
- [Insecure HTTP methods](insecure_http_methods_check.md)
|
||||
- [JSON hijacking](json_hijacking_check.md)
|
||||
- [JSON injection](json_injection_check.md)
|
||||
- [Open redirect](open_redirect_check.md)
|
||||
- [OS command injection](os_command_injection_check.md)
|
||||
- [Path traversal](path_traversal_check.md)
|
||||
- [Sensitive file](sensitive_file_disclosure_check.md)
|
||||
- [Sensitive information](sensitive_information_disclosure_check.md)
|
||||
- [Session cookie](session_cookie_check.md)
|
||||
- [Shellshock](shellshock_check.md)
|
||||
- [SQL injection](sql_injection_check.md)
|
||||
- [TLS configuration](tls_server_configuration_check.md)
|
||||
- [Authentication token](authentication_token_check.md)
|
||||
- [XML injection](xml_injection_check.md)
|
||||
- [XML external entity](xml_external_entity_check.md)
|
||||
|
||||
### Quick
|
||||
|
||||
- [Application information check](application_information_check.md)
|
||||
- [Cleartext authentication check](cleartext_authentication_check.md)
|
||||
- [Framework debug mode](framework_debug_mode_check.md)
|
||||
- [HTML injection check](html_injection_check.md)
|
||||
- [Insecure HTTP methods](insecure_http_methods_check.md)
|
||||
- [JSON hijacking](json_hijacking_check.md)
|
||||
- [JSON injection](json_injection_check.md)
|
||||
- [OS command injection](os_command_injection_check.md)
|
||||
- [Sensitive information](sensitive_information_disclosure_check.md)
|
||||
- [Session cookie](session_cookie_check.md)
|
||||
- [SQL injection](sql_injection_check.md)
|
||||
- [Authentication token](authentication_token_check.md)
|
||||
- [XML injection](xml_injection_check.md)
|
||||
|
||||
### Full
|
||||
|
||||
- [Application information check](application_information_check.md)
|
||||
- [Cleartext authentication check](cleartext_authentication_check.md)
|
||||
- [CORS](cors_check.md)
|
||||
- [DNS rebinding](dns_rebinding_check.md)
|
||||
- [Framework debug mode](framework_debug_mode_check.md)
|
||||
- [Heartbleed OpenSSL vulnerability](heartbleed_open_ssl_check.md)
|
||||
- [HTML injection check](html_injection_check.md)
|
||||
- [Insecure HTTP methods](insecure_http_methods_check.md)
|
||||
- [JSON hijacking](json_hijacking_check.md)
|
||||
- [JSON injection](json_injection_check.md)
|
||||
- [Open redirect](open_redirect_check.md)
|
||||
- [OS command injection](os_command_injection_check.md)
|
||||
- [Path traversal](path_traversal_check.md)
|
||||
- [Sensitive file](sensitive_file_disclosure_check.md)
|
||||
- [Sensitive information](sensitive_information_disclosure_check.md)
|
||||
- [Session cookie](session_cookie_check.md)
|
||||
- [Shellshock](shellshock_check.md)
|
||||
- [SQL injection](sql_injection_check.md)
|
||||
- [TLS configuration](tls_server_configuration_check.md)
|
||||
- [Authentication token](authentication_token_check.md)
|
||||
- [XML injection](xml_injection_check.md)
|
||||
- [XML external entity](xml_external_entity_check.md)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Insecure HTTP methods
|
||||
|
||||
## Description
|
||||
|
||||
Checks to see if HTTP methods like OPTIONS and TRACE are enabled on any target endpoints.
|
||||
|
||||
## Remediation
|
||||
|
||||
The resource tested supports the OPTIONS HTTP method. Normally this is considered a security miss configuration as it leaks supported HTTP methods leading to information gathering about a specific server or resource. However, there is a sub-set of the API community looking to use OPTIONS as a method to self discover resource operations. If this is the intended use for enabling OPTIONS, than this issue can be considered a false positive.
|
||||
|
||||
The resource tested supports the TRACE HTTP method. In combination with other cross-domain vulnerabilities in web browsers, sensitive information can be leaked from headers. It's recommended the TRACE method be disabled in your server/framework.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A05_2021-Security_Misconfiguration)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/200.html)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# JSON hijacking
|
||||
|
||||
## Description
|
||||
|
||||
Checks for JSON data potentially vulnerable to hijacking. This check looks for a GET request that returns a JSON array, which could potentially be hijacked and read by a malicious website.
|
||||
|
||||
## Remediation
|
||||
|
||||
JSON hijacking allows an attacker to send a GET request via a malicious web site or similar attack vector and utilize a user's stored credentials to retrieve sensitive or protected data to which that user has access. Since a JSON array on its own is valid JavaScript, a malicious GET request to a resource that returns only a JavaScript array can allow the attacker to use a malicious script to read the data in the array from the request. GET requests should never return a JSON array, even if the resource requires authentication to access. Consider using POST instead of a GET for this request or wrapping the array in a JSON object.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/352.html)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# JSON injection
|
||||
|
||||
## Description
|
||||
|
||||
Check for JSON serialization/injection vulnerabilities.
|
||||
|
||||
## Remediation
|
||||
|
||||
JSON injection is an attack technique used to manipulate or compromise the logic of a JSON application or service. The injection of unintended JSON content and/or structures into an JSON message can alter the intend logic of the application. Further, JSON injection can cause the insertion of malicious content into the resulting message/document.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A03_2021-Injection)
|
||||
- [CWE](CWE-929: OWASP Top Ten 2013 Category A1 - Injection)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Open redirect
|
||||
|
||||
## Description
|
||||
|
||||
Identify open redirects and determine if they can be abused by attackers.
|
||||
|
||||
## Remediation
|
||||
|
||||
Unvalidated redirects and forwards are possible when a web application accepts untrusted input that could cause the web application to redirect the request to a URL contained within untrusted input. By modifying untrusted URL input to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials. Because the server name in the modified link is identical to the original site, phishing attempts may have a more trustworthy appearance. Unvalidated redirect and forward attacks can also be used to maliciously craft a URL that would pass the application’s access control check and then forward the attacker to privileged functions that they would normally not be able to access.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/601.html)
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# OS command injection
|
||||
|
||||
## Description
|
||||
|
||||
Check for OS command injection vulnerabilities. An OS command injection attack consists of insertion or "injection" of an OS command via the input data from the client to the application.
|
||||
A successful OS command injection exploit can run arbitrary commands. This allows an attacker the ability to read, write, and delete data. Depending on the user the commands run as, this can also include administrative functions.
|
||||
|
||||
This check modifies parameters in the request (path, query string, headers, JSON, XML, etc.) to try and execute an OS command. Both standard injections and blind injections are performed. Blind injections cause delays in response when successful.
|
||||
|
||||
## Remediation
|
||||
|
||||
It is possible to execute arbitrary OS commands on the target application server. OS Command Injection is a critical vulnerability that can lead to a full system compromise. User input should never be used in constructing commands or command arguments to functions which execute OS commands. This includes filenames supplied by user uploads or downloads.
|
||||
|
||||
Ensure your application does not:
|
||||
|
||||
- Use user supplied information in the process name to execute.
|
||||
- Use user supplied information in an OS command execution function which does
|
||||
not escape shell meta-characters.
|
||||
- Use user supplied information in arguments to OS commands.
|
||||
|
||||
The application should have a hardcoded set of arguments that are to be passed to OS commands. If filenames are being passed to these functions, it is recommended that a hash of the filename be used instead, or some other unique identifier. It is strongly recommended that a native library that implements the same functionality be used instead of using OS system commands due to the risk of unknown attacks against third party commands.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A03_2021-Injection)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/78.html)
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Path traversal
|
||||
|
||||
## Description
|
||||
|
||||
Many file operations are intended to take place within a restricted directory. By using special elements such as ".." and "/" separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the "../" sequence, which in most modern operating systems is interpreted as the parent directory of the current location. This is referred to as relative path traversal. Path traversal also covers the use of absolute path-names such as "/usr/local/bin", which may also be useful in accessing unexpected files. This is referred to as absolute path traversal.
|
||||
|
||||
In many programming languages, the injection of a null byte(the 0 or NUL) may allow an attacker to truncate a generated filename to widen the scope of attack. For example, the software may add ".txt" to any pathname, thus limiting the attacker to text files, but a null injection may effectively remove this restriction.
|
||||
|
||||
This check modifies parameters in the request (path, query string, headers, JSON, XML, etc.) to try and access restricted files and files outside of the web-root. Logs and responses are then analyzed to try and detect if the file was successfully accessed.
|
||||
|
||||
## Remediation
|
||||
|
||||
The Path traversal attack technique allows an attacker access to files, directories, and commands that potentially reside outside the web document root directory. An attacker may manipulate a URL in such a way that the web site will execute or reveal the contents of arbitrary files anywhere on the web server. Any device that exposes an HTTP-based interface is potentially vulnerable to Path traversal.
|
||||
|
||||
Most web sites restrict user access to a specific portion of the file-system, typically called the “web document root” or “CGI root” directory. These directories contain the files intended for user access and the executable necessary to drive web application functionality. To access files or execute commands anywhere on the file-system, Path traversal attacks will utilize the ability of special-characters sequences.
|
||||
|
||||
The most basic Path traversal attack uses the “../” special-character sequence to alter the resource location requested in the URL. Although most popular web servers will prevent this technique from escaping the web document root, alternate encodings of the "../" sequence may help bypass the security filters. These method variations include valid and invalid Unicode-encoding ("..%u2216" or "..%c0%af") of the forward slash character, backslash characters ("..") on Windows-based servers, URL encoded characters "%2e%2e%2f"), and double URL encoding ("..%255c") of the backslash character.
|
||||
|
||||
Even if the web server properly restricts Path traversal attempts in the URL path, a web application itself may still be vulnerable due to improper handling of user-supplied input. This is a common problem of web applications that use template mechanisms or load static text from files. In variations of the attack, the original URL parameter value is substituted with the file name of one of the web application's dynamic scripts. Consequently, the results can reveal source code because the file is interpreted as text instead of an executable script. These techniques often employ additional special characters such as the dot (".") to reveal the listing of the current working directory, or “%00” NULL characters in order to bypass rudimentary file extension checks.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/22.html)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Sensitive file disclosure
|
||||
|
||||
## Description
|
||||
|
||||
Check for sensitive file disclosure. This check looks for files that may contain sensitive information. Examples include .htaccess, .htpasswd, .bash_history, etc.
|
||||
|
||||
## Remediation
|
||||
|
||||
Information leakage is an application weakness where an application reveals sensitive data, such as technical details of the web application, environment, or user-specific data. Sensitive data may be used by an attacker to exploit the target web application, its hosting network, or its users. Therefore, leakage of sensitive data should be limited or prevented whenever possible. Information Leakage, in its most common form,is the result of one or more of the following conditions: A failure to scrub out HTML/Script comments containing sensitive information, improper application or server configurations, or differences in page responses for valid versus invalid data.
|
||||
|
||||
In the case of this failure, one or more files and/or folders are accessable that should not be. This can include files common in home folders like such as command histories or files that contain secrets such as passwords.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/200.html)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Sensitive information disclosure
|
||||
|
||||
## Description
|
||||
|
||||
Sensitive information disclosure check. This includes credit card numbers, health records, personal information, etc.
|
||||
|
||||
## Remediation
|
||||
|
||||
Sensitive information leakage is an application weakness where an application reveals sensitive, user-specific data. Sensitive data may be used by an attacker to exploit its users. Therefore, leakage of sensitive data should be limited or prevented whenever possible. Information Leakage, in its most common form, is the result of differences in page responses for valid versus invalid data.
|
||||
|
||||
Pages that provide different responses based on the validity of the data can also lead to Information Leakage; specifically when data deemed confidential is being revealed as a result of the web application's design. Examples of sensitive data includes (but is not limited to): account numbers, user identifiers (Drivers license number, Passport number, Social Security Numbers, etc.) and user-specific information (passwords, sessions, addresses). Information Leakage in this context deals with exposure of key user data deemed confidential, or secret, that should not be exposed in plain view, even to the user. Credit card numbers and other heavily regulated information are prime examples of user data that needs to be further protected from exposure or leakage even with proper encryption and access controls already in place.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/200.html)
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Session cookie
|
||||
|
||||
## Description
|
||||
|
||||
Verify session cookie has correct flags and expiration.
|
||||
|
||||
## Remediation
|
||||
|
||||
Since HTTP is a stateless protocol, web sites commonly use cookies to store session IDs that uniquely identify a user from request to request. Consequently, each session ID's confidentiality must be maintained in order to prevent multiple users from accessing the same account. A stolen session ID can be used to view another user's account or perform a fraudulent
|
||||
transaction.
|
||||
|
||||
- One part of securing session ID's is to property mark them to expire and also require the correct set of flags to ensure they are not transmitted in the clear or accessible from scripting.
|
||||
- HttpOnly is an additional flag included in a Set-Cookie HTTP response header. Using the HttpOnly flag when generating a cookie helps mitigate the risk of client side script accessing the protected cookie (if the browser supports it). If the HttpOnly flag (optional) is included in the HTTP response header, the cookie cannot be accessed through client side script (again if the browser supports this flag). As a result, even if a cross-site scripting (XSS) flaw exists, and a user accidentally accesses a link that exploits this flaw, the browser will not reveal the cookie to a third party.
|
||||
- The Secure attribute for sensitive cookies in HTTPS sessions is not set, which could cause the user agent to send those cookies in plaintext over an HTTP session.
|
||||
- A session related cookie was identified being used on an insecure transport protocol. Insecure transport protocols are those that do not make use of SSL/TLS to secure the connection. Examples of such protocols are 'http'.
|
||||
- Insufficient Session Expiration occurs when a Web application permits an attacker to reuse old session credentials or session IDs for authorization. Insufficient Session Expiration increases a website's exposure to attacks that steal or reuse user's session identifiers. Since HTTP is a stateless protocol, websites commonly use cookies to store session IDs that uniquely identify a user from request to request. Consequently, each session ID's confidentiality must be maintained in order to prevent multiple users from accessing the same account. A stolen session ID can be used to view another user's account or perform a fraudulent transaction. One part of securing session ID's is to property mark them to expire and also require the correct set of flags to ensure they are not transmitted in the clear or accessible from scripting.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/930.html)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Shellshock
|
||||
|
||||
## Description
|
||||
|
||||
Check for Shellshock vulnerabilities.
|
||||
|
||||
## Remediation
|
||||
|
||||
Shellshock vulnerability takes advantage of a bug in BASH, in which, BASH incorrectly executes trailing commands when it imports a function definition stored into an environment variable. Any environment which allows defining BASH environmental variables could be vulnerable to this bug, as for example a Apache Web Server using mod_cgi and mod_cgid modules. A known-good request was modified to include malicious content. The malicious content includes an Shell shock attack in which the server-side application returns a specific text (evidence) in the response headers.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A03_2021-Injection)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/78.html)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# SQL injection
|
||||
|
||||
## Description
|
||||
|
||||
Check for SQL and NoSQL injection vulnerabilities. A SQL injection attack consists of insertion or "injection" of a SQL query via the input data from the client to the application. A successful SQL injection exploit can read sensitive data from the database, modify database data (Insert/Update/Delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file present on the DBMS file system and in some cases issue commands to the operating system. SQL injection attacks are a type of injection attack, in which SQL commands are injected into data-plane input in order to effect the execution of predefined SQL commands. This check modifies parameters in the request (path, query string, headers, JSON, XML, etc.) to try and create a syntax error in the SQL or NoSQL query. Logs and responses are then analyzed to try and detect if an error occured. If an error is detected there is a high likelihood that a vulnerability exists.
|
||||
|
||||
## Remediation
|
||||
|
||||
The software constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.
|
||||
|
||||
Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data. This can be used to alter query logic to bypass security checks, or to insert additional statements that modify the back-end database, possibly including execution of system commands.
|
||||
|
||||
SQL injection has become a common issue with database-driven websites. The flaw is easily detected, and easily exploited, and as such, any site or software package with even a minimal user base is likely to be subject to an attempted attack of this kind. This flaw depends on the fact that SQL makes no real distinction between the control and data planes.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A03_2021-Injection)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/930.html)
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# TLS server configuration
|
||||
|
||||
## Description
|
||||
|
||||
Check for various TLS Server configuration issues. Checks TLS versions, hmacs, ciphers and compression algs supported by server.
|
||||
|
||||
## Remediation
|
||||
|
||||
Insufficient transport layer protection allows communication to be exposed to untrusted third-parties, providing an attack vector to compromise a web application and/or steal sensitive information. Websites typically use Secure Sockets Layer/Transport Layer Security (SSL/TLS) to provide encryption at the transport layer. However, unless the website is configured to use SSL/TLS and configured to use SSL/TLS properly, the website may be vulnerable to traffic interception and modification.
|
||||
|
||||
SSL/TLS as a protocol have gone through several revisions over the years. Each new version adds features and fixes weaknesses in the protocol. Over time some versions of the protocol are broken so badly as to become vulnerabilities if supported. It's recommended to support only the most recent TLS versions such as TLS 1.3 (2018), and TLS 1.2 (2008).
|
||||
|
||||
Compression has been linked to side-channel attacks on TLS connections. Disabling compression can prevent these attacks. One attack in particular, CRIME ("Compression Ratio Info-leak Made Easy") can be prevented. CRIME is an attack that targets clients, but if the server does not support compression the attack is mitigated.
|
||||
|
||||
Historically, high grade cryptography was restricted from export to outside the United States. Because of this, websites were configured to support weak cryptographic options for those clients that were restricted to only using weak ciphers. Weak ciphers are vulnerable to attack because of the relative ease of breaking them; less than two weeks on a typical home computer
|
||||
and a few seconds using dedicated hardware.
|
||||
|
||||
Today, all modern browsers and websites use much stronger encryption, but some websites are still configured to support outdated weak ciphers. Because of this, an attacker may be able to force the client to downgrade to a weaker cipher when connecting to the website, allowing the attacker to break the weak encryption. For this reason, the server should be configured to only accept strong ciphers and not provide service to any client that requests using a weaker cipher. In addition, some websites are misconfigured to choose a weaker cipher even when the client will support a much stronger one. OWASP offers a guide to testing for SSL/TLS issues, including weak cipher support and misconfiguration, and there are other resources and tools as well.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A02_2021-Cryptographic_Failures)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/934.html)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# XML external entity
|
||||
|
||||
## Description
|
||||
|
||||
Check for XML DTD processing vulnerabilities.
|
||||
|
||||
## Remediation
|
||||
|
||||
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.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A03_2021-Injection)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/611.html)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# XML Injection Check
|
||||
|
||||
## Description
|
||||
|
||||
Check for XML serialization/injection vulnerabilities.
|
||||
|
||||
## Remediation
|
||||
|
||||
XML Injection is an attack technique used to manipulate or compromise the logic of an XML application or service. The injection of unintended XML content and/or structures into an XML message can alter the intend logic of the application. Further, XML injection can cause the insertion of malicious content into the resulting message/document.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A03_2021-Injection)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/91.html)
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,937 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Enabling the analyzer
|
||||
|
||||
You can specify the API you want to scan by using:
|
||||
|
||||
- [OpenAPI v2 or v3 Specification](#openapi-specification)
|
||||
- [GraphQL Schema](#graphql-schema)
|
||||
- [HTTP Archive (HAR)](#http-archive-har)
|
||||
- [Postman Collection v2.0 or v2.1](#postman-collection)
|
||||
|
||||
## OpenAPI Specification
|
||||
|
||||
The [OpenAPI Specification](https://www.openapis.org/) (formerly the Swagger Specification) is an API description format for REST APIs.
|
||||
This section shows you how to configure API security testing scanning using an OpenAPI Specification to provide information about the target API to test.
|
||||
OpenAPI Specifications are provided as a file system resource or URL. Both JSON and YAML OpenAPI formats are supported.
|
||||
|
||||
API security testing uses an OpenAPI document to generate the request body. When a request body is required,
|
||||
the body generation is limited to these body types:
|
||||
|
||||
- `application/x-www-form-urlencoded`
|
||||
- `multipart/form-data`
|
||||
- `application/json`
|
||||
- `application/xml`
|
||||
|
||||
## OpenAPI and media types
|
||||
|
||||
A media type (formerly known as MIME type) is an identifier for file formats and format contents transmitted. A OpenAPI document lets you specify that a given operation can accept different media types, hence a given request can send data using different file content. As for example, a `PUT /user` operation to update user data could accept data in either XML (media type `application/xml`) or JSON (media type `application/json`) format.
|
||||
OpenAPI 2.x lets you specify the accepted media types globally or per operation, and OpenAPI 3.x lets you specify the accepted media types per operation. API security testing will check the listed media types, and try to produce sample data for each supported media type.
|
||||
|
||||
- The default behavior is to select one of the supported media types to use. The first supported media type is chosen from the list. This behavior is configurable.
|
||||
|
||||
Testing the same operation (for example, `POST /user`) using different media types (for example, `application/json` and `application/xml`) is not always desirable.
|
||||
For example, if the target application executes the same code regardless of the request content type, it will take longer to finish the test session, and it may report duplicated vulnerabilities related to the request body depending on the target app.
|
||||
|
||||
The environment variable `DAST_API_OPENAPI_ALL_MEDIA_TYPES` lets you specify whether or not to use all supported media types instead of one when generating requests for a given operation. When the environment variable `DAST_API_OPENAPI_ALL_MEDIA_TYPES` is set to any value, API security testing tries to generate requests for all supported media types instead of one in a given operation. This will cause testing to take longer as testing is repeated for each provided media type.
|
||||
|
||||
Alternatively, the variable `DAST_API_OPENAPI_MEDIA_TYPES` is used to provide a list of media types that will each be tested. Providing more than one media type causes testing to take longer, as testing is performed for each media type selected. When the environment variable `DAST_API_OPENAPI_MEDIA_TYPES` is set to a list of media types, only the listed media types are included when creating requests.
|
||||
|
||||
Multiple media types in `DAST_API_OPENAPI_MEDIA_TYPES` are separated by a colon (`:`). For example, to limit request generation to the media types `application/x-www-form-urlencoded` and `multipart/form-data`, set the environment variable `DAST_API_OPENAPI_MEDIA_TYPES` to `application/x-www-form-urlencoded:multipart/form-data`. Only supported media types in this list are included when creating requests, though non-supported media types are always skipped. A media type text may contain different sections. For example, `application/vnd.api+json; charset=UTF-8`, is a compound of `type "/" [tree "."] subtype ["+" suffix]* [";" parameter]`. Parameters are not taken into account when performing the filtering media types on request generation.
|
||||
|
||||
The environment variables `DAST_API_OPENAPI_ALL_MEDIA_TYPES` and `DAST_API_OPENAPI_MEDIA_TYPES` allow you to decide how to handle media types. These settings are mutually exclusive. If both are enabled, API security testing reports an error.
|
||||
|
||||
### Configure API security testing with an OpenAPI Specification
|
||||
|
||||
To configure API security testing scanning with an OpenAPI Specification:
|
||||
|
||||
1. [Include](../../../../ci/yaml/index.md#includetemplate)
|
||||
the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) in your `.gitlab-ci.yml` file.
|
||||
|
||||
1. The [configuration file](variables.md#configuration-files) has several testing profiles defined with different checks enabled. We recommend that you start with the `Quick` profile.
|
||||
Testing with this profile completes faster, allowing for easier configuration validation.
|
||||
Provide the profile by adding the `DAST_API_PROFILE` CI/CD variable to your `.gitlab-ci.yml` file.
|
||||
|
||||
1. Provide the location of the OpenAPI Specification as either a file or URL.
|
||||
Specify the location by adding the `DAST_API_OPENAPI` variable.
|
||||
|
||||
1. The target API instance's base URL is also required. Provide it by using the `DAST_API_TARGET_URL`
|
||||
variable or an `environment_url.txt` file.
|
||||
|
||||
Adding the URL in an `environment_url.txt` file at your project's root is great for testing in
|
||||
dynamic environments. To run API security testing against an app dynamically created during a GitLab CI/CD
|
||||
pipeline, have the app persist its URL in an `environment_url.txt` file. API security testing
|
||||
automatically parses that file to find its scan target. You can see an
|
||||
[example of this in our Auto DevOps CI YAML](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml).
|
||||
|
||||
Complete example configuration of using an OpenAPI Specification:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_OPENAPI: test-api-specification.json
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
This is a minimal configuration for API security testing. From here you can:
|
||||
|
||||
- [Run your first scan](#running-your-first-scan).
|
||||
- [Add authentication](customizing_analyzer_settings.md#authentication).
|
||||
- Learn how to [handle false positives](#handling-false-positives).
|
||||
|
||||
## HTTP Archive (HAR)
|
||||
|
||||
The [HTTP Archive format (HAR)](../../api_fuzzing/create_har_files.md) is an archive file format for
|
||||
logging HTTP transactions. When used with the GitLab API security testing scanner, the HAR file must contain
|
||||
records of calling the web API to test. The API security testing scanner extracts all of the requests and uses them
|
||||
to perform testing.
|
||||
|
||||
You can use various tools to generate HAR files:
|
||||
|
||||
- [Insomnia Core](https://insomnia.rest/): API client
|
||||
- [Chrome](https://www.google.com/chrome/): Browser
|
||||
- [Firefox](https://www.mozilla.org/en-US/firefox/): Browser
|
||||
- [Fiddler](https://www.telerik.com/fiddler): Web debugging proxy
|
||||
- [GitLab HAR Recorder](https://gitlab.com/gitlab-org/security-products/har-recorder): Command line
|
||||
|
||||
WARNING:
|
||||
HAR files may contain sensitive information such as authentication tokens, API keys, and session
|
||||
cookies. We recommend that you review the HAR file contents before adding them to a repository.
|
||||
|
||||
### API security testing scanning with a HAR file
|
||||
|
||||
To configure API security testing to use a HAR file that provides information about the target API to test:
|
||||
|
||||
1. [Include](../../../../ci/yaml/index.md#includetemplate)
|
||||
the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) in your `.gitlab-ci.yml` file.
|
||||
|
||||
1. The [configuration file](variables.md#configuration-files) has several testing profiles defined with different checks enabled. We recommend that you start with the `Quick` profile.
|
||||
Testing with this profile completes faster, allowing for easier configuration validation.
|
||||
|
||||
Provide the profile by adding the `DAST_API_PROFILE` CI/CD variable to your `.gitlab-ci.yml` file.
|
||||
|
||||
1. Provide the location of the HAR file. You can provide the location as a file path
|
||||
or URL. Specify the location by adding the `DAST_API_HAR` variable.
|
||||
|
||||
1. The target API instance's base URL is also required. Provide it by using the `DAST_API_TARGET_URL`
|
||||
variable or an `environment_url.txt` file.
|
||||
|
||||
Adding the URL in an `environment_url.txt` file at your project's root is great for testing in
|
||||
dynamic environments. To run API security testing against an app dynamically created during a GitLab CI/CD
|
||||
pipeline, have the app persist its URL in an `environment_url.txt` file. API security testing
|
||||
automatically parses that file to find its scan target. You can see an
|
||||
[example of this in our Auto DevOps CI YAML](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml).
|
||||
|
||||
Complete example configuration of using an HAR file:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_HAR: test-api-recording.har
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
This example is a minimal configuration for API security testing. From here you can:
|
||||
|
||||
- [Run your first scan](#running-your-first-scan).
|
||||
- [Add authentication](customizing_analyzer_settings.md#authentication).
|
||||
- Learn how to [handle false positives](#handling-false-positives).
|
||||
|
||||
## GraphQL Schema
|
||||
|
||||
> - Support for GraphQL Schema was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352780) in GitLab 15.4.
|
||||
|
||||
GraphQL is a query language for your API and an alternative to REST APIs.
|
||||
API security testing supports testing GraphQL endpoints multiple ways:
|
||||
|
||||
- Test using the GraphQL Schema. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352780) in GitLab 15.4.
|
||||
- Test using a recording (HAR) of GraphQL queries.
|
||||
- Test using a Postman Collection containing GraphQL queries.
|
||||
|
||||
This section documents how to test using a GraphQL schema. The GraphQL schema support in
|
||||
API security testing is able to query the schema from endpoints that support [introspection](https://graphql.org/learn/introspection/).
|
||||
Introspection is enabled by default to allow tools like GraphiQL to work.
|
||||
For details on how to enable introspection, see your GraphQL framework documentation.
|
||||
|
||||
### API security testing scanning with a GraphQL endpoint URL
|
||||
|
||||
The GraphQL support in API security testing is able to query a GraphQL endpoint for the schema.
|
||||
|
||||
NOTE:
|
||||
The GraphQL endpoint must support introspection queries for this method to work correctly.
|
||||
|
||||
To configure API security testing to use a GraphQL endpoint URL that provides information about the target API to test:
|
||||
|
||||
1. [Include](../../../../ci/yaml/index.md#includetemplate)
|
||||
the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) in your `.gitlab-ci.yml` file.
|
||||
|
||||
1. Provide the path to the GraphQL endpoint, for example `/api/graphql`. Specify the location by adding the `DAST_API_GRAPHQL` variable.
|
||||
|
||||
1. The target API instance's base URL is also required. Provide it by using the `DAST_API_TARGET_URL`
|
||||
variable or an `environment_url.txt` file.
|
||||
|
||||
Adding the URL in an `environment_url.txt` file at your project's root is great for testing in
|
||||
dynamic environments. See the [dynamic environment solutions](../troubleshooting.md#dynamic-environment-solutions) section of our documentation for more information.
|
||||
|
||||
Complete example configuration of using a GraphQL endpoint path:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
dast_api:
|
||||
variables:
|
||||
DAST_API_GRAPHQL: /api/graphql
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
This example is a minimal configuration for API security testing. From here you can:
|
||||
|
||||
- [Run your first scan](#running-your-first-scan).
|
||||
- [Add authentication](customizing_analyzer_settings.md#authentication).
|
||||
- Learn how to [handle false positives](#handling-false-positives).
|
||||
|
||||
### API security testing scanning with a GraphQL Schema file
|
||||
|
||||
API security testing can use a GraphQL schema file to understand and test a GraphQL endpoint that has introspection disabled. To use a GraphQL schema file, it must be in the introspection JSON format. A GraphQL schema can be converted to a the introspection JSON format using an online 3rd party tool: [https://transform.tools/graphql-to-introspection-json](https://transform.tools/graphql-to-introspection-json).
|
||||
|
||||
To configure API security testing to use a GraphQL schema file that provides information about the target API to test:
|
||||
|
||||
1. [Include](../../../../ci/yaml/index.md#includetemplate)
|
||||
the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) in your `.gitlab-ci.yml` file.
|
||||
|
||||
1. Provide the GraphQL endpoint path, for example `/api/graphql`. Specify the path by adding the `DAST_API_GRAPHQL` variable.
|
||||
|
||||
1. Provide the location of the GraphQL schema file. You can provide the location as a file path
|
||||
or URL. Specify the location by adding the `DAST_API_GRAPHQL_SCHEMA` variable.
|
||||
|
||||
1. The target API instance's base URL is also required. Provide it by using the `DAST_API_TARGET_URL`
|
||||
variable or an `environment_url.txt` file.
|
||||
|
||||
Adding the URL in an `environment_url.txt` file at your project's root is great for testing in
|
||||
dynamic environments. See the [dynamic environment solutions](../troubleshooting.md#dynamic-environment-solutions) section of our documentation for more information.
|
||||
|
||||
Complete example configuration of using an GraphQL schema file:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
dast_api:
|
||||
variables:
|
||||
DAST_API_GRAPHQL: /api/graphql
|
||||
DAST_API_GRAPHQL_SCHEMA: test-api-graphql.schema
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
Complete example configuration of using an GraphQL schema file URL:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
dast_api:
|
||||
variables:
|
||||
DAST_API_GRAPHQL: /api/graphql
|
||||
DAST_API_GRAPHQL_SCHEMA: http://file-store/files/test-api-graphql.schema
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
This example is a minimal configuration for API security testing. From here you can:
|
||||
|
||||
- [Run your first scan](#running-your-first-scan).
|
||||
- [Add authentication](customizing_analyzer_settings.md#authentication).
|
||||
- Learn how to [handle false positives](#handling-false-positives).
|
||||
|
||||
## Postman Collection
|
||||
|
||||
The [Postman API Client](https://www.postman.com/product/api-client/) is a popular tool that
|
||||
developers and testers use to call various types of APIs. The API definitions
|
||||
[can be exported as a Postman Collection file](https://learning.postman.com/docs/getting-started/importing-and-exporting-data/#exporting-postman-data)
|
||||
for use with API security testing. When exporting, make sure to select a supported version of Postman
|
||||
Collection: v2.0 or v2.1.
|
||||
|
||||
When used with the GitLab API security testing scanner, Postman Collections must contain definitions of the web API to
|
||||
test with valid data. The API security testing scanner extracts all the API definitions and uses them to perform
|
||||
testing.
|
||||
|
||||
WARNING:
|
||||
Postman Collection files may contain sensitive information such as authentication tokens, API keys,
|
||||
and session cookies. We recommend that you review the Postman Collection file contents before adding
|
||||
them to a repository.
|
||||
|
||||
### API security testing scanning with a Postman Collection file
|
||||
|
||||
To configure API security testing to use a Postman Collection file that provides information about the target
|
||||
API to test:
|
||||
|
||||
1. [Include](../../../../ci/yaml/index.md#includetemplate)
|
||||
the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml).
|
||||
|
||||
1. The [configuration file](variables.md#configuration-files) has several testing profiles defined with different checks enabled. We recommend that you start with the `Quick` profile.
|
||||
Testing with this profile completes faster, allowing for easier configuration validation.
|
||||
|
||||
Provide the profile by adding the `DAST_API_PROFILE` CI/CD variable to your `.gitlab-ci.yml` file.
|
||||
|
||||
1. Provide the location of the Postman Collection file as either a file or URL. Specify the location by adding the `DAST_API_POSTMAN_COLLECTION` variable.
|
||||
|
||||
1. The target API instance's base URL is also required. Provide it by using the `DAST_API_TARGET_URL`
|
||||
variable or an `environment_url.txt` file.
|
||||
|
||||
Adding the URL in an `environment_url.txt` file at your project's root is great for testing in
|
||||
dynamic environments. To run API security testing against an app dynamically created during a GitLab CI/CD
|
||||
pipeline, have the app persist its URL in an `environment_url.txt` file. API security testing
|
||||
automatically parses that file to find its scan target. You can see an
|
||||
[example of this in our Auto DevOps CI YAML](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml).
|
||||
|
||||
Complete example configuration of using a Postman collection:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_POSTMAN_COLLECTION: postman-collection_serviceA.json
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
This is a minimal configuration for API security testing. From here you can:
|
||||
|
||||
- [Run your first scan](#running-your-first-scan).
|
||||
- [Add authentication](customizing_analyzer_settings.md#authentication).
|
||||
- Learn how to [handle false positives](#handling-false-positives).
|
||||
|
||||
### Postman variables
|
||||
|
||||
> - Support for Postman Environment file format was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/356312) in GitLab 15.1.
|
||||
> - Support for multiple variable files was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/356312) in GitLab 15.1.
|
||||
> - Support for Postman variable scopes: Global and Environment was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/356312) in GitLab 15.1.
|
||||
|
||||
#### Variables in Postman Client
|
||||
|
||||
Postman allows the developer to define placeholders that can be used in different parts of the
|
||||
requests. These placeholders are called variables, as explained in [using variables](https://learning.postman.com/docs/sending-requests/variables/).
|
||||
You can use variables to store and reuse values in your requests and scripts. For example, you can
|
||||
edit the collection to add variables to the document:
|
||||
|
||||

|
||||
|
||||
Or alternatively, you can add variables in an environment:
|
||||
|
||||

|
||||
|
||||
You can then use the variables in sections such as URL, headers, and others:
|
||||
|
||||

|
||||
|
||||
Postman has grown from a basic client tool with a nice UX experience to a more complex ecosystem that allows testing APIs with scripts, creating complex collections that trigger secondary requests, and setting variables along the way. Not every feature in the Postman ecosystem is supported. For example, scripts are not supported. The main focus of the Postman support is to ingest Postman Collection definitions that are used by the Postman Client and their related variables defined in the workspace, environments, and the collections themselves.
|
||||
|
||||
Postman allows creating variables in different scopes. Each scope has a different level of visibility in the Postman tools. For example, you can create a variable in a _global environment_ scope that is seen by every operation definition and workspace. You can also create a variable in a specific _environment_ scope that is only visible and used when that specific environment is selected for use. Some scopes are not always available, for example in the Postman ecosystem you can create requests in the Postman Client, these requests do not have a _local_ scope, but test scripts do.
|
||||
|
||||
Variable scopes in Postman can be a daunting topic and not everyone is familiar with it. We strongly recommend that you read [Variable Scopes](https://learning.postman.com/docs/sending-requests/variables/#variable-scopes) from Postman documentation before moving forward.
|
||||
|
||||
As mentioned above, there are different variable scopes, and each of them has a purpose and can be used to provide more flexibility to your Postman document. There is an important note on how values for variables are computed, as per Postman documentation:
|
||||
|
||||
> If a variable with the same name is declared in two different scopes, the value stored in the variable with narrowest scope is used. For example, if there is a global variable named `username` and a local variable named `username`, the local value is used when the request runs.
|
||||
|
||||
The following is a summary of the variable scopes supported by the Postman Client and API security testing:
|
||||
|
||||
- **Global Environment (Global) scope** is a special pre-defined environment that is available throughout a workspace. We can also refer to the _global environment_ scope as the _global_ scope. The Postman Client allows exporting the global environment into a JSON file, which can be used with API security testing.
|
||||
- **Environment scope** is a named group of variables created by a user in the Postman Client.
|
||||
The Postman Client supports a single active environment along with the global environment. The variables defined in an active user-created environment take precedence over variables defined in the global environment. The Postman Client allows exporting your environment into a JSON file, which can be used with API security testing.
|
||||
- **Collection scope** is a group of variables declared in a given collection. The collection variables are available to the collection where they have been declared and the nested requests or collections. Variables defined in the collection scope take precedence over the _global environment_ scope and also the _environment_ scope.
|
||||
The Postman Client can export one or more collections into a JSON file, this JSON file contains selected collections, requests, and collection variables.
|
||||
- **API security testing scope** is a new scope added by API security testing to allow users to provide extra variables, or override variables defined in other supported scopes. This scope is not supported by Postman. The _API security testing scope_ variables are provided using a [custom JSON file format](#api-security-testing-scope-custom-json-file-format).
|
||||
- Override values defined in the environment or collection
|
||||
- Defining variables from scripts
|
||||
- Define a single row of data from the unsupported _data scope_
|
||||
- **Data scope** is a group of variables in which their name and values come from JSON or CSV files. A Postman collection runner like [Newman](https://learning.postman.com/docs/running-collections/using-newman-cli/command-line-integration-with-newman/) or [Postman Collection Runner](https://learning.postman.com/docs/running-collections/intro-to-collection-runs/) executes the requests in a collection as many times as entries have the JSON or CSV file. A good use case for these variables is to automate tests using scripts in Postman.
|
||||
API security testing does **not** support reading data from a CSV or JSON file.
|
||||
- **Local scope** are variables that are defined in Postman scripts. API security testing does **not** support Postman scripts and by extension, variables defined in scripts. You can still provide values for the script-defined variables by defining them in one of the supported scopes, or our custom JSON format.
|
||||
|
||||
Not all scopes are supported by API security testing and variables defined in scripts are not supported. The following table is sorted by broadest scope to narrowest scope.
|
||||
|
||||
| Scope | Postman | API security testing | Comment |
|
||||
|----------------------------|:-------:|:--------------------:|:-------------------------------------------|
|
||||
| Global Environment | Yes | Yes | Special pre-defined environment |
|
||||
| Environment | Yes | Yes | Named environments |
|
||||
| Collection | Yes | Yes | Defined in your postman collection |
|
||||
| API security testing scope | No | Yes | Custom scope added by API security testing |
|
||||
| Data | Yes | No | External files in CSV or JSON format |
|
||||
| Local | Yes | No | Variables defined in scripts |
|
||||
|
||||
For more details on how to define variables and export variables in different scopes, see:
|
||||
|
||||
- [Defining collection variables](https://learning.postman.com/docs/sending-requests/variables/#defining-collection-variables)
|
||||
- [Defining environment variables](https://learning.postman.com/docs/sending-requests/variables/#defining-environment-variables)
|
||||
- [Defining global variables](https://learning.postman.com/docs/sending-requests/variables/#defining-global-variables)
|
||||
|
||||
##### Exporting from Postman Client
|
||||
|
||||
The Postman Client lets you export different file formats, for instance, you can export a Postman collection or a Postman environment.
|
||||
The exported environment can be the global environment (which is always available) or can be any custom environment you previously have created. When you export a Postman Collection, it may contain only declarations for _collection_ and _local_ scoped variables; _environment_ scoped variables are not included.
|
||||
|
||||
To get the declaration for _environment_ scoped variables, you have to export a given environment at the time. Each exported file only includes variables from the selected environment.
|
||||
|
||||
For more details on exporting variables in different supported scopes, see:
|
||||
|
||||
- [Exporting collections](https://learning.postman.com/docs/getting-started/importing-and-exporting-data/#exporting-collections)
|
||||
- [Exporting environments](https://learning.postman.com/docs/getting-started/importing-and-exporting-data/#exporting-environments)
|
||||
- [Downloading global environments](https://learning.postman.com/docs/sending-requests/variables/#downloading-global-environments)
|
||||
|
||||
#### API security testing scope, custom JSON file format
|
||||
|
||||
Our custom JSON file format is a JSON object where each object property represents a variable name and the property value represents the variable value. This file can be created using your favorite text editor, or it can be produced by an earlier job in your pipeline.
|
||||
|
||||
This example defines two variables `base_url` and `token` in the API security testing scope:
|
||||
|
||||
```json
|
||||
{
|
||||
"base_url": "http://127.0.0.1/",
|
||||
"token": "Token 84816165151"
|
||||
}
|
||||
```
|
||||
|
||||
#### Using scopes with API security testing
|
||||
|
||||
The scopes: _global_, _environment_, _collection_, and _GitLab API security testing_ are supported in [GitLab 15.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/356312). GitLab 15.0 and earlier, supports only the _collection_, and _GitLab API security testing_ scopes.
|
||||
|
||||
The following table provides a quick reference for mapping scope files/URLs to API security testing configuration variables:
|
||||
|
||||
| Scope | How to Provide |
|
||||
| ------------------ | --------------- |
|
||||
| Global environment | DAST_API_POSTMAN_COLLECTION_VARIABLES |
|
||||
| Environment | DAST_API_POSTMAN_COLLECTION_VARIABLES |
|
||||
| Collection | DAST_API_POSTMAN_COLLECTION |
|
||||
| API security testing scope | DAST_API_POSTMAN_COLLECTION_VARIABLES |
|
||||
| Data | Not supported |
|
||||
| Local | Not supported |
|
||||
|
||||
The Postman Collection document automatically includes any _collection_ scoped variables. The Postman Collection is provided with the configuration variable `DAST_API_POSTMAN_COLLECTION`. This variable can be set to a single [exported Postman collection](https://learning.postman.com/docs/getting-started/importing-and-exporting-data/#exporting-collections).
|
||||
|
||||
Variables from other scopes are provided through the `DAST_API_POSTMAN_COLLECTION_VARIABLES` configuration variable. The configuration variable supports a comma (`,`) delimited file list in [GitLab 15.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/356312). GitLab 15.0 and earlier, supports only one single file. The order of the files provided is not important as the files provide the needed scope information.
|
||||
|
||||
The configuration variable `DAST_API_POSTMAN_COLLECTION_VARIABLES` can be set to:
|
||||
|
||||
- [Exported Global environment](https://learning.postman.com/docs/sending-requests/variables/#downloading-global-environments)
|
||||
- [Exported environments](https://learning.postman.com/docs/getting-started/importing-and-exporting-data/#exporting-environments)
|
||||
- [API security testing Custom JSON format](#api-security-testing-scope-custom-json-file-format)
|
||||
|
||||
#### Undefined Postman variables
|
||||
|
||||
There is a chance that API security testing engine does not find all variables references that your Postman collection file is using. Some cases can be:
|
||||
|
||||
- You are using _data_ or _local_ scoped variables, and as stated previously these scopes are not supported by API security testing. Thus, assuming the values for these variables have not been provided through [the API security testing scope](#api-security-testing-scope-custom-json-file-format), then the values of the _data_ and _local_ scoped variables are undefined.
|
||||
- A variable name was typed incorrectly, and the name does not match the defined variable.
|
||||
- Postman Client supports a new dynamic variable that is not supported by API security testing.
|
||||
|
||||
When possible, API security testing follows the same behavior as the Postman Client does when dealing with undefined variables. The text of the variable reference remains the same, and there is no text substitution. The same behavior also applies to any unsupported dynamic variables.
|
||||
|
||||
For example, if a request definition in the Postman Collection references the variable `{{full_url}}` and the variable is not found it is left unchanged with the value `{{full_url}}`.
|
||||
|
||||
#### Dynamic Postman variables
|
||||
|
||||
In addition to variables that a user can define at various scope levels, Postman has a set of pre-defined variables called _dynamic_ variables. The [_dynamic_ variables](https://learning.postman.com/docs/writing-scripts/script-references/variables-list/) are already defined and their name is prefixed with a dollar sign (`$`), for instance, `$guid`. _Dynamic_ variables can be used like any other variable, and in the Postman Client, they produce random values during the request/collection run.
|
||||
|
||||
An important difference between API security testing and Postman is that API security testing returns the same value for each usage of the same dynamic variables. This differs from the Postman Client behavior which returns a random value on each use of the same dynamic variable. In other words, API security testing uses static values for dynamic variables while Postman uses random values.
|
||||
|
||||
The supported dynamic variables during the scanning process are:
|
||||
|
||||
| Variable | Value |
|
||||
| ----------- | ----------- |
|
||||
| `$guid` | `611c2e81-2ccb-42d8-9ddc-2d0bfa65c1b4` |
|
||||
| `$isoTimestamp` | `2020-06-09T21:10:36.177Z` |
|
||||
| `$randomAbbreviation` | `PCI` |
|
||||
| `$randomAbstractImage` | `http://no-a-valid-host/640/480/abstract` |
|
||||
| `$randomAdjective` | `auxiliary` |
|
||||
| `$randomAlphaNumeric` | `a` |
|
||||
| `$randomAnimalsImage` | `http://no-a-valid-host/640/480/animals` |
|
||||
| `$randomAvatarImage` | `https://no-a-valid-host/path/to/some/image.jpg` |
|
||||
| `$randomBankAccount` | `09454073` |
|
||||
| `$randomBankAccountBic` | `EZIAUGJ1` |
|
||||
| `$randomBankAccountIban` | `MU20ZPUN3039684000618086155TKZ` |
|
||||
| `$randomBankAccountName` | `Home Loan Account` |
|
||||
| `$randomBitcoin` | `3VB8JGT7Y4Z63U68KGGKDXMLLH5` |
|
||||
| `$randomBoolean` | `true` |
|
||||
| `$randomBs` | `killer leverage schemas` |
|
||||
| `$randomBsAdjective` | `viral` |
|
||||
| `$randomBsBuzz` | `repurpose` |
|
||||
| `$randomBsNoun` | `markets` |
|
||||
| `$randomBusinessImage` | `http://no-a-valid-host/640/480/business` |
|
||||
| `$randomCatchPhrase` | `Future-proofed heuristic open architecture` |
|
||||
| `$randomCatchPhraseAdjective` | `Business-focused` |
|
||||
| `$randomCatchPhraseDescriptor` | `bandwidth-monitored` |
|
||||
| `$randomCatchPhraseNoun` | `superstructure` |
|
||||
| `$randomCatsImage` | `http://no-a-valid-host/640/480/cats` |
|
||||
| `$randomCity` | `Spinkahaven` |
|
||||
| `$randomCityImage` | `http://no-a-valid-host/640/480/city` |
|
||||
| `$randomColor` | `fuchsia` |
|
||||
| `$randomCommonFileExt` | `wav` |
|
||||
| `$randomCommonFileName` | `well_modulated.mpg4` |
|
||||
| `$randomCommonFileType` | `audio` |
|
||||
| `$randomCompanyName` | `Grady LLC` |
|
||||
| `$randomCompanySuffix` | `Inc` |
|
||||
| `$randomCountry` | `Kazakhstan` |
|
||||
| `$randomCountryCode` | `MD` |
|
||||
| `$randomCreditCardMask` | `3622` |
|
||||
| `$randomCurrencyCode` | `ZMK` |
|
||||
| `$randomCurrencyName` | `Pound Sterling` |
|
||||
| `$randomCurrencySymbol` | `£` |
|
||||
| `$randomDatabaseCollation` | `utf8_general_ci` |
|
||||
| `$randomDatabaseColumn` | `updatedAt` |
|
||||
| `$randomDatabaseEngine` | `Memory` |
|
||||
| `$randomDatabaseType` | `text` |
|
||||
| `$randomDateFuture` | `Tue Mar 17 2020 13:11:50 GMT+0530 (India Standard Time)` |
|
||||
| `$randomDatePast` | `Sat Mar 02 2019 09:09:26 GMT+0530 (India Standard Time)` |
|
||||
| `$randomDateRecent` | `Tue Jul 09 2019 23:12:37 GMT+0530 (India Standard Time)` |
|
||||
| `$randomDepartment` | `Electronics` |
|
||||
| `$randomDirectoryPath` | `/usr/local/bin` |
|
||||
| `$randomDomainName` | `trevor.info` |
|
||||
| `$randomDomainSuffix` | `org` |
|
||||
| `$randomDomainWord` | `jaden` |
|
||||
| `$randomEmail` | `Iva.Kovacek61@no-a-valid-host.com` |
|
||||
| `$randomExampleEmail` | `non-a-valid-user@example.net` |
|
||||
| `$randomFashionImage` | `http://no-a-valid-host/640/480/fashion` |
|
||||
| `$randomFileExt` | `war` |
|
||||
| `$randomFileName` | `neural_sri_lanka_rupee_gloves.gdoc` |
|
||||
| `$randomFilePath` | `/home/programming_chicken.cpio` |
|
||||
| `$randomFileType` | `application` |
|
||||
| `$randomFirstName` | `Chandler` |
|
||||
| `$randomFoodImage` | `http://no-a-valid-host/640/480/food` |
|
||||
| `$randomFullName` | `Connie Runolfsdottir` |
|
||||
| `$randomHexColor` | `#47594a` |
|
||||
| `$randomImageDataUri` | `data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20baseProfile%3D%22full%22%20width%3D%22undefined%22%20height%3D%22undefined%22%3E%20%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22grey%22%2F%3E%20%20%3Ctext%20x%3D%220%22%20y%3D%2220%22%20font-size%3D%2220%22%20text-anchor%3D%22start%22%20fill%3D%22white%22%3Eundefinedxundefined%3C%2Ftext%3E%20%3C%2Fsvg%3E` |
|
||||
| `$randomImageUrl` | `http://no-a-valid-host/640/480` |
|
||||
| `$randomIngverb` | `navigating` |
|
||||
| `$randomInt` | `494` |
|
||||
| `$randomIP` | `241.102.234.100` |
|
||||
| `$randomIPV6` | `dbe2:7ae6:119b:c161:1560:6dda:3a9b:90a9` |
|
||||
| `$randomJobArea` | `Mobility` |
|
||||
| `$randomJobDescriptor` | `Senior` |
|
||||
| `$randomJobTitle` | `International Creative Liaison` |
|
||||
| `$randomJobType` | `Supervisor` |
|
||||
| `$randomLastName` | `Schneider` |
|
||||
| `$randomLatitude` | `55.2099` |
|
||||
| `$randomLocale` | `ny` |
|
||||
| `$randomLongitude` | `40.6609` |
|
||||
| `$randomLoremLines` | `Ducimus in ut mollitia.\nA itaque non.\nHarum temporibus nihil voluptas.\nIste in sed et nesciunt in quaerat sed.` |
|
||||
| `$randomLoremParagraph` | `Ab aliquid odio iste quo voluptas voluptatem dignissimos velit. Recusandae facilis qui commodi ea magnam enim nostrum quia quis. Nihil est suscipit assumenda ut voluptatem sed. Esse ab voluptas odit qui molestiae. Rem est nesciunt est quis ipsam expedita consequuntur.` |
|
||||
| `$randomLoremParagraphs` | `Voluptatem rem magnam aliquam ab id aut quaerat. Placeat provident possimus voluptatibus dicta velit non aut quasi. Mollitia et aliquam expedita sunt dolores nam consequuntur. Nam dolorum delectus ipsam repudiandae et ipsam ut voluptatum totam. Nobis labore labore recusandae ipsam quo.` |
|
||||
| `$randomLoremSentence` | `Molestias consequuntur nisi non quod.` |
|
||||
| `$randomLoremSentences` | `Et sint voluptas similique iure amet perspiciatis vero sequi atque. Ut porro sit et hic. Neque aspernatur vitae fugiat ut dolore et veritatis. Ab iusto ex delectus animi. Voluptates nisi iusto. Impedit quod quae voluptate qui.` |
|
||||
| `$randomLoremSlug` | `eos-aperiam-accusamus, beatae-id-molestiae, qui-est-repellat` |
|
||||
| `$randomLoremText` | `Quisquam asperiores exercitationem ut ipsum. Aut eius nesciunt. Et reiciendis aut alias eaque. Nihil amet laboriosam pariatur eligendi. Sunt ullam ut sint natus ducimus. Voluptas harum aspernatur soluta rem nam.` |
|
||||
| `$randomLoremWord` | `est` |
|
||||
| `$randomLoremWords` | `vel repellat nobis` |
|
||||
| `$randomMACAddress` | `33:d4:68:5f:b4:c7` |
|
||||
| `$randomMimeType` | `audio/vnd.vmx.cvsd` |
|
||||
| `$randomMonth` | `February` |
|
||||
| `$randomNamePrefix` | `Dr.` |
|
||||
| `$randomNameSuffix` | `MD` |
|
||||
| `$randomNatureImage` | `http://no-a-valid-host/640/480/nature` |
|
||||
| `$randomNightlifeImage` | `http://no-a-valid-host/640/480/nightlife` |
|
||||
| `$randomNoun` | `bus` |
|
||||
| `$randomPassword` | `t9iXe7COoDKv8k3` |
|
||||
| `$randomPeopleImage` | `http://no-a-valid-host/640/480/people` |
|
||||
| `$randomPhoneNumber` | `700-008-5275` |
|
||||
| `$randomPhoneNumberExt` | `27-199-983-3864` |
|
||||
| `$randomPhrase` | `You can't program the monitor without navigating the mobile XML program!` |
|
||||
| `$randomPrice` | `531.55` |
|
||||
| `$randomProduct` | `Pizza` |
|
||||
| `$randomProductAdjective` | `Unbranded` |
|
||||
| `$randomProductMaterial` | `Steel` |
|
||||
| `$randomProductName` | `Handmade Concrete Tuna` |
|
||||
| `$randomProtocol` | `https` |
|
||||
| `$randomSemver` | `7.0.5` |
|
||||
| `$randomSportsImage` | `http://no-a-valid-host/640/480/sports` |
|
||||
| `$randomStreetAddress` | `5742 Harvey Streets` |
|
||||
| `$randomStreetName` | `Kuhic Island` |
|
||||
| `$randomTransactionType` | `payment` |
|
||||
| `$randomTransportImage` | `http://no-a-valid-host/640/480/transport` |
|
||||
| `$randomUrl` | `https://no-a-valid-host.net` |
|
||||
| `$randomUserAgent` | `Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.9.8; rv:15.6) Gecko/20100101 Firefox/15.6.6` |
|
||||
| `$randomUserName` | `Jarrell.Gutkowski` |
|
||||
| `$randomUUID` | `6929bb52-3ab2-448a-9796-d6480ecad36b` |
|
||||
| `$randomVerb` | `navigate` |
|
||||
| `$randomWeekday` | `Thursday` |
|
||||
| `$randomWord` | `withdrawal` |
|
||||
| `$randomWords` | `Samoa Synergistic sticky copying Grocery` |
|
||||
| `$timestamp` | `1562757107` |
|
||||
|
||||
#### Example: Global Scope
|
||||
|
||||
In this example, [the _global_ scope is exported](https://learning.postman.com/docs/sending-requests/variables/#downloading-global-environments) from the Postman Client as `global-scope.json` and provided to API security testing through the `DAST_API_POSTMAN_COLLECTION_VARIABLES` configuration variable.
|
||||
|
||||
Here is an example of using `DAST_API_POSTMAN_COLLECTION_VARIABLES`:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_POSTMAN_COLLECTION: postman-collection.json
|
||||
DAST_API_POSTMAN_COLLECTION_VARIABLES: global-scope.json
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
#### Example: Environment Scope
|
||||
|
||||
In this example, [the _environment_ scope is exported](https://learning.postman.com/docs/getting-started/importing-and-exporting-data/#exporting-environments) from the Postman Client as `environment-scope.json` and provided to API security testing through the `DAST_API_POSTMAN_COLLECTION_VARIABLES` configuration variable.
|
||||
|
||||
Here is an example of using `DAST_API_POSTMAN_COLLECTION_VARIABLES`:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_POSTMAN_COLLECTION: postman-collection.json
|
||||
DAST_API_POSTMAN_COLLECTION_VARIABLES: environment-scope.json
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
#### Example: Collection Scope
|
||||
|
||||
The _collection_ scope variables are included in the exported Postman Collection file and provided through the `DAST_API_POSTMAN_COLLECTION` configuration variable.
|
||||
|
||||
Here is an example of using `DAST_API_POSTMAN_COLLECTION`:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_POSTMAN_COLLECTION: postman-collection.json
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
#### Example: API security testing scope
|
||||
|
||||
The API security testing scope is used for two main purposes, defining _data_ and _local_ scope variables that are not supported by API security testing, and changing the value of an existing variable defined in another scope. The API security testing scope is provided through the `DAST_API_POSTMAN_COLLECTION_VARIABLES` configuration variable.
|
||||
|
||||
Here is an example of using `DAST_API_POSTMAN_COLLECTION_VARIABLES`:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_POSTMAN_COLLECTION: postman-collection.json
|
||||
DAST_API_POSTMAN_COLLECTION_VARIABLES: dast-api-scope.json
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
The file `dast-api-scope.json` uses our [custom JSON file format](#api-security-testing-scope-custom-json-file-format). This JSON is an object with key-value pairs for properties. The keys are the variables' names, and the values are the variables'
|
||||
values. For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"base_url": "http://127.0.0.1/",
|
||||
"token": "Token 84816165151"
|
||||
}
|
||||
```
|
||||
|
||||
#### Example: Multiple Scopes
|
||||
|
||||
In this example, a _global_ scope, _environment_ scope, and _collection_ scope are configured. The first step is to export our various scopes.
|
||||
|
||||
- [Export the _global_ scope](https://learning.postman.com/docs/sending-requests/variables/#downloading-global-environments) as `global-scope.json`
|
||||
- [Export the _environment_ scope](https://learning.postman.com/docs/getting-started/importing-and-exporting-data/#exporting-environments) as `environment-scope.json`
|
||||
- Export the Postman Collection which includes the _collection_ scope as `postman-collection.json`
|
||||
|
||||
The Postman Collection is provided using the `DAST_API_POSTMAN_COLLECTION` variable, while the other scopes are provided using the `DAST_API_POSTMAN_COLLECTION_VARIABLES`. API security testing can identify which scope the provided files match using data provided in each file.
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_POSTMAN_COLLECTION: postman-collection.json
|
||||
DAST_API_POSTMAN_COLLECTION_VARIABLES: global-scope.json,environment-scope.json
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
#### Example: Changing a Variables Value
|
||||
|
||||
When using exported scopes, it's often the case that the value of a variable must be changed for use with API security testing. For example, a _collection_ scoped variable might contain a variable named `api_version` with a value of `v2`, while your test needs a value of `v1`. Instead of modifying the exported collection to change the value, the API security testing scope can be used to change its value. This works because the _API security testing_ scope takes precedence over all other scopes.
|
||||
|
||||
The _collection_ scope variables are included in the exported Postman Collection file and provided through the `DAST_API_POSTMAN_COLLECTION` configuration variable.
|
||||
|
||||
The API security testing scope is provided through the `DAST_API_POSTMAN_COLLECTION_VARIABLES` configuration variable, but first, we must create the file.
|
||||
The file `dast-api-scope.json` uses our [custom JSON file format](#api-security-testing-scope-custom-json-file-format). This JSON is an object with key-value pairs for properties. The keys are the variables' names, and the values are the variables'
|
||||
values. For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"api_version": "v1"
|
||||
}
|
||||
```
|
||||
|
||||
Our CI definition:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_POSTMAN_COLLECTION: postman-collection.json
|
||||
DAST_API_POSTMAN_COLLECTION_VARIABLES: dast-api-scope.json
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
#### Example: Changing a Variables Value with Multiple Scopes
|
||||
|
||||
When using exported scopes, it's often the case that the value of a variable must be changed for use with API security testing. For example, an _environment_ scope might contain a variable named `api_version` with a value of `v2`, while your test needs a value of `v1`. Instead of modifying the exported file to change the value, the API security testing scope can be used. This works because the _API security testing_ scope takes precedence over all other scopes.
|
||||
|
||||
In this example, a _global_ scope, _environment_ scope, _collection_ scope, and _API security testing_ scope are configured. The first step is to export and create our various scopes.
|
||||
|
||||
- [Export the _global_ scope](https://learning.postman.com/docs/sending-requests/variables/#downloading-global-environments) as `global-scope.json`
|
||||
- [Export the _environment_ scope](https://learning.postman.com/docs/getting-started/importing-and-exporting-data/#exporting-environments) as `environment-scope.json`
|
||||
- Export the Postman Collection which includes the _collection_ scope as `postman-collection.json`
|
||||
|
||||
The API security testing scope is used by creating a file `dast-api-scope.json` using our [custom JSON file format](#api-security-testing-scope-custom-json-file-format). This JSON is an object with key-value pairs for properties. The keys are the variables' names, and the values are the variables'
|
||||
values. For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"api_version": "v1"
|
||||
}
|
||||
```
|
||||
|
||||
The Postman Collection is provided using the `DAST_API_POSTMAN_COLLECTION` variable, while the other scopes are provided using the `DAST_API_POSTMAN_COLLECTION_VARIABLES`. API security testing can identify which scope the provided files match using data provided in each file.
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_POSTMAN_COLLECTION: postman-collection.json
|
||||
DAST_API_POSTMAN_COLLECTION_VARIABLES: global-scope.json,environment-scope.json,dast-api-scope.json
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
```
|
||||
|
||||
## Running your first scan
|
||||
|
||||
When configured correctly, a CI/CD pipeline contains a `dast` stage and an `dast_api` job. The job only fails when an invalid configuration is provided. During typical operation, the job always succeeds even if vulnerabilities are identified during testing.
|
||||
|
||||
Vulnerabilities are displayed on the **Security** pipeline tab with the suite name. When testing against the repositories default branch, the API security testing vulnerabilities are also shown on the Security and Compliance's Vulnerability Report page.
|
||||
|
||||
To prevent an excessive number of reported vulnerabilities, the API security testing scanner limits the number of vulnerabilities it reports per operation.
|
||||
|
||||
## Viewing API security testing vulnerabilities
|
||||
|
||||
The API security testing analyzer produces a JSON report that is collected and used
|
||||
[to populate the vulnerabilities into GitLab vulnerability screens](#view-details-of-an-api-security-testing-vulnerability).
|
||||
|
||||
See [handling false positives](#handling-false-positives) for information about configuration changes you can make to limit the number of false positives reported.
|
||||
|
||||
### View details of an API security testing vulnerability
|
||||
|
||||
Follow these steps to view details of a vulnerability:
|
||||
|
||||
1. You can view vulnerabilities in a project, or a merge request:
|
||||
|
||||
- In a project, go to the project's **Secure > Vulnerability report**
|
||||
page. This page shows all vulnerabilities from the default branch only.
|
||||
- In a merge request, go the merge request's **Security** section and select the **Expand**
|
||||
button. API security testing vulnerabilities are available in a section labeled
|
||||
**DAST detected N potential vulnerabilities**. Select the title to display the vulnerability
|
||||
details.
|
||||
|
||||
1. Select the vulnerabilities title to display the details. The table below describes these details.
|
||||
|
||||
| Field | Description |
|
||||
|:--------------------|:----------------------------------------------------------------------------------------|
|
||||
| Description | Description of the vulnerability including what was modified. |
|
||||
| Project | Namespace and project in which the vulnerability was detected. |
|
||||
| Method | HTTP method used to detect the vulnerability. |
|
||||
| URL | URL at which the vulnerability was detected. |
|
||||
| Request | The HTTP request that caused the vulnerability. |
|
||||
| Unmodified Response | Response from an unmodified request. This is what a typical working response looks like.|
|
||||
| Actual Response | Response received from test request. |
|
||||
| Evidence | How we determined a vulnerability occurred. |
|
||||
| Identifiers | The API security testing check used to find this vulnerability. |
|
||||
| Severity | Severity of the vulnerability. |
|
||||
| Scanner Type | Scanner used to perform testing. |
|
||||
|
||||
### Security Dashboard
|
||||
|
||||
The Security Dashboard is a good place to get an overview of all the security vulnerabilities in your groups, projects and
|
||||
pipelines. For more information, see the [Security Dashboard documentation](../../security_dashboard/index.md).
|
||||
|
||||
### Interacting with the vulnerabilities
|
||||
|
||||
Once a vulnerability is found, you can interact with it. Read more on how to
|
||||
[address the vulnerabilities](../../vulnerabilities/index.md).
|
||||
|
||||
### Handling False Positives
|
||||
|
||||
False positives can be handled in several ways:
|
||||
|
||||
- Dismiss the vulnerability.
|
||||
- Some checks have several methods of detecting when a vulnerability is identified, called _Assertions_.
|
||||
Assertions can also be turned off and configured. For example, the API security testing scanner by default uses HTTP
|
||||
status codes to help identify when something is a real issue. If an API returns a 500 error during
|
||||
testing, this creates a vulnerability. This isn't always desired, as some frameworks return 500 errors often.
|
||||
- Turn off the Check producing the false positive. This prevents the check from generating any
|
||||
vulnerabilities. Example checks are the SQL Injection Check, and JSON Hijacking Check.
|
||||
|
||||
#### Turn off a Check
|
||||
|
||||
Checks perform testing of a specific type and can be turned on and off for specific configuration
|
||||
profiles. The provided [configuration files](variables.md#configuration-files) define several profiles that you
|
||||
can use. The profile definition in the configuration file lists all the checks that are active
|
||||
during a scan. To turn off a specific check, remove it from the profile definition in the
|
||||
configuration file. The profiles are defined in the `Profiles` section of the configuration file.
|
||||
|
||||
Example profile definition:
|
||||
|
||||
```yaml
|
||||
Profiles:
|
||||
- Name: Quick
|
||||
DefaultProfile: Empty
|
||||
Routes:
|
||||
- Route: *Route0
|
||||
Checks:
|
||||
- Name: ApplicationInformationCheck
|
||||
- Name: CleartextAuthenticationCheck
|
||||
- Name: FrameworkDebugModeCheck
|
||||
- Name: HtmlInjectionCheck
|
||||
- Name: InsecureHttpMethodsCheck
|
||||
- Name: JsonHijackingCheck
|
||||
- Name: JsonInjectionCheck
|
||||
- Name: SensitiveInformationCheck
|
||||
- Name: SessionCookieCheck
|
||||
- Name: SqlInjectionCheck
|
||||
- Name: TokenCheck
|
||||
- Name: XmlInjectionCheck
|
||||
```
|
||||
|
||||
To turn off the JSON Hijacking Check you can remove these lines:
|
||||
|
||||
```yaml
|
||||
- Name: JsonHijackingCheck
|
||||
```
|
||||
|
||||
This results in the following YAML:
|
||||
|
||||
```yaml
|
||||
- Name: Quick
|
||||
DefaultProfile: Empty
|
||||
Routes:
|
||||
- Route: *Route0
|
||||
Checks:
|
||||
- Name: ApplicationInformationCheck
|
||||
- Name: CleartextAuthenticationCheck
|
||||
- Name: FrameworkDebugModeCheck
|
||||
- Name: HtmlInjectionCheck
|
||||
- Name: InsecureHttpMethodsCheck
|
||||
- Name: JsonInjectionCheck
|
||||
- Name: SensitiveInformationCheck
|
||||
- Name: SessionCookieCheck
|
||||
- Name: SqlInjectionCheck
|
||||
- Name: TokenCheck
|
||||
- Name: XmlInjectionCheck
|
||||
```
|
||||
|
||||
#### Turn off an Assertion for a Check
|
||||
|
||||
Assertions detect vulnerabilities in tests produced by checks. Many checks support multiple Assertions such as Log Analysis, Response Analysis, and Status Code. When a vulnerability is found, the Assertion used is provided. To identify which Assertions are on by default, see the Checks default configuration in the configuration file. The section is called `Checks`.
|
||||
|
||||
This example shows the SQL Injection Check:
|
||||
|
||||
```yaml
|
||||
- Name: SqlInjectionCheck
|
||||
Configuration:
|
||||
UserInjections: []
|
||||
Assertions:
|
||||
- Name: LogAnalysisAssertion
|
||||
- Name: ResponseAnalysisAssertion
|
||||
- Name: StatusCodeAssertion
|
||||
```
|
||||
|
||||
Here you can see three Assertions are on by default. A common source of false positives is
|
||||
`StatusCodeAssertion`. To turn it off, modify its configuration in the `Profiles` section. This
|
||||
example provides only the other two Assertions (`LogAnalysisAssertion`,
|
||||
`ResponseAnalysisAssertion`). This prevents `SqlInjectionCheck` from using `StatusCodeAssertion`:
|
||||
|
||||
```yaml
|
||||
Profiles:
|
||||
- Name: Quick
|
||||
DefaultProfile: Empty
|
||||
Routes:
|
||||
- Route: *Route0
|
||||
Checks:
|
||||
- Name: ApplicationInformationCheck
|
||||
- Name: CleartextAuthenticationCheck
|
||||
- Name: FrameworkDebugModeCheck
|
||||
- Name: HtmlInjectionCheck
|
||||
- Name: InsecureHttpMethodsCheck
|
||||
- Name: JsonHijackingCheck
|
||||
- Name: JsonInjectionCheck
|
||||
- Name: SensitiveInformationCheck
|
||||
- Name: SessionCookieCheck
|
||||
- Name: SqlInjectionCheck
|
||||
Assertions:
|
||||
- Name: LogAnalysisAssertion
|
||||
- Name: ResponseAnalysisAssertion
|
||||
- Name: TokenCheck
|
||||
- Name: XmlInjectionCheck
|
||||
```
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
type: reference, howto
|
||||
---
|
||||
|
||||
# Configuration
|
||||
|
||||
- [Requirements](requirements.md)
|
||||
- [Enabling the analyzer](enabling_the_analyzer.md)
|
||||
- [Customize analyzer settings](customizing_analyzer_settings.md)
|
||||
- [Overriding analyzer jobs](overriding_analyzer_jobs.md)
|
||||
- [Available CI/CD variables](variables.md)
|
||||
- [Offline configuration](offline_configuration.md)
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Offline configuration
|
||||
|
||||
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access to external resources through the internet, some adjustments are required for the API security testing job to successfully run.
|
||||
|
||||
Steps:
|
||||
|
||||
1. Host the Docker image in a local container registry.
|
||||
1. Set the `SECURE_ANALYZERS_PREFIX` to the local container registry.
|
||||
|
||||
The Docker image for API security testing must be pulled (downloaded) from the public registry and then pushed (imported) into a local registry. The GitLab container registry can be used to locally host the Docker image. This process can be performed using a special template. See [loading Docker images onto your offline host](../../offline_deployments/index.md#loading-docker-images-onto-your-offline-host) for instructions.
|
||||
|
||||
Once the Docker image is hosted locally, the `SECURE_ANALYZERS_PREFIX` variable is set with the location of the local registry. The variable must be set such that concatenating `/api-security:2` results in a valid image location.
|
||||
|
||||
NOTE:
|
||||
API security testing and API Fuzzing both use the same underlying Docker image `api-security:2`.
|
||||
|
||||
For example, the below line sets a registry for the image `registry.gitlab.com/security-products/api-security:2`:
|
||||
|
||||
`SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"`
|
||||
|
||||
NOTE:
|
||||
Setting `SECURE_ANALYZERS_PREFIX` changes the Docker image registry location for all GitLab Secure templates.
|
||||
|
||||
For more information, see [Offline environments](../../offline_deployments/index.md).
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
type: reference, howto
|
||||
---
|
||||
|
||||
# Overriding API security testing jobs
|
||||
|
||||
To override a job definition, (for example, change properties like `variables`, `dependencies`, or [`rules`](../../../../ci/yaml/index.md#rules)),
|
||||
declare a job with the same name as the DAST job to override. Place this new job after the template
|
||||
inclusion and specify any additional keys under it. For example, this sets the target APIs base URL:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- template: Security/DAST-API.gitlab-ci.yml
|
||||
|
||||
dast_api:
|
||||
variables:
|
||||
DAST_API_TARGET_URL: https://target/api
|
||||
```
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
type: reference, howto
|
||||
---
|
||||
|
||||
# Requirements
|
||||
|
||||
- A web API using one of the supported API types:
|
||||
- REST API
|
||||
- SOAP
|
||||
- GraphQL
|
||||
- Form bodies, JSON, or XML
|
||||
- An API specification in one of the following formats:
|
||||
- [OpenAPI v2 or v3 Specification](enabling_the_analyzer.md#openapi-specification)
|
||||
- [GraphQL Schema](enabling_the_analyzer.md#graphql-schema)
|
||||
- [HTTP Archive (HAR)](enabling_the_analyzer.md#http-archive-har)
|
||||
- [Postman Collection v2.0 or v2.1](enabling_the_analyzer.md#postman-collection)
|
||||
- [GitLab Runner](../../../../ci/runners/index.md) available, with the
|
||||
[`docker` executor](https://docs.gitlab.com/runner/executors/docker.html) on Linux/amd64.
|
||||
- Target application deployed. For more details, read [Deployment options](#application-deployment-options).
|
||||
- `dast` stage added to the CI/CD pipeline definition. This should be added after the deploy step, for example:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
- dast
|
||||
```
|
||||
|
||||
## Recommendations
|
||||
|
||||
- Configure runners to use the [always pull policy](https://docs.gitlab.com/runner/executors/docker.html#using-the-always-pull-policy) to run the latest versions of the analyzers.
|
||||
- By default, API security testing downloads all artifacts defined by previous jobs in the pipeline. If
|
||||
your DAST job does not rely on `environment_url.txt` to define the URL under test or any other files created
|
||||
in previous jobs, we recommend you don't download artifacts. To avoid downloading
|
||||
artifacts, extend the analyzer CI/CD job to specify no dependencies. For example, for the DAST proxy-based analyzer add the following to your `.gitlab-ci.yml` file:
|
||||
|
||||
```yaml
|
||||
dast_api:
|
||||
dependencies: []
|
||||
```
|
||||
|
||||
## Application deployment options
|
||||
|
||||
API security testing requires a deployed application to be available to scan.
|
||||
|
||||
Depending on the complexity of the target application, there are a few options as to how to deploy and configure
|
||||
the API security testing template.
|
||||
|
||||
### Review Apps
|
||||
|
||||
Review Apps are the most involved method of deploying your DAST target application. To assist in the process,
|
||||
we created a Review App deployment using Google Kubernetes Engine (GKE). This example can be found in our
|
||||
[Review Apps - GKE](https://gitlab.com/gitlab-org/security-products/demos/dast/review-app-gke) project, along with detailed
|
||||
instructions in the [README.md](https://gitlab.com/gitlab-org/security-products/demos/dast/review-app-gke/-/blob/master/README.md)
|
||||
on how to configure Review Apps for DAST.
|
||||
|
||||
### Docker Services
|
||||
|
||||
If your application uses Docker containers you have another option for deploying and scanning with DAST.
|
||||
After your Docker build job completes and your image is added to your container registry, you can use the image as a
|
||||
[service](../../../../ci/services/index.md).
|
||||
|
||||
By using service definitions in your `.gitlab-ci.yml`, you can scan services with the DAST analyzer.
|
||||
|
||||
When adding a `services` section to the job, the `alias` is used to define the hostname that can be used to access the service. In the following example, the `alias: yourapp` portion of the `dast` job definition means that the URL to the deployed application uses `yourapp` as the hostname (`https://yourapp/`).
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- build
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
# Deploys the container to the GitLab container registry
|
||||
deploy:
|
||||
services:
|
||||
- name: docker:dind
|
||||
alias: dind
|
||||
image: docker:20.10.16
|
||||
stage: build
|
||||
script:
|
||||
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
||||
- docker pull $CI_REGISTRY_IMAGE:latest || true
|
||||
- docker build --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
|
||||
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
- docker push $CI_REGISTRY_IMAGE:latest
|
||||
|
||||
dast_api:
|
||||
services: # use services to link your app container to the dast job
|
||||
- name: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
alias: yourapp
|
||||
|
||||
variables:
|
||||
DAST_API_TARGET_URL: https://yourapp
|
||||
```
|
||||
|
||||
Most applications depend on multiple services such as databases or caching services. By default, services defined in the services fields cannot communicate
|
||||
with each another. To allow communication between services, enable the `FF_NETWORK_PER_BUILD` [feature flag](https://docs.gitlab.com/runner/configuration/feature-flags.html#available-feature-flags).
|
||||
|
||||
```yaml
|
||||
variables:
|
||||
FF_NETWORK_PER_BUILD: "true" # enable network per build so all services can communicate on the same network
|
||||
|
||||
services: # use services to link the container to the dast job
|
||||
- name: mongo:latest
|
||||
alias: mongo
|
||||
- name: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
|
||||
alias: yourapp
|
||||
```
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Available CI/CD variables and configuration files
|
||||
|
||||
## Available CI/CD variables
|
||||
|
||||
| CI/CD variable | Description |
|
||||
|------------------------------------------------------|--------------------|
|
||||
| `SECURE_ANALYZERS_PREFIX` | Specify the Docker registry base address from which to download the analyzer. |
|
||||
| `DAST_API_DISABLED` | Set to 'true' or '1' to disable API security testing scanning. |
|
||||
| `DAST_API_DISABLED_FOR_DEFAULT_BRANCH` | Set to 'true' or '1' to disable API security testing scanning for only the default (production) branch. |
|
||||
| `DAST_API_VERSION` | Specify API security testing container version. Defaults to `3`. |
|
||||
| `DAST_API_IMAGE_SUFFIX` | Specify a container image suffix. Defaults to none. |
|
||||
| `DAST_API_API_PORT` | Specify the communication port number used by API security testing engine. Defaults to `5500`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/367734) in GitLab 15.5. |
|
||||
| `DAST_API_TARGET_URL` | Base URL of API testing target. |
|
||||
|[`DAST_API_CONFIG`](#configuration-files) | API security testing configuration file. Defaults to `.gitlab-dast-api.yml`. |
|
||||
|[`DAST_API_PROFILE`](#configuration-files) | Configuration profile to use during testing. Defaults to `Quick`. |
|
||||
|[`DAST_API_EXCLUDE_PATHS`](customizing_analyzer_settings.md#exclude-paths) | Exclude API URL paths from testing. |
|
||||
|[`DAST_API_EXCLUDE_URLS`](customizing_analyzer_settings.md#exclude-urls) | Exclude API URL from testing. |
|
||||
|[`DAST_API_EXCLUDE_PARAMETER_ENV`](customizing_analyzer_settings.md#exclude-parameters) | JSON string containing excluded parameters. |
|
||||
|[`DAST_API_EXCLUDE_PARAMETER_FILE`](customizing_analyzer_settings.md#exclude-parameters) | Path to a JSON file containing excluded parameters. |
|
||||
|[`DAST_API_REQUEST_HEADERS`](customizing_analyzer_settings.md#request-headers) | A comma-separated (`,`) list of headers to include on each scan request. Consider using `DAST_API_REQUEST_HEADERS_BASE64` when storing secret header values in a [masked variable](../../../../ci/variables/index.md#mask-a-cicd-variable), which has character set restrictions. |
|
||||
|[`DAST_API_REQUEST_HEADERS_BASE64`](customizing_analyzer_settings.md#request-headers) | A comma-separated (`,`) list of headers to include on each scan request, Base64-encoded. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/378440) in GitLab 15.6. |
|
||||
|[`DAST_API_OPENAPI`](enabling_the_analyzer.md#openapi-specification) | OpenAPI specification file or URL. |
|
||||
|[`DAST_API_OPENAPI_RELAXED_VALIDATION`](enabling_the_analyzer.md#openapi-specification) | Relax document validation. Default is disabled. |
|
||||
|[`DAST_API_OPENAPI_ALL_MEDIA_TYPES`](enabling_the_analyzer.md#openapi-specification) | Use all supported media types instead of one when generating requests. Causes test duration to be longer. Default is disabled. |
|
||||
|[`DAST_API_OPENAPI_MEDIA_TYPES`](enabling_the_analyzer.md#openapi-specification) | Colon (`:`) separated media types accepted for testing. Default is disabled. |
|
||||
|[`DAST_API_HAR`](enabling_the_analyzer.md#http-archive-har) | HTTP Archive (HAR) file. |
|
||||
|[`DAST_API_GRAPHQL`](enabling_the_analyzer.md#graphql-schema) | Path to GraphQL endpoint, for example `/api/graphql`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352780) in GitLab 15.4. |
|
||||
|[`DAST_API_GRAPHQL_SCHEMA`](enabling_the_analyzer.md#graphql-schema) | A URL or filename for a GraphQL schema in JSON format. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352780) in GitLab 15.4. |
|
||||
|[`DAST_API_POSTMAN_COLLECTION`](enabling_the_analyzer.md#postman-collection) | Postman Collection file. |
|
||||
|[`DAST_API_POSTMAN_COLLECTION_VARIABLES`](enabling_the_analyzer.md#postman-variables) | Path to a JSON file to extract Postman variable values. The support for comma-separated (`,`) files was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/356312) in GitLab 15.1. |
|
||||
|[`DAST_API_OVERRIDES_FILE`](customizing_analyzer_settings.md#overrides) | Path to a JSON file containing overrides. |
|
||||
|[`DAST_API_OVERRIDES_ENV`](customizing_analyzer_settings.md#overrides) | JSON string containing headers to override. |
|
||||
|[`DAST_API_OVERRIDES_CMD`](customizing_analyzer_settings.md#overrides) | Overrides command. |
|
||||
|[`DAST_API_OVERRIDES_CMD_VERBOSE`](customizing_analyzer_settings.md#overrides) | When set to any value. It shows overrides command output as part of the job output. |
|
||||
|`DAST_API_PRE_SCRIPT` | Run user command or script before scan session starts. |
|
||||
|`DAST_API_POST_SCRIPT` | Run user command or script after scan session has finished. |
|
||||
|[`DAST_API_OVERRIDES_INTERVAL`](customizing_analyzer_settings.md#overrides) | How often to run overrides command in seconds. Defaults to `0` (once). |
|
||||
|[`DAST_API_HTTP_USERNAME`](customizing_analyzer_settings.md#http-basic-authentication) | Username for HTTP authentication. |
|
||||
|[`DAST_API_HTTP_PASSWORD`](customizing_analyzer_settings.md#http-basic-authentication) | Password for HTTP authentication. Consider using `DAST_API_HTTP_PASSWORD_BASE64` instead. |
|
||||
|[`DAST_API_HTTP_PASSWORD_BASE64`](customizing_analyzer_settings.md#http-basic-authentication) | Password for HTTP authentication, base64-encoded. [Introduced](https://gitlab.com/gitlab-org/security-products/analyzers/api-fuzzing-src/-/merge_requests/702) in GitLab 15.4. |
|
||||
|`DAST_API_SERVICE_START_TIMEOUT` | How long to wait for target API to become available in seconds. Default is 300 seconds. |
|
||||
|`DAST_API_TIMEOUT` | How long to wait for API responses in seconds. Default is 30 seconds. |
|
||||
|
||||
## Configuration files
|
||||
|
||||
To get you started quickly, GitLab provides the configuration file
|
||||
[`gitlab-dast-api-config.yml`](https://gitlab.com/gitlab-org/security-products/analyzers/dast/-/blob/master/config/gitlab-dast-api-config.yml).
|
||||
This file has several testing profiles that perform various numbers of tests. The run time of each
|
||||
profile increases as the test numbers go up. To use a configuration file, add it to your
|
||||
repository's root as `.gitlab/gitlab-dast-api-config.yml`.
|
||||
|
||||
### Profiles
|
||||
|
||||
The following profiles are pre-defined in the default configuration file. Profiles
|
||||
can be added, removed, and modified by creating a custom configuration.
|
||||
|
||||
#### Passive
|
||||
|
||||
- Application Information Check
|
||||
- Cleartext Authentication Check
|
||||
- JSON Hijacking Check
|
||||
- Sensitive Information Check
|
||||
- Session Cookie Check
|
||||
|
||||
#### Quick
|
||||
|
||||
- Application Information Check
|
||||
- Cleartext Authentication Check
|
||||
- FrameworkDebugModeCheck
|
||||
- HTML Injection Check
|
||||
- Insecure Http Methods Check
|
||||
- JSON Hijacking Check
|
||||
- JSON Injection Check
|
||||
- Sensitive Information Check
|
||||
- Session Cookie Check
|
||||
- SQL Injection Check
|
||||
- Token Check
|
||||
- XML Injection Check
|
||||
|
||||
#### Full
|
||||
|
||||
- Application Information Check
|
||||
- Cleartext AuthenticationCheck
|
||||
- CORS Check
|
||||
- DNS Rebinding Check
|
||||
- Framework Debug Mode Check
|
||||
- HTML Injection Check
|
||||
- Insecure Http Methods Check
|
||||
- JSON Hijacking Check
|
||||
- JSON Injection Check
|
||||
- Open Redirect Check
|
||||
- Sensitive File Check
|
||||
- Sensitive Information Check
|
||||
- Session Cookie Check
|
||||
- SQL Injection Check
|
||||
- TLS Configuration Check
|
||||
- Token Check
|
||||
- XML Injection Check
|
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
|
@ -0,0 +1,85 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# API security testing analyzer
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
> - API security testing analyzer [became the default analyzer for on-demand API security testing scans](https://gitlab.com/groups/gitlab-org/-/epics/4254) in GitLab 15.6.
|
||||
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/457449) from **DAST API analyzer** to **API security testing analyzer** in GitLab 17.0.
|
||||
|
||||
Perform Dynamic Application Security Testing (DAST) of web APIs to help discover bugs and potential
|
||||
security issues that other QA processes may miss. Use API security testing in addition to
|
||||
other [GitLab Secure](../index.md) security scanners and your own test processes. You can run DAST
|
||||
API tests either as part your CI/CD workflow, [on-demand](../dast/on-demand_scan.md), or both.
|
||||
|
||||
WARNING:
|
||||
Do not run API security testing against a production server. Not only can it perform _any_ function that
|
||||
the API can, it may also trigger bugs in the API. This includes actions like modifying and deleting
|
||||
data. Only run API security testing against a test server.
|
||||
|
||||
API security testing can test the following web API types:
|
||||
|
||||
- REST API
|
||||
- SOAP
|
||||
- GraphQL
|
||||
- Form bodies, JSON, or XML
|
||||
|
||||
## When API security testing scans run
|
||||
|
||||
When run in your CI/CD pipeline, API security testing scanning runs in the `dast` stage by default. To ensure
|
||||
API security testing scanning examines the latest code, ensure your CI/CD pipeline deploys changes to a test
|
||||
environment in a stage before the `dast` stage.
|
||||
|
||||
If your pipeline is configured to deploy to the same web server on each run, running a pipeline
|
||||
while another is still running could cause a race condition in which one pipeline overwrites the
|
||||
code from another. The API to be scanned should be excluded from changes for the duration of a
|
||||
API security testing scan. The only changes to the API should be from the API security testing scanner. Changes made to the
|
||||
API (for example, by users, scheduled tasks, database changes, code changes, other pipelines, or
|
||||
other scanners) during a scan could cause inaccurate results.
|
||||
|
||||
## Example API security testing scanning configurations
|
||||
|
||||
The following projects demonstrate API security testing scanning:
|
||||
|
||||
- [Example OpenAPI v2 Specification project](https://gitlab.com/gitlab-org/security-products/demos/api-dast/openapi-example)
|
||||
- [Example HTTP Archive (HAR) project](https://gitlab.com/gitlab-org/security-products/demos/api-dast/har-example)
|
||||
- [Example Postman Collection project](https://gitlab.com/gitlab-org/security-products/demos/api-dast/postman-example)
|
||||
- [Example GraphQL project](https://gitlab.com/gitlab-org/security-products/demos/api-dast/graphql-example)
|
||||
- [Example SOAP project](https://gitlab.com/gitlab-org/security-products/demos/api-dast/soap-example)
|
||||
- [Authentication Token using Selenium](https://gitlab.com/gitlab-org/security-products/demos/api-dast/auth-token-selenium)
|
||||
|
||||
## Get support or request an improvement
|
||||
|
||||
To get support for your particular problem, use the [getting help channels](https://about.gitlab.com/get-help/).
|
||||
|
||||
The [GitLab issue tracker on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues) is the right place for bugs and feature proposals about API Security and API security testing.
|
||||
Use `~"Category:API Security"` [label](../../../development/labels/index.md) when opening a new issue regarding API security testing to ensure it is quickly reviewed by the right people. Refer to our [review response SLO](https://handbook.gitlab.com/handbook/engineering/workflow/code-review/#review-response-slo) to understand when you should receive a response.
|
||||
|
||||
[Search the issue tracker](https://gitlab.com/gitlab-org/gitlab/-/issues) for similar entries before submitting your own, there's a good chance somebody else had the same issue or feature proposal. Show your support with an emoji reaction or join the discussion.
|
||||
|
||||
When experiencing a behavior not working as expected, consider providing contextual information:
|
||||
|
||||
- GitLab version if using a self-managed instance.
|
||||
- `.gitlab-ci.yml` job definition.
|
||||
- Full job console output.
|
||||
- Scanner log file available as a job artifact named `gl-api-security-scanner.log`.
|
||||
|
||||
WARNING:
|
||||
**Sanitize data attached to a support issue**. Remove sensitive information, including: credentials, passwords, tokens, keys, and secrets.
|
||||
|
||||
## Glossary
|
||||
|
||||
- Assert: Assertions are detection modules used by checks to trigger a vulnerability. Many assertions have
|
||||
configurations. A check can use multiple Assertions. For example, Log Analysis, Response Analysis,
|
||||
and Status Code are common Assertions used together by checks. Checks with multiple Assertions
|
||||
allow them to be turned on and off.
|
||||
- Check: Performs a specific type of test, or performed a check for a type of vulnerability. For
|
||||
example, the SQL Injection Check performs DAST testing for SQL Injection vulnerabilities. The API security testing scanner is comprised of several checks. Checks can be turned on and off in a profile.
|
||||
- Profile: A configuration file has one or more testing profiles, or sub-configurations. You may
|
||||
have a profile for feature branches and another with extra testing for a main branch.
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Performance tuning and testing speed
|
||||
|
||||
Security tools that perform dynamic analysis testing, such as API security testing, perform testing by sending requests to an instance of your running application. The requests are engineered to test for specific vulnerabilities that might exist in your application. The speed of a dynamic analysis test depends on the following:
|
||||
|
||||
- How many requests per second can be sent to your application by our tooling
|
||||
- How fast your application responds to requests
|
||||
- How many requests must be sent to test the application
|
||||
- How many operations your API is comprised of
|
||||
- How many fields are in each operation (think JSON bodies, headers, query string, cookies, etc.)
|
||||
|
||||
If the API security testing job still takes longer than expected reach after following the advice in this performance guide, reach out to support for further assistance.
|
||||
|
||||
## Diagnosing performance issues
|
||||
|
||||
The first step to resolving performance issues is to understand what is contributing to the slower-than-expected testing time. Some common issues we see are:
|
||||
|
||||
- API security testing is running on a low-vCPU runner
|
||||
- The application deployed to a slow/single-CPU instance and is not able to keep up with the testing load
|
||||
- The application contains a slow operation that impacts the overall test speed (> 1/2 second)
|
||||
- The application contains an operation that returns a large amount of data (> 500K+)
|
||||
- The application contains a large number of operations (> 40)
|
||||
|
||||
### The application contains a slow operation that impacts the overall test speed (> 1/2 second)
|
||||
|
||||
The API security testing job output contains helpful information about how fast we are testing, how fast each operation being tested responds, and summary information. Let's take a look at some sample output to see how it can be used in tracking down performance issues:
|
||||
|
||||
```shell
|
||||
DAST API: Loaded 10 operations from: assets/har-large-response/large_responses.har
|
||||
DAST API:
|
||||
DAST API: Testing operation [1/10]: 'GET http://target:7777/api/large_response_json'.
|
||||
DAST API: - Parameters: (Headers: 4, Query: 0, Body: 0)
|
||||
DAST API: - Request body size: 0 Bytes (0 bytes)
|
||||
DAST API:
|
||||
DAST API: Finished testing operation 'GET http://target:7777/api/large_response_json'.
|
||||
DAST API: - Excluded Parameters: (Headers: 0, Query: 0, Body: 0)
|
||||
DAST API: - Performed 767 requests
|
||||
DAST API: - Average response body size: 130 MB
|
||||
DAST API: - Average call time: 2 seconds and 82.69 milliseconds (2.082693 seconds)
|
||||
DAST API: - Time to complete: 14 minutes, 8 seconds and 788.36 milliseconds (848.788358 seconds)
|
||||
```
|
||||
|
||||
This job console output snippet starts by telling us how many operations were found (10), followed by notifications that testing has started on a specific operation and a summary of the operation has been completed. The summary is the most interesting part of this log output. In the summary, we can see that it took API security testing 767 requests to fully test this operation and its related fields. We can also see that the average response time was 2 seconds and the time to complete was 14 minutes for this one operation.
|
||||
|
||||
An average response time of 2 seconds is a good initial indicator that this specific operation takes a long time to test. Further, we can see that the response body size is quite large. The large body size is the culprit here, transferring that much data on each request is what takes the majority of that 2 seconds.
|
||||
|
||||
For this issue, the team might decide to:
|
||||
|
||||
- Use a runner with more vCPUs, as this allows API security testing to parallelize the work being performed. This helps lower the test time, but getting the test down under 10 minutes might still be problematic without moving to a high CPU machine due to how long the operation takes to test. While larger runners are more costly, you also pay for less minutes if the job executions are quicker.
|
||||
- [Exclude this operation](#excluding-slow-operations) from API security testing. While this is the simplest, it has the downside of a gap in security test coverage.
|
||||
- [Exclude the operation from feature branch API security testing, but include it in the default branch test](#excluding-operations-in-feature-branches-but-not-default-branch).
|
||||
- [Split up API security testing into multiple jobs](#splitting-a-test-into-multiple-jobs).
|
||||
|
||||
The likely solution is to use a combination of these solutions to reach an acceptable test time, assuming your team's requirements are in the 5-7 minute range.
|
||||
|
||||
## Addressing performance issues
|
||||
|
||||
The following sections document various options for addressing performance issues for API security testing:
|
||||
|
||||
- [Using a larger runner](#using-a-larger-runner)
|
||||
- [Excluding slow operations](#excluding-slow-operations)
|
||||
- [Splitting a test into multiple jobs](#splitting-a-test-into-multiple-jobs)
|
||||
- [Excluding operations in feature branches, but not default branch](#excluding-operations-in-feature-branches-but-not-default-branch)
|
||||
|
||||
### Using a larger runner
|
||||
|
||||
One of the easiest performance boosts can be achieved using a [larger runner](../../../ci/runners/hosted_runners/linux.md#machine-types-available-for-linux-x86-64) with API security testing. This table shows statistics collected during benchmarking of a Java Spring Boot REST API. In this benchmark, the target and API security testing share a single runner instance.
|
||||
|
||||
| Hosted runner on Linux tag | Requests per Second |
|
||||
|------------------------------------|-----------|
|
||||
| `saas-linux-small-amd64` (default) | 255 |
|
||||
| `saas-linux-medium-amd64` | 400 |
|
||||
|
||||
As we can see from this table, increasing the size of the runner and vCPU count can have a large impact on testing speed/performance.
|
||||
|
||||
Here is an example job definition for API security testing that adds a `tags` section to use the medium SaaS runner on Linux. The job extends the job definition included through the API security testing template.
|
||||
|
||||
```yaml
|
||||
dast_api:
|
||||
tags:
|
||||
- saas-linux-medium-amd64
|
||||
```
|
||||
|
||||
In the `gl-api-security-scanner.log` file you can search for the string `Starting work item processor` to inspect the reported max DOP (degree of parallelism). The max DOP should be greater than or equal to the number of vCPUs assigned to the runner. If unable to identify the problem, open a ticket with support to assist.
|
||||
|
||||
Example log entry:
|
||||
|
||||
`17:00:01.084 [INF] <Peach.Web.Core.Services.WebRunnerMachine> Starting work item processor with 4 max DOP`
|
||||
|
||||
### Excluding slow operations
|
||||
|
||||
In the case of one or two slow operations, the team might decide to skip testing the operations. Excluding the operation is done using the `DAST_API_EXCLUDE_PATHS` configuration [variable as explained in this section.](configuration/customizing_analyzer_settings.md#exclude-paths)
|
||||
|
||||
In this example, we have an operation that returns a large amount of data. The operation is `GET http://target:7777/api/large_response_json`. To exclude it we provide the `DAST_API_EXCLUDE_PATHS` configuration variable with the path portion of our operation URL `/api/large_response_json`.
|
||||
|
||||
To verify the operation is excluded, run the API security testing job and review the job console output. It includes a list of included and excluded operations at the end of the test.
|
||||
|
||||
```yaml
|
||||
dast_api:
|
||||
variables:
|
||||
DAST_API_EXCLUDE_PATHS: /api/large_response_json
|
||||
```
|
||||
|
||||
Excluding operations from testing could allow some vulnerabilities to go undetected.
|
||||
{: .alert .alert-warning}
|
||||
|
||||
### Splitting a test into multiple jobs
|
||||
|
||||
Splitting a test into multiple jobs is supported by API security testing through the use of [`DAST_API_EXCLUDE_PATHS`](configuration/customizing_analyzer_settings.md#exclude-paths) and [`DAST_API_EXCLUDE_URLS`](configuration/customizing_analyzer_settings.md#exclude-urls). When splitting a test up, a good pattern is to disable the `dast_api` job and replace it with two jobs with identifying names. In this example we have two jobs, each job is testing a version of the API, so our names reflect that. However, this technique can be applied to any situation, not just with versions of an API.
|
||||
|
||||
The rules we are using in the `dast_api_v1` and `dast_api_v2` jobs are copied from the [API security testing template](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml).
|
||||
|
||||
```yaml
|
||||
# Disable the main dast_api job
|
||||
dast_api:
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
when: never
|
||||
|
||||
dast_api_v1:
|
||||
extends: dast_api
|
||||
variables:
|
||||
DAST_API_EXCLUDE_PATHS: /api/v1/**
|
||||
rules:
|
||||
- if: $DAST_API_DISABLED == 'true' || $DAST_API_DISABLED == '1'
|
||||
when: never
|
||||
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == 'true' &&
|
||||
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
|
||||
when: never
|
||||
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == '1' &&
|
||||
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH &&
|
||||
$CI_GITLAB_FIPS_MODE == "true"
|
||||
variables:
|
||||
DAST_API_IMAGE_SUFFIX: "-fips"
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
|
||||
dast_api_v2:
|
||||
variables:
|
||||
DAST_API_EXCLUDE_PATHS: /api/v2/**
|
||||
rules:
|
||||
- if: $DAST_API_DISABLED == 'true' || $DAST_API_DISABLED == '1'
|
||||
when: never
|
||||
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == 'true' &&
|
||||
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
|
||||
when: never
|
||||
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == '1' &&
|
||||
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH &&
|
||||
$CI_GITLAB_FIPS_MODE == "true"
|
||||
variables:
|
||||
DAST_API_IMAGE_SUFFIX: "-fips"
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
```
|
||||
|
||||
### Excluding operations in feature branches, but not default branch
|
||||
|
||||
In the case of one or two slow operations, the team might decide to skip testing the operations, or exclude them from feature branch tests, but include them for default branch tests. Excluding the operation is done using the `DAST_API_EXCLUDE_PATHS` configuration [variable as explained in this section.](configuration/customizing_analyzer_settings.md#exclude-paths)
|
||||
|
||||
In this example, we have an operation that returns a large amount of data. The operation is `GET http://target:7777/api/large_response_json`. To exclude it we provide the `DAST_API_EXCLUDE_PATHS` configuration variable with the path portion of our operation URL `/api/large_response_json`. Our configuration disables the main `dast_api` job and creates two new jobs `dast_api_main` and `dast_api_branch`. The `dast_api_branch` is set up to exclude the long operation and only run on non-default branches (for example, feature branches). The `dast_api_main` branch is set up to only execute on the default branch (`main` in this example). The `dast_api_branch` jobs run faster, allowing for quick development cycles, while the `dast_api_main` job which only runs on default branch builds, takes longer to run.
|
||||
|
||||
To verify the operation is excluded, run the API security testing job and review the job console output. It includes a list of included and excluded operations at the end of the test.
|
||||
|
||||
```yaml
|
||||
# Disable the main job so we can create two jobs with
|
||||
# different names
|
||||
dast_api:
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
when: never
|
||||
|
||||
# API security testing for feature branch work, excludes /api/large_response_json
|
||||
dast_api_branch:
|
||||
extends: dast_api
|
||||
variables:
|
||||
DAST_API_EXCLUDE_PATHS: /api/large_response_json
|
||||
rules:
|
||||
- if: $DAST_API_DISABLED == 'true' || $DAST_API_DISABLED == '1'
|
||||
when: never
|
||||
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == 'true' &&
|
||||
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
|
||||
when: never
|
||||
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == '1' &&
|
||||
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH &&
|
||||
$CI_GITLAB_FIPS_MODE == "true"
|
||||
variables:
|
||||
DAST_API_IMAGE_SUFFIX: "-fips"
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
|
||||
# API security testing for default branch (main in our case)
|
||||
# Includes the long running operations
|
||||
dast_api_main:
|
||||
extends: dast_api
|
||||
rules:
|
||||
- if: $DAST_API_DISABLED == 'true' || $DAST_API_DISABLED == '1'
|
||||
when: never
|
||||
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == 'true' &&
|
||||
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
|
||||
when: never
|
||||
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH == '1' &&
|
||||
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH &&
|
||||
$CI_GITLAB_FIPS_MODE == "true"
|
||||
variables:
|
||||
DAST_API_IMAGE_SUFFIX: "-fips"
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
```
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
## API security testing job times out after N hours
|
||||
|
||||
For larger repositories, the API security testing job could time out on the [small hosted runner on Linux](../../../ci/runners/hosted_runners/linux.md#machine-types-available-for-linux-x86-64), which is set per default. If this happens in your jobs, you should scale up to a [larger runner](performance.md#using-a-larger-runner).
|
||||
|
||||
See the following documentation sections for assistance:
|
||||
|
||||
- [Performance tuning and testing speed](performance.md#performance-tuning-and-testing-speed)
|
||||
- [Using a larger Runner](performance.md#using-a-larger-runner)
|
||||
- [Excluding operations by path](configuration/customizing_analyzer_settings.md#exclude-paths)
|
||||
- [Excluding slow operations](performance.md#excluding-slow-operations)
|
||||
|
||||
## API security testing job takes too long to complete
|
||||
|
||||
See [Performance Tuning and Testing Speed](performance.md#performance-tuning-and-testing-speed)
|
||||
|
||||
## Error: `Error waiting for DAST API 'http://127.0.0.1:5000' to become available`
|
||||
|
||||
A bug exists in versions of the API security testing analyzer prior to v1.6.196 that can cause a background process to fail under certain conditions. The solution is to update to a newer version of the API security testing analyzer.
|
||||
|
||||
The version information can be found in the job details for the `dast_api` job.
|
||||
|
||||
If the issue is occurring with versions v1.6.196 or greater, contact Support and provide the following information:
|
||||
|
||||
1. Reference this troubleshooting section and ask for the issue to be escalated to the Dynamic Analysis Team.
|
||||
1. The full console output of the job.
|
||||
1. The `gl-api-security-scanner.log` file available as a job artifact. In the right-hand panel of the job details page, select the **Browse** button.
|
||||
1. The `dast_api` job definition from your `.gitlab-ci.yml` file.
|
||||
|
||||
**Error message**
|
||||
|
||||
- In [GitLab 15.6 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/376078), `Error waiting for DAST API 'http://127.0.0.1:5000' to become available`
|
||||
- In GitLab 15.5 and earlier, `Error waiting for API Security 'http://127.0.0.1:5000' to become available`.
|
||||
|
||||
## `Failed to start scanner session (version header not found)`
|
||||
|
||||
The API security testing engine outputs an error message when it cannot establish a connection with the scanner application component. The error message is shown in the job output window of the `dast_api` job. A common cause of this issue is changing the `DAST_API_API` variable from its default.
|
||||
|
||||
**Error message**
|
||||
|
||||
- `Failed to start scanner session (version header not found).`
|
||||
|
||||
**Solution**
|
||||
|
||||
- Remove the `DAST_API_API` variable from the `.gitlab-ci.yml` file. The value inherits from the API security testing CI/CD template. We recommend this method instead of manually setting a value.
|
||||
- If removing the variable is not possible, check to see if this value has changed in the latest version of the [API security testing CI/CD template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml). If so, update the value in the `.gitlab-ci.yml` file.
|
||||
|
||||
## `Failed to start session with scanner. Please retry, and if the problem persists reach out to support.`
|
||||
|
||||
The API security testing engine outputs an error message when it cannot establish a connection with the scanner application component. The error message is shown in the job output window of the `dast_api` job. A common cause for this issue is that the background component cannot use the selected port as it's already in use. This error can occur intermittently if timing plays a part (race condition). This issue occurs most often with Kubernetes environments when other services are mapped into the container causing port conflicts.
|
||||
|
||||
Before proceeding with a solution, it is important to confirm that the error message was produced because the port was already taken. To confirm this was the cause:
|
||||
|
||||
1. Go to the job console.
|
||||
|
||||
1. Look for the artifact `gl-api-security-scanner.log`. You can either download all artifacts by selecting **Download** and then search for the file, or directly start searching by selecting **Browse**.
|
||||
|
||||
1. Open the file `gl-api-security-scanner.log` in a text editor.
|
||||
|
||||
1. If the error message was produced because the port was already taken, you should see in the file a message like the following:
|
||||
|
||||
- In [GitLab 15.5 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/367734):
|
||||
|
||||
```log
|
||||
Failed to bind to address http://127.0.0.1:5500: address already in use.
|
||||
```
|
||||
|
||||
- In GitLab 15.4 and earlier:
|
||||
|
||||
```log
|
||||
Failed to bind to address http://[::]:5000: address already in use.
|
||||
```
|
||||
|
||||
The text `http://[::]:5000` in the previous message could be different in your case, for instance it could be `http://[::]:5500` or `http://127.0.0.1:5500`. As long as the remaining parts of the error message are the same, it is safe to assume the port was already taken.
|
||||
|
||||
If you did not find evidence that the port was already taken, check other troubleshooting sections which also address the same error message shown in the job console output. If there are no more options, feel free to [get support or request an improvement](index.md#get-support-or-request-an-improvement) through the proper channels.
|
||||
|
||||
Once you have confirmed the issue was produced because the port was already taken. Then, [GitLab 15.5 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/367734) introduced the configuration variable `DAST_API_API_PORT`. This configuration variable allows setting a fixed port number for the scanner background component.
|
||||
|
||||
**Solution**
|
||||
|
||||
1. Ensure your `.gitlab-ci.yml` file defines the configuration variable `DAST_API_API_PORT`.
|
||||
1. Update the value of `DAST_API_API_PORT` to any available port number greater than 1024. We recommend checking that the new value is not in used by GitLab. See the full list of ports used by GitLab in [Package defaults](../../../administration/package_information/defaults.md#ports)
|
||||
|
||||
## `Application cannot determine the base URL for the target API`
|
||||
|
||||
The API security testing engine outputs an error message when it cannot determine the target API after inspecting the OpenAPI document. This error message is shown when the target API has not been set in the `.gitlab-ci.yml` file, it is not available in the `environment_url.txt` file, and it could not be computed using the OpenAPI document.
|
||||
|
||||
There is a order of precedence in which the API security testing engine tries to get the target API when checking the different sources. First, it tries to use the `DAST_API_TARGET_URL`. If the environment variable has not been set, then the API security testing engine attempts to use the `environment_url.txt` file. If there is no file `environment_url.txt`, then the API security testing engine uses the OpenAPI document contents and the URL provided in `DAST_API_OPENAPI` (if a URL is provided) to try to compute the target API.
|
||||
|
||||
The best-suited solution depends on whether or not your target API changes for each deployment. In static environments, the target API is the same for each deployment, in this case refer to the [static environment solution](#static-environment-solution). If the target API changes for each deployment a [dynamic environment solution](#dynamic-environment-solutions) should be applied.
|
||||
|
||||
## API security testing job excludes some paths from operations
|
||||
|
||||
If you find that some paths are being excluded from operations, ensure that the `consumes` array is defined and has a valid type in the target definition JSON file. This is required.
|
||||
|
||||
See the [example project target definition file](https://gitlab.com/gitlab-org/security-products/demos/api-dast/openapi-example/-/blob/12e2b039d08208f1dd38a1e7c52b0bda848bb449/rest_target_openapi.json?plain=1#L13) where the `consumes` array is defined.
|
||||
|
||||
### Static environment solution
|
||||
|
||||
This solution is for pipelines in which the target API URL doesn't change (is static).
|
||||
|
||||
**Add environmental variable**
|
||||
|
||||
For environments where the target API remains the same, we recommend you specify the target URL by using the `DAST_API_TARGET_URL` environment variable. In your `.gitlab-ci.yml`, add a variable `DAST_API_TARGET_URL`. The variable must be set to the base URL of API testing target. For example:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
DAST_API_OPENAPI: test-api-specification.json
|
||||
```
|
||||
|
||||
### Dynamic environment solutions
|
||||
|
||||
In a dynamic environment your target API changes for each different deployment. In this case, there is more than one possible solution, we recommend you use the `environment_url.txt` file when dealing with dynamic environments.
|
||||
|
||||
**Use environment_url.txt**
|
||||
|
||||
To support dynamic environments in which the target API URL changes during each pipeline, API security testing engine supports the use of an `environment_url.txt` file that contains the URL to use. This file is not checked into the repository, instead it's created during the pipeline by the job that deploys the test target and collected as an artifact that can be used by later jobs in the pipeline. The job that creates the `environment_url.txt` file must run before the API security testing engine job.
|
||||
|
||||
1. Modify the test target deployment job adding the base URL in an `environment_url.txt` file at the root of your project.
|
||||
1. Modify the test target deployment job collecting the `environment_url.txt` as an artifact.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
deploy-test-target:
|
||||
script:
|
||||
# Perform deployment steps
|
||||
# Create environment_url.txt (example)
|
||||
- echo http://${CI_PROJECT_ID}-${CI_ENVIRONMENT_SLUG}.example.org > environment_url.txt
|
||||
|
||||
artifacts:
|
||||
paths:
|
||||
- environment_url.txt
|
||||
```
|
||||
|
||||
## Use OpenAPI with an invalid schema
|
||||
|
||||
There are cases where the document is autogenerated with an invalid schema or cannot be edited manually in a timely manner. In those scenarios, the API security testing is able to perform a relaxed validation by setting the variable `DAST_API_OPENAPI_RELAXED_VALIDATION`. We recommend providing a fully compliant OpenAPI document to prevent unexpected behaviors.
|
||||
|
||||
### Edit a non-compliant OpenAPI file
|
||||
|
||||
To detect and correct elements that don't comply with the OpenAPI specifications, we recommend using an editor. An editor commonly provides document validation, and suggestions to create a schema-compliant OpenAPI document. Suggested editors include:
|
||||
|
||||
| Editor | OpenAPI 2.0 | OpenAPI 3.0.x | OpenAPI 3.1.x |
|
||||
| -- | -- | -- | -- |
|
||||
| [Swagger Editor](https://editor.swagger.io/) | **{check-circle}** YAML, JSON | **{check-circle}** YAML, JSON | **{dotted-circle}** YAML, JSON |
|
||||
| [Stoplight Studio](https://stoplight.io/studio) | **{check-circle}** YAML, JSON | **{check-circle}** YAML, JSON | **{check-circle}** YAML, JSON |
|
||||
|
||||
If your OpenAPI document is generated manually, load your document in the editor and fix anything that is non-compliant. If your document is generated automatically, load it in your editor to identify the issues in the schema, then go to the application and perform the corrections based on the framework you are using.
|
||||
|
||||
### Enable OpenAPI relaxed validation
|
||||
|
||||
Relaxed validation is meant for cases when the OpenAPI document cannot meet OpenAPI specifications, but it still has enough content to be consumed by different tools. A validation is performed but less strictly in regards to document schema.
|
||||
|
||||
API security testing can still try to consume an OpenAPI document that does not fully comply with OpenAPI specifications. To instruct API security testing to perform a relaxed validation, set the variable `DAST_API_OPENAPI_RELAXED_VALIDATION` to any value, for example:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_PROFILE: Quick
|
||||
DAST_API_TARGET_URL: http://test-deployment/
|
||||
DAST_API_OPENAPI: test-api-specification.json
|
||||
DAST_API_OPENAPI_RELAXED_VALIDATION: 'On'
|
||||
```
|
||||
|
||||
## `No operation in the OpenAPI document is consuming any supported media type`
|
||||
|
||||
API security testing uses the specified media types in the OpenAPI document to generate requests. If no request can be created due to the lack of supported media types, then an error is thrown.
|
||||
|
||||
**Error message**
|
||||
|
||||
- `Error, no operation in the OpenApi document is consuming any supported media type. Check 'OpenAPI Specification' to check the supported media types.`
|
||||
|
||||
**Solution**
|
||||
|
||||
1. Review supported media types in the [OpenAPI Specification](configuration/enabling_the_analyzer.md#openapi-specification) section.
|
||||
1. Edit your OpenAPI document, allowing at least a given operation to accept any of the supported media types. Alternatively, a supported media type could be set in the OpenAPI document level and get applied to all operations. This step may require changes in your application to ensure the supported media type is accepted by the application.
|
||||
|
||||
## ``Error, error occurred trying to download `<URL>`: There was an error when retrieving content from Uri:' <URL>'. Error:The SSL connection could not be established, see inner exception.``
|
||||
|
||||
API security testing is compatible with a broad range of TLS configurations, including outdated protocols and ciphers.
|
||||
Despite broad support, you might encounter connection errors. This error occurs because API security testing could not establish a secure connection with the server at the given URL.
|
||||
|
||||
To resolve the issue:
|
||||
|
||||
If the host in the error message supports non-TLS connections, change `https://` to `http://` in your configuration.
|
||||
For example, if an error occurs with the following configuration:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_TARGET_URL: https://test-deployment/
|
||||
DAST_API_OPENAPI: https://specs/openapi.json
|
||||
```
|
||||
|
||||
Change the prefix of `DAST_API_OPENAPI` from `https://` to `http://`:
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- dast
|
||||
|
||||
include:
|
||||
- template: DAST-API.gitlab-ci.yml
|
||||
|
||||
variables:
|
||||
DAST_API_TARGET_URL: https://test-deployment/
|
||||
DAST_API_OPENAPI: http://specs/openapi.json
|
||||
```
|
||||
|
||||
If you cannot use a non-TLS connection to access the URL, contact the Support team for help.
|
||||
|
||||
You can expedite the investigation with the [testssl.sh tool](https://testssl.sh/). From a machine with a bash shell and connectivity to the affected server:
|
||||
|
||||
1. Download the latest release `zip` or `tar.gz` file and extract from <https://github.com/drwetter/testssl.sh/releases>.
|
||||
1. Run `./testssl.sh --log https://specs`.
|
||||
1. Attach the log file to your support ticket.
|
||||
|
||||
## `ERROR: Job failed: failed to pull image`
|
||||
|
||||
This error message occurs when pulling an image from a container registry that requires authentication to access (it is not public).
|
||||
|
||||
In the job console output the error looks like:
|
||||
|
||||
```log
|
||||
Running with gitlab-runner 15.6.0~beta.186.ga889181a (a889181a)
|
||||
on blue-2.shared.runners-manager.gitlab.com/default XxUrkriX
|
||||
Resolving secrets
|
||||
00:00
|
||||
Preparing the "docker+machine" executor
|
||||
00:06
|
||||
Using Docker executor with image registry.gitlab.com/security-products/api-security:2 ...
|
||||
Starting service registry.example.com/my-target-app:latest ...
|
||||
Pulling docker image registry.example.com/my-target-app:latest ...
|
||||
WARNING: Failed to pull image with policy "always": Error response from daemon: Get https://registry.example.com/my-target-app/manifests/latest: unauthorized (manager.go:237:0s)
|
||||
ERROR: Job failed: failed to pull image "registry.example.com/my-target-app:latest" with specified policies [always]: Error response from daemon: Get https://registry.example.com/my-target-app/manifests/latest: unauthorized (manager.go:237:0s)
|
||||
```
|
||||
|
||||
**Error message**
|
||||
|
||||
- In GitLab 15.9 and earlier, `ERROR: Job failed: failed to pull image` followed by `Error response from daemon: Get IMAGE: unauthorized`.
|
||||
|
||||
**Solution**
|
||||
|
||||
Authentication credentials are provided using the methods outlined in the [Access an image from a private container registry](../../../ci/docker/using_docker_images.md#access-an-image-from-a-private-container-registry) documentation section. The method used is dictated by your container registry provider and its configuration. If your using a container registry provided by a 3rd party, such as a cloud provider (Azure, Google Could (GCP), AWS and so on), check the providers documentation for information on how to authenticate to their container registries.
|
||||
|
||||
The following example uses the [statically defined credentials](../../../ci/docker/using_docker_images.md#use-statically-defined-credentials) authentication method. In this example the container registry is `registry.example.com` and image is `my-target-app:latest`.
|
||||
|
||||
1. Read how to [Determine your `DOCKER_AUTH_CONFIG` data](../../../ci/docker/using_docker_images.md#determine-your-docker_auth_config-data) to understand how to compute the variable value for `DOCKER_AUTH_CONFIG`. The configuration variable `DOCKER_AUTH_CONFIG` contains the Docker JSON configuration to provide the appropriate authentication information. For example, to access private container registry: `registry.example.com` with the credentials `abcdefghijklmn`, the Docker JSON looks like:
|
||||
|
||||
```json
|
||||
{
|
||||
"auths": {
|
||||
"registry.example.com": {
|
||||
"auth": "abcdefghijklmn"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Add the `DOCKER_AUTH_CONFIG` as a CI/CD variable. Instead of adding the configuration variable directly in your `.gitlab-ci.yml`file you should create a project [CI/CD variable](../../../ci/variables/index.md#for-a-project).
|
||||
1. Rerun your job, and the statically-defined credentials are now used to sign in to the private container registry `registry.example.com`, and let you pull the image `my-target-app:latest`. If succeeded the job console shows an output like:
|
||||
|
||||
```log
|
||||
Running with gitlab-runner 15.6.0~beta.186.ga889181a (a889181a)
|
||||
on blue-4.shared.runners-manager.gitlab.com/default J2nyww-s
|
||||
Resolving secrets
|
||||
00:00
|
||||
Preparing the "docker+machine" executor
|
||||
00:56
|
||||
Using Docker executor with image registry.gitlab.com/security-products/api-security:2 ...
|
||||
Starting service registry.example.com/my-target-app:latest ...
|
||||
Authenticating with credentials from $DOCKER_AUTH_CONFIG
|
||||
Pulling docker image registry.example.com/my-target-app:latest ...
|
||||
Using docker image sha256:139c39668e5e4417f7d0eb0eeb74145ba862f4f3c24f7c6594ecb2f82dc4ad06 for registry.example.com/my-target-app:latest with digest registry.example.com/my-target-
|
||||
app@sha256:2b69fc7c3627dbd0ebaa17674c264fcd2f2ba21ed9552a472acf8b065d39039c ...
|
||||
Waiting for services to be up and running (timeout 30 seconds)...
|
||||
```
|
||||
|
|
@ -1,24 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/application_information_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# Application information disclosure
|
||||
This document was moved to [another location](../../api_security_testing/checks/application_information_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Application information disclosure check. This includes information such as version numbers, database error messages, stack traces.
|
||||
|
||||
## Remediation
|
||||
|
||||
Application information disclosure is an application weakness where an application reveals sensitive data, such as technical details of the web application or environment. Application data may be used by an attacker to exploit the target web application, its hosting network, or its users. Therefore, leakage of sensitive data should be limited or prevented whenever possible. Information disclosure, in its most common form, is the result of one or more of the following conditions: a failure to scrub out HTML or script comments containing sensitive information or improper application or server configurations.
|
||||
|
||||
Failure to scrub HTML or script comments prior to a push to the production environment can result in the leak of sensitive, contextual, information such as server directory structure, SQL query structure, and internal network information. Often a developer will leave comments within the HTML and script code to help facilitate the debugging or integration process during the pre-production phase. Although there is no harm in allowing developers to include inline comments within the content they develop, these comments should all be removed prior to the content's public release.
|
||||
|
||||
Software version numbers and verbose error messages (such as ASP.NET version numbers) are examples of improper server configurations. This information is useful to an attacker by providing detailed insight as to the framework, languages, or pre-built functions being utilized by a web application. Most default server configurations provide software version numbers and verbose error messages for debugging and troubleshooting purposes. Configuration changes can be made to disable these features, preventing the display of this information.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A05_2021-Security_Misconfiguration)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/200.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,29 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/authentication_token_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# Authentication token
|
||||
This document was moved to [another location](../../api_security_testing/checks/authentication_token_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Perform various authentication token checks such as removing the token or changing to an invalid value.
|
||||
|
||||
## Remediation
|
||||
|
||||
API tokens must be unpredictable (random enough) to prevent guessing attacks, where an attacker is able to guess or predict a valid API Token through statistical analysis techniques. For this purpose, a good PRNG (Pseudo Random Number Generator) must be used.
|
||||
|
||||
The authentication token may have been:
|
||||
|
||||
- modified to an invalid value.
|
||||
- removed from request.
|
||||
- not match length requirements.
|
||||
- configured as a signature.
|
||||
|
||||
An API operation failed to property restrict access using an authentication token. This allows an attacker to bypass authentication gaining access to information or even the ability to modify data.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/285.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,20 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/cleartext_authentication_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# Cleartext authentication
|
||||
This document was moved to [another location](../../api_security_testing/checks/cleartext_authentication_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
This check looks for cleartext authentication such as HTTP Basic auth with no-TLS.
|
||||
|
||||
## Remediation
|
||||
|
||||
Authentication credentials are transported via unencrypted channel (HTTP). This exposes the transmitted credentials to any attacker who can monitor (sniff) the network traffic during transmission. Sensitive information such as credentials should always be transmitted via encrypted channels such as HTTPS.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A02_2021-Cryptographic_Failures)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/319.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,20 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/cors_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# CORS
|
||||
This document was moved to [another location](../../api_security_testing/checks/cors_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Check for CORS misconfiguration including overly permissive white-lists of accepted Origin headers or failure to validate Origin header. Also checks for allowing credentials on potentially invalid or dangerous Origins and missing headers that could potentially result in cache poisoning.
|
||||
|
||||
## Remediation
|
||||
|
||||
A misconfigured CORS implementation may be overly permissive in which domains should be trusted and at what level of trust. This could allow an untrusted domain to forge the Origin header and launch various types of attacks such as cross-site request forgery or cross-site scripting. An attacker could potentially steal a victim's credentials or send malicious requests on behalf of a victim. The victim may not even be aware that an attack is being launched.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/942.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,20 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/dns_rebinding_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# DNS rebinding
|
||||
This document was moved to [another location](../../api_security_testing/checks/dns_rebinding_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Check for DNS rebinding. This check verifies that the host checks that the HOST header of the request exists and matches the expected name of the host to avoid attacks via malicious DNS entries.
|
||||
|
||||
## Remediation
|
||||
|
||||
DNS rebinding allows a malicious host to spoof or redirect a request to an alternate IP address, potentially allowing an attacker to bypass security authentication or authorization. DNS resolution on its own does not properly constitute a valid authentication mechanism. Servers should validate that the Host header of the request matches the expected hostname of the server. In cases where the hostname is missing or does not match the expected value, the server should return a 400. The X-Forwarded-Host header is sometimes used instead of the Host header in cases where the request is being forwarded. In these cases, the X-Forwarded-Host header should also be validated if it is being used to determine the Host of the original request.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A05_2021-Security_Misconfiguration)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/350.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,21 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/framework_debug_mode_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# Framework debug mode
|
||||
This document was moved to [another location](../../api_security_testing/checks/framework_debug_mode_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Checks to see if debug mode is enabled in various frameworks such as Flask and ASP.NET. This check has a low false positive rate.
|
||||
|
||||
## Remediation
|
||||
|
||||
The Flask or ASP .NET framework was identified with debug mode enabled. This allows an attacker the ability to download any file on the file system and other capabilities. This is a high severity issue that is easy for an attacker to exploit.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A05_2021-Security_Misconfiguration)
|
||||
- [CWE-23: Relative Path Traversal](https://cwe.mitre.org/data/definitions/23.html)
|
||||
- [CWE-285: Improper Authorization](https://cwe.mitre.org/data/definitions/285.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,22 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/heartbleed_open_ssl_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# Heartbleed OpenSSL vulnerability
|
||||
This document was moved to [another location](../../api_security_testing/checks/heartbleed_open_ssl_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Check for Heartbleed OpenSSL vulnerability.
|
||||
|
||||
## Remediation
|
||||
|
||||
The Heartbleed vulnerability is a serious bug in the popular OpenSSL cryptographic library. OpenSSL is used to encrypt and decrypt communications and secure the Internet traffic. This vulnerability allows the attacker to steal protected information, which should not be accessible under other circumstance such as secret keys that are used to encrypt sensitive information.
|
||||
|
||||
Anyone on with access to the target API can use the Heartbleed vulnerability to read the memory from protected systems taking advantage of vulnerable versions of OpenSSL library.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A06_2021-Vulnerable_and_Outdated_Components)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/119.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,28 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/html_injection_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# HTML injection
|
||||
This document was moved to [another location](../../api_security_testing/checks/html_injection_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Check for XSS via HTML injection into all fields that support strings. This includes portions of the HTTP request such as path, query, headers and also body parameters such as XML fields, JSON fields, etc. Detection is performed by monitoring responses for the injected value in to known HTML enabled fields.
|
||||
|
||||
## Remediation
|
||||
|
||||
Cross-site scripting (XSS) is an attack technique that involves echoing attacker-supplied code into a user's browser instance. A browser instance can be a standard web browser client, or a browser object embedded in a software product such as the browser within WinAmp, an RSS reader, or an email client. The code itself is usually written in HTML/JavaScript, but may also extend to VBScript, ActiveX, Java, Flash, or any other browser-supported technology.
|
||||
|
||||
When an attacker gets a user's browser to execute his/her code, the code will run within the security context (or zone) of the hosting web site. With this level of privilege, the code has the ability to read, modify and transmit any sensitive data accessible by the browser. A Cross-site Scripted user could have his/her account hijacked (cookie theft), their browser redirected to another location, or possibly shown fraudulent content delivered by the web site they are visiting. Cross-site Scripting attacks essentially compromise the trust relationship between a user and the web site. Applications utilizing browser object instances which load content from the file system may execute code under the local machine zone allowing for system compromise.
|
||||
|
||||
There are three types of Cross-site Scripting attacks: non-persistent, persistent and DOM-based.
|
||||
|
||||
Non-persistent attacks and DOM-based attacks require a user to either visit a specially crafted link laced with malicious code, or visit a malicious web page containing a web form, which when posted to the vulnerable site, will mount the attack. Using a malicious form will oftentimes take place when the vulnerable resource only accepts HTTP POST requests. In such a case, the form can be submitted automatically, without the victim's knowledge (e.g. by using JavaScript). Upon clicking on the malicious link or submitting the malicious form, the XSS payload will get echoed back and will get interpreted by the user's browser and execute. Another technique to send almost arbitrary requests (GET and POST) is by using an embedded client, such as Adobe Flash.
|
||||
|
||||
Persistent attacks occur when the malicious code is submitted to a web site where it's stored for a period of time. Examples of an attacker's favorite targets often include message board posts, web mail messages, and web chat software. The unsuspecting user is not required to interact with any additional site/link (e.g. an attacker site or a malicious link sent via email), just simply view the web page containing the code.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A03_2021-Injection)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/79.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,140 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/index.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# API security testing vulnerability checks
|
||||
This document was moved to [another location](../../api_security_testing/checks/index.md).
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate
|
||||
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
|
||||
|
||||
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/457449) from **DAST API vulnerability checks** to **API security testing vulnerability checks** in GitLab 17.0.
|
||||
|
||||
[API security testing](../index.md) provides vulnerability checks that are used to
|
||||
scan for vulnerabilities in the API under test.
|
||||
|
||||
## Passive checks
|
||||
|
||||
| Check | Severity | Type | Profiles |
|
||||
|:-----------------------------------------------------------------------------|:---------|:--------|:---------|
|
||||
| [Application information check](application_information_check.md) | Medium | Passive | Passive, Passive-Quick, Active-Quick, Active Full, Quick, Full |
|
||||
| [Cleartext authentication check](cleartext_authentication_check.md) | High | Passive | Passive, Passive-Quick, Active-Quick, Active Full, Quick, Full |
|
||||
| [JSON hijacking](json_hijacking_check.md) | Medium | Passive | Passive, Passive-Quick, Active-Quick, Active Full, Quick, Full |
|
||||
| [Sensitive information](sensitive_information_disclosure_check.md) | High | Passive | Passive, Passive-Quick, Active-Quick, Active Full, Quick, Full |
|
||||
| [Session cookie](session_cookie_check.md) | Medium | Passive | Passive, Passive-Quick, Active-Quick, Active Full, Quick, Full |
|
||||
|
||||
## Active checks
|
||||
|
||||
| Check | Severity | Type | Profiles |
|
||||
|:-----------------------------------------------------------------------------|:---------|:--------|:---------|
|
||||
| [CORS](cors_check.md) | Medium | Active | Active Full, Full |
|
||||
| [DNS rebinding](dns_rebinding_check.md) | Medium | Active | Active Full, Full |
|
||||
| [Framework debug mode](framework_debug_mode_check.md) | High | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [Heartbleed OpenSSL vulnerability](heartbleed_open_ssl_check.md) | High | Active | Active Full, Full |
|
||||
| [HTML injection check](html_injection_check.md) | Medium | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [Insecure HTTP methods](insecure_http_methods_check.md) | Medium | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [JSON injection](json_injection_check.md) | Medium | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [Open redirect](open_redirect_check.md) | Medium | Active | Active Full, Full |
|
||||
| [OS command injection](os_command_injection_check.md) | High | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [Path traversal](path_traversal_check.md) | High | Active | Active Full, Full |
|
||||
| [Sensitive file](sensitive_file_disclosure_check.md) | Medium | Active | Active Full, Full |
|
||||
| [Shellshock](shellshock_check.md) | High | Active | Active Full, Full |
|
||||
| [SQL injection](sql_injection_check.md) | High | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [TLS configuration](tls_server_configuration_check.md) | High | Active | Active Full, Full |
|
||||
| [Authentication token](authentication_token_check.md) | High | Active | Active-Quick, Active Full, Quick, Full |
|
||||
| [XML external entity](xml_external_entity.md) | High | Active | Active Full, Full |
|
||||
| [XML injection](xml_injection_check.md) | Medium | Active | Active-Quick, Active Full, Quick, Full |
|
||||
|
||||
## API security testing checks by profile
|
||||
|
||||
### Passive-Quick
|
||||
|
||||
- [Application information check](application_information_check.md)
|
||||
- [Cleartext authentication check](cleartext_authentication_check.md)
|
||||
- [JSON hijacking](json_hijacking_check.md)
|
||||
- [Sensitive information](sensitive_information_disclosure_check.md)
|
||||
- [Session cookie](session_cookie_check.md)
|
||||
|
||||
### Active-Quick
|
||||
|
||||
- [Application information check](application_information_check.md)
|
||||
- [Cleartext authentication check](cleartext_authentication_check.md)
|
||||
- [Framework debug mode](framework_debug_mode_check.md)
|
||||
- [HTML injection check](html_injection_check.md)
|
||||
- [Insecure HTTP methods](insecure_http_methods_check.md)
|
||||
- [JSON hijacking](json_hijacking_check.md)
|
||||
- [JSON injection](json_injection_check.md)
|
||||
- [OS command injection](os_command_injection_check.md)
|
||||
- [Sensitive information](sensitive_information_disclosure_check.md)
|
||||
- [Session cookie](session_cookie_check.md)
|
||||
- [SQL injection](sql_injection_check.md)
|
||||
- [Authentication token](authentication_token_check.md)
|
||||
- [XML injection](xml_injection_check.md)
|
||||
|
||||
### Active-Full
|
||||
|
||||
- [Application information check](application_information_check.md)
|
||||
- [Cleartext authentication check](cleartext_authentication_check.md)
|
||||
- [CORS](cors_check.md)
|
||||
- [DNS rebinding](dns_rebinding_check.md)
|
||||
- [Framework debug mode](framework_debug_mode_check.md)
|
||||
- [Heartbleed OpenSSL vulnerability](heartbleed_open_ssl_check.md)
|
||||
- [HTML injection check](html_injection_check.md)
|
||||
- [Insecure HTTP methods](insecure_http_methods_check.md)
|
||||
- [JSON hijacking](json_hijacking_check.md)
|
||||
- [JSON injection](json_injection_check.md)
|
||||
- [Open redirect](open_redirect_check.md)
|
||||
- [OS command injection](os_command_injection_check.md)
|
||||
- [Path traversal](path_traversal_check.md)
|
||||
- [Sensitive file](sensitive_file_disclosure_check.md)
|
||||
- [Sensitive information](sensitive_information_disclosure_check.md)
|
||||
- [Session cookie](session_cookie_check.md)
|
||||
- [Shellshock](shellshock_check.md)
|
||||
- [SQL injection](sql_injection_check.md)
|
||||
- [TLS configuration](tls_server_configuration_check.md)
|
||||
- [Authentication token](authentication_token_check.md)
|
||||
- [XML injection](xml_injection_check.md)
|
||||
- [XML external entity](xml_external_entity.md)
|
||||
|
||||
### Quick
|
||||
|
||||
- [Application information check](application_information_check.md)
|
||||
- [Cleartext authentication check](cleartext_authentication_check.md)
|
||||
- [Framework debug mode](framework_debug_mode_check.md)
|
||||
- [HTML injection check](html_injection_check.md)
|
||||
- [Insecure HTTP methods](insecure_http_methods_check.md)
|
||||
- [JSON hijacking](json_hijacking_check.md)
|
||||
- [JSON injection](json_injection_check.md)
|
||||
- [OS command injection](os_command_injection_check.md)
|
||||
- [Sensitive information](sensitive_information_disclosure_check.md)
|
||||
- [Session cookie](session_cookie_check.md)
|
||||
- [SQL injection](sql_injection_check.md)
|
||||
- [Authentication token](authentication_token_check.md)
|
||||
- [XML injection](xml_injection_check.md)
|
||||
|
||||
### Full
|
||||
|
||||
- [Application information check](application_information_check.md)
|
||||
- [Cleartext authentication check](cleartext_authentication_check.md)
|
||||
- [CORS](cors_check.md)
|
||||
- [DNS rebinding](dns_rebinding_check.md)
|
||||
- [Framework debug mode](framework_debug_mode_check.md)
|
||||
- [Heartbleed OpenSSL vulnerability](heartbleed_open_ssl_check.md)
|
||||
- [HTML injection check](html_injection_check.md)
|
||||
- [Insecure HTTP methods](insecure_http_methods_check.md)
|
||||
- [JSON hijacking](json_hijacking_check.md)
|
||||
- [JSON injection](json_injection_check.md)
|
||||
- [Open redirect](open_redirect_check.md)
|
||||
- [OS command injection](os_command_injection_check.md)
|
||||
- [Path traversal](path_traversal_check.md)
|
||||
- [Sensitive file](sensitive_file_disclosure_check.md)
|
||||
- [Sensitive information](sensitive_information_disclosure_check.md)
|
||||
- [Session cookie](session_cookie_check.md)
|
||||
- [Shellshock](shellshock_check.md)
|
||||
- [SQL injection](sql_injection_check.md)
|
||||
- [TLS configuration](tls_server_configuration_check.md)
|
||||
- [Authentication token](authentication_token_check.md)
|
||||
- [XML injection](xml_injection_check.md)
|
||||
- [XML external entity](xml_external_entity.md)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
|
|||
|
|
@ -1,22 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/insecure_http_methods_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# Insecure HTTP methods
|
||||
This document was moved to [another location](../../api_security_testing/configuration/insecure_http_methods_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Checks to see if HTTP methods like OPTIONS and TRACE are enabled on any target endpoints.
|
||||
|
||||
## Remediation
|
||||
|
||||
The resource tested supports the OPTIONS HTTP method. Normally this is considered a security miss configuration as it leaks supported HTTP methods leading to information gathering about a specific server or resource. However, there is a sub-set of the API community looking to use OPTIONS as a method to self discover resource operations. If this is the intended use for enabling OPTIONS, than this issue can be considered a false positive.
|
||||
|
||||
The resource tested supports the TRACE HTTP method. In combination with other cross-domain vulnerabilities in web browsers, sensitive information can be leaked from headers. It's recommended the TRACE method be disabled in your server/framework.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A05_2021-Security_Misconfiguration)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/200.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,20 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/json_hijacking_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# JSON hijacking
|
||||
This document was moved to [another location](../../api_security_testing/checks/json_hijacking_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Checks for JSON data potentially vulnerable to hijacking. This check looks for a GET request that returns a JSON array, which could potentially be hijacked and read by a malicious website.
|
||||
|
||||
## Remediation
|
||||
|
||||
JSON hijacking allows an attacker to send a GET request via a malicious web site or similar attack vector and utilize a user's stored credentials to retrieve sensitive or protected data to which that user has access. Since a JSON array on its own is valid JavaScript, a malicious GET request to a resource that returns only a JavaScript array can allow the attacker to use a malicious script to read the data in the array from the request. GET requests should never return a JSON array, even if the resource requires authentication to access. Consider using POST instead of a GET for this request or wrapping the array in a JSON object.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/352.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,20 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/json_injection_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# JSON injection
|
||||
This document was moved to [another location](../../api_security_testing/checks/json_injection_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Check for JSON serialization/injection vulnerabilities.
|
||||
|
||||
## Remediation
|
||||
|
||||
JSON injection is an attack technique used to manipulate or compromise the logic of a JSON application or service. The injection of unintended JSON content and/or structures into an JSON message can alter the intend logic of the application. Further, JSON injection can cause the insertion of malicious content into the resulting message/document.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A03_2021-Injection)
|
||||
- [CWE](CWE-929: OWASP Top Ten 2013 Category A1 - Injection)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,20 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/open_redirect_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# Open redirect
|
||||
This document was moved to [another location](../../api_security_testing/checks/open_redirect_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Identify open redirects and determine if they can be abused by attackers.
|
||||
|
||||
## Remediation
|
||||
|
||||
Unvalidated redirects and forwards are possible when a web application accepts untrusted input that could cause the web application to redirect the request to a URL contained within untrusted input. By modifying untrusted URL input to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials. Because the server name in the modified link is identical to the original site, phishing attempts may have a more trustworthy appearance. Unvalidated redirect and forward attacks can also be used to maliciously craft a URL that would pass the application’s access control check and then forward the attacker to privileged functions that they would normally not be able to access.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/601.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,32 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/os_command_injection_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# OS command injection
|
||||
This document was moved to [another location](../../api_security_testing/checks/os_command_injection_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Check for OS command injection vulnerabilities. An OS command injection attack consists of insertion or "injection" of an OS command via the input data from the client to the application.
|
||||
A successful OS command injection exploit can run arbitrary commands. This allows an attacker the ability to read, write, and delete data. Depending on the user the commands run as, this can also include administrative functions.
|
||||
|
||||
This check modifies parameters in the request (path, query string, headers, JSON, XML, etc.) to try and execute an OS command. Both standard injections and blind injections are performed. Blind injections cause delays in response when successful.
|
||||
|
||||
## Remediation
|
||||
|
||||
It is possible to execute arbitrary OS commands on the target application server. OS Command Injection is a critical vulnerability that can lead to a full system compromise. User input should never be used in constructing commands or command arguments to functions which execute OS commands. This includes filenames supplied by user uploads or downloads.
|
||||
|
||||
Ensure your application does not:
|
||||
|
||||
- Use user supplied information in the process name to execute.
|
||||
- Use user supplied information in an OS command execution function which does
|
||||
not escape shell meta-characters.
|
||||
- Use user supplied information in arguments to OS commands.
|
||||
|
||||
The application should have a hardcoded set of arguments that are to be passed to OS commands. If filenames are being passed to these functions, it is recommended that a hash of the filename be used instead, or some other unique identifier. It is strongly recommended that a native library that implements the same functionality be used instead of using OS system commands due to the risk of unknown attacks against third party commands.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A03_2021-Injection)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/78.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
|
|
@ -1,30 +1,11 @@
|
|||
---
|
||||
stage: Secure
|
||||
group: Dynamic Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
redirect_to: '../../api_security_testing/checks/path_traversal_check.md'
|
||||
remove_date: '2024-07-30'
|
||||
---
|
||||
|
||||
# Path traversal
|
||||
This document was moved to [another location](../../api_security_testing/checks/path_traversal_check.md).
|
||||
|
||||
## Description
|
||||
|
||||
Many file operations are intended to take place within a restricted directory. By using special elements such as ".." and "/" separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the "../" sequence, which in most modern operating systems is interpreted as the parent directory of the current location. This is referred to as relative path traversal. Path traversal also covers the use of absolute path-names such as "/usr/local/bin", which may also be useful in accessing unexpected files. This is referred to as absolute path traversal.
|
||||
|
||||
In many programming languages, the injection of a null byte(the 0 or NUL) may allow an attacker to truncate a generated filename to widen the scope of attack. For example, the software may add ".txt" to any pathname, thus limiting the attacker to text files, but a null injection may effectively remove this restriction.
|
||||
|
||||
This check modifies parameters in the request (path, query string, headers, JSON, XML, etc.) to try and access restricted files and files outside of the web-root. Logs and responses are then analyzed to try and detect if the file was successfully accessed.
|
||||
|
||||
## Remediation
|
||||
|
||||
The Path traversal attack technique allows an attacker access to files, directories, and commands that potentially reside outside the web document root directory. An attacker may manipulate a URL in such a way that the web site will execute or reveal the contents of arbitrary files anywhere on the web server. Any device that exposes an HTTP-based interface is potentially vulnerable to Path traversal.
|
||||
|
||||
Most web sites restrict user access to a specific portion of the file-system, typically called the “web document root” or “CGI root” directory. These directories contain the files intended for user access and the executable necessary to drive web application functionality. To access files or execute commands anywhere on the file-system, Path traversal attacks will utilize the ability of special-characters sequences.
|
||||
|
||||
The most basic Path traversal attack uses the “../” special-character sequence to alter the resource location requested in the URL. Although most popular web servers will prevent this technique from escaping the web document root, alternate encodings of the "../" sequence may help bypass the security filters. These method variations include valid and invalid Unicode-encoding ("..%u2216" or "..%c0%af") of the forward slash character, backslash characters ("..") on Windows-based servers, URL encoded characters "%2e%2e%2f"), and double URL encoding ("..%255c") of the backslash character.
|
||||
|
||||
Even if the web server properly restricts Path traversal attempts in the URL path, a web application itself may still be vulnerable due to improper handling of user-supplied input. This is a common problem of web applications that use template mechanisms or load static text from files. In variations of the attack, the original URL parameter value is substituted with the file name of one of the web application's dynamic scripts. Consequently, the results can reveal source code because the file is interpreted as text instead of an executable script. These techniques often employ additional special characters such as the dot (".") to reveal the listing of the current working directory, or “%00” NULL characters in order to bypass rudimentary file extension checks.
|
||||
|
||||
## Links
|
||||
|
||||
- [OWASP](https://owasp.org/Top10/A01_2021-Broken_Access_Control)
|
||||
- [CWE](https://cwe.mitre.org/data/definitions/22.html)
|
||||
<!-- This redirect file can be deleted after <2024-07-30>. -->
|
||||
<!-- Redirects that point to other docs in the same project expire in three months. -->
|
||||
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
|
||||
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue