[{"data":1,"prerenderedAt":1727},["ShallowReactive",2],{"/blog/how-to-configure-dast-full-scans-for-complex-web-applications":3,"navigation-en-us":942,"banner-en-us":1369,"footer-en-us":1379,"blog-post-authors-en-us-Dennis Appelt":1624,"blog-related-posts-en-us-how-to-configure-dast-full-scans-for-complex-web-applications":1639,"blog-promotions-en-us":1664,"next-steps-en-us":1717},{"id":4,"title":5,"authors":6,"body":8,"category":922,"date":923,"description":924,"extension":925,"externalUrl":926,"faq":926,"featured":927,"heroImage":928,"meta":929,"navigation":112,"path":930,"seo":931,"slug":935,"stem":936,"tags":937,"template":940,"updatedDate":926,"__hash__":941},"blogPosts/en-us/blog/how-to-configure-dast-full-scans-for-complex-web-applications.md","How to configure DAST full scans for complex web applications",[7],"Dennis Appelt",{"type":9,"value":10,"toc":911},"minimark",[11,22,25,47,56,61,69,177,210,213,217,220,226,229,250,258,261,266,269,277,292,300,319,331,335,338,354,375,379,382,397,432,512,519,528,532,535,541,548,555,571,576,582,588,604,608,611,793,814,817,830,841,874,878,881,890,893,907],[12,13,14,15,21],"p",{},"Shifting ",[16,17,20],"a",{"href":18,"rel":19},"https://docs.gitlab.com/user/application_security/dast/",[],"Dynamic Application Security Testing"," (DAST) left can help to detect security vulnerabilities earlier in the software development lifecycle (SDLC). However, testing earlier and more often in the SDLC comes with its own set of challenges: an abundance of alerts from automated security tools and a high computational cost caused by frequent and long-running CI security jobs.",[12,23,24],{},"In this blog post, I’ll walk you through how we configured DAST for the internal pipeline that tests the GitLab web application. We’ll discuss some of the common challenges that you might encounter when testing large applications, such as:",[26,27,28,38],"ol",{},[29,30,31,32,37],"li",{},"How to keep the duration of the DAST scan within an acceptable ",[16,33,36],{"href":34,"rel":35},"https://docs.gitlab.com/ci/pipelines/settings/#timeout",[],"job timeout",": This matters because jobs that exceed timeouts will fail and no results will be displayed. We will review how to optimize scan duration by excluding low-risk parts of the application from being tested, by correctly seeding your application with test data, and by parallelizing the DAST job.",[29,39,40,41,46],{},"How to get relevant results for your context: This is key – tuning job configurations to produce relevant results allows your engineers to focus on findings that matter and prevents ",[16,42,45],{"href":43,"rel":44},"https://en.wikipedia.org/wiki/Alarm_fatigue",[],"alert fatigue",". In this area, we'll discuss criteria for identifing rules that are applicable to your application and we will explain how to disable irrelevant rules.",[12,48,49,50,55],{},"The discussed solutions are based on the DAST configuration that we use to test GitLab itself. If you are looking for inspiration on how to configure your own DAST jobs, feel free to take a look at our ",[16,51,54],{"href":52,"rel":53},"https://gitlab.com/gitlab-org/gitlab/-/blob/8b1557c02fe5519ba952ea59c93b84912dd357b4/.gitlab/ci/dast.gitlab-ci.yml",[],"configuration",".",[57,58,60],"h2",{"id":59},"how-to-set-up-a-simple-dast-full-scan","How to set up a simple DAST full scan",[12,62,63,64,68],{},"Kicking off a DAST full scan in GitLab CI is as easy as including the job template and setting a few variables in your ",[65,66,67],"code",{},".gitlab-ci.yml"," file:",[70,71,76],"pre",{"className":72,"code":73,"language":74,"meta":75,"style":75},"language-yaml shiki shiki-themes github-light","include:\n  - template: DAST.gitlab-ci.yml\n\nvariables:\n  DAST_WEBSITE: \"https://my-site.example\"\n  DAST_FULL_SCAN_ENABLED: \"true\"\n  DAST_AUTH_URL: \"https://my-site.example/signin\"\n  DAST_AUTH_USERNAME: “john”\n  DAST_AUTH_PASSWORD: “P@ssw0rd”\n\n","yaml","",[65,77,78,91,107,114,122,133,144,155,166],{"__ignoreMap":75},[79,80,83,87],"span",{"class":81,"line":82},"line",1,[79,84,86],{"class":85},"shJU0","include",[79,88,90],{"class":89},"sgsFI",":\n",[79,92,94,97,100,103],{"class":81,"line":93},2,[79,95,96],{"class":89},"  - ",[79,98,99],{"class":85},"template",[79,101,102],{"class":89},": ",[79,104,106],{"class":105},"sYBdl","DAST.gitlab-ci.yml\n",[79,108,110],{"class":81,"line":109},3,[79,111,113],{"emptyLinePlaceholder":112},true,"\n",[79,115,117,120],{"class":81,"line":116},4,[79,118,119],{"class":85},"variables",[79,121,90],{"class":89},[79,123,125,128,130],{"class":81,"line":124},5,[79,126,127],{"class":85},"  DAST_WEBSITE",[79,129,102],{"class":89},[79,131,132],{"class":105},"\"https://my-site.example\"\n",[79,134,136,139,141],{"class":81,"line":135},6,[79,137,138],{"class":85},"  DAST_FULL_SCAN_ENABLED",[79,140,102],{"class":89},[79,142,143],{"class":105},"\"true\"\n",[79,145,147,150,152],{"class":81,"line":146},7,[79,148,149],{"class":85},"  DAST_AUTH_URL",[79,151,102],{"class":89},[79,153,154],{"class":105},"\"https://my-site.example/signin\"\n",[79,156,158,161,163],{"class":81,"line":157},8,[79,159,160],{"class":85},"  DAST_AUTH_USERNAME",[79,162,102],{"class":89},[79,164,165],{"class":105},"“john”\n",[79,167,169,172,174],{"class":81,"line":168},9,[79,170,171],{"class":85},"  DAST_AUTH_PASSWORD",[79,173,102],{"class":89},[79,175,176],{"class":105},"“P@ssw0rd”\n",[12,178,179,180,183,184,187,188,193,194,199,200,203,204,209],{},"The variable ",[65,181,182],{},"DAST_WEBSITE"," defines the target website tested by DAST. Setting ",[65,185,186],{},"DAST_FULL_SCAN_ENABLED: true"," instructs DAST to run a ",[16,189,192],{"href":190,"rel":191},"https://www.zaproxy.org/docs/docker/full-scan/",[],"full scan",", which is more comprehensive than a ",[16,195,198],{"href":196,"rel":197},"https://www.zaproxy.org/docs/docker/baseline-scan/",[],"baseline scan"," and potentially finds more vulnerabilities. There are also other config options that you likely want to define such as authentication-related options (",[65,201,202],{},"DAST_AUTH_*",") which are not discussed here. You can check out our DAST ",[16,205,208],{"href":206,"rel":207},"https://docs.gitlab.com/user/application_security/dast/#available-variables",[],"user docs"," for a refresher on these config options.",[12,211,212],{},"When running a DAST full scan against a web application with many pages and input parameters, it is possible that the DAST job will not finish testing the application within the CI job timeout and fail. If this is the case for your DAST job, keep reading to learn about tweaking your job configuration to stay within the timeout.",[57,214,216],{"id":215},"how-to-optimize-dast-scan-duration","How to optimize DAST scan duration",[12,218,219],{},"It is not uncommon that a DAST full scan can take 10 or more hours to complete testing in complex applications. To understand how we can reduce the scan duration, we need to take a closer look at how DAST works internally.",[12,221,222,223,225],{},"DAST job execution is roughly separated into two phases: A spidering phase and a test execution phase. A DAST job starts with spidering, during which it will detect all pages a web application consists of and identify the input parameters on these pages. The spider recursively discovers all pages of an application by visiting the configured target URL (parameter ",[65,224,182],{},") and by following all URLs found in the page source. These URLs are in turn also searched for URLs in their page source, any new URLs are followed and so on. In a DAST full scan, this procedure is typically repeated until all discovered URLs have been visited.",[12,227,228],{},"In the test execution phase, test rules are executed against the target application to find vulnerabilities. Most of the rules are executed for any of the discovered pages in the spidering phase, leading to a direct relation between the number of executed test cases and the number of discovered pages.",[12,230,231,232,237,238,243,244,249],{},"Some rules check for specific CVEs such as ",[16,233,236],{"href":234,"rel":235},"https://www.zaproxy.org/docs/alerts/20015/",[],"Heartbleed"," while others are only applicable to applications written in specific languages such as ",[16,239,242],{"href":240,"rel":241},"https://www.zaproxy.org/docs/alerts/90002/",[],"Java",", ",[16,245,248],{"href":246,"rel":247},"https://www.zaproxy.org/docs/alerts/10061/",[],"ASP.net",", and so on. A DAST full scan will, by default, execute all rules even if the target application’s tech stack is not affected by the vulnerability being tested for.",[12,251,252,253,257],{},"To summarize, you can use the following rule of thumb to estimate a DAST job’s scan duration: Number of Tested Pages ",[254,255,256],"strong",{},"x"," Number of Executed Rules.",[12,259,260],{},"To optimize scan duration, we will have to tweak these factors.",[262,263,265],"h3",{"id":264},"how-to-reduce-the-number-of-tested-pages","How to reduce the number of tested pages",[12,267,268],{},"To understand which pages of our application are tested we can refer to the job log. The URLs of all tested pages are listed like in the example below.",[70,270,275],{"className":271,"code":273,"language":274,"meta":75},[272],"language-text","2020-08-01 00:25:34,454 The following 2903 URLs were scanned:\nGET https://gitlab-review.app\nGET https://gitlab-review.app/*/*.git\nGET https://gitlab-review.app/help\nGET https://gitlab.com/help/user/index.md\n...\n","text",[65,276,273],{"__ignoreMap":75},[12,278,279,280,285,286,291],{},"Based on this information we can exclude low-risk pages from being tested. For example, for the GitLab web app we decided to ",[16,281,284],{"href":282,"rel":283},"https://gitlab.com/gitlab-org/gitlab/-/blob/8b1557c02fe5519ba952ea59c93b84912dd357b4/.gitlab/ci/dast.gitlab-ci.yml#L30",[],"exclude"," any of the ",[16,287,290],{"href":288,"rel":289},"https://gitlab.com/help",[],"help pages",". These pages are mostly static and the application code doesn’t process any user-controlled inputs, which rules out attack categories like SQL injection, XSS etc. Excluding these led to 899 URLs less being spidered and tested, reducing the scan duration significantly.",[12,293,294,295,299],{},"To exclude low-risk pages from being tested, you can use the environment variable ",[16,296,298],{"href":206,"rel":297},[],"DAST_AUTH_EXCLUDE_URLS"," as mapped out below:",[70,301,303],{"className":72,"code":302,"language":74,"meta":75,"style":75},"script:\n  - 'export DAST_AUTH_EXCLUDE_URLS=\"https://gitlab-review.app/help/.*,https://gitlab-review.app/profile/two_factor_auth\"'\n\n",[65,304,305,312],{"__ignoreMap":75},[79,306,307,310],{"class":81,"line":82},[79,308,309],{"class":85},"script",[79,311,90],{"class":89},[79,313,314,316],{"class":81,"line":93},[79,315,96],{"class":89},[79,317,318],{"class":105},"'export DAST_AUTH_EXCLUDE_URLS=\"https://gitlab-review.app/help/.*,https://gitlab-review.app/profile/two_factor_auth\"'\n",[12,320,321,323,324,327,328,55],{},[65,322,298],{}," takes a comma-separated list of URLs to exclude. URLs can contain regular expressions, e.g. ",[65,325,326],{},"https://gitlab-review.app/help/.*"," will exclude any URL that starts with ",[65,329,330],{},"https://gitlab-review.app/help/",[262,332,334],{"id":333},"how-to-populate-your-app-with-test-data","How to populate your app with test data",[12,336,337],{},"Populating your application with test data is important because it allows DAST to discover and test all the functionality of your application. At the same time, you want to avoid adding redundant test data to your application, which would lead to DAST exercising the same code repeatedly.",[12,339,340,341,346,347,243,350,353],{},"For example, we can create multiple ",[16,342,345],{"href":343,"rel":344},"https://docs.gitlab.com/user/project/",[],"projects"," in a GitLab instance and each project will be accessible via a unique URL, e.g. ",[65,348,349],{},"https://gitlab.example/awesome-project",[65,351,352],{},"https://gitlab.example/another-project",", etc. To DAST these look like unrelated pages and it will test each page separately. However, the application code that is processing requests to different projects is largely identical, leading to the same code being tested multiple times. This increases the scan duration and is unlikely to identify more vulnerabilities than testing only a single project would.",[12,355,356,357,362,363,368,369,374],{},"In every pipeline that runs DAST against GitLab, we spin up a fresh GitLab instance as a ",[16,358,361],{"href":359,"rel":360},"https://docs.gitlab.com/ci/review_apps/",[],"review app"," and populate it with the test data that we need for the DAST job. If you are looking for a similar solution, you might find the job that is ",[16,364,367],{"href":365,"rel":366},"https://gitlab.com/gitlab-org/gitlab/-/blob/8b1557c02fe5519ba952ea59c93b84912dd357b4/.gitlab/ci/review.gitlab-ci.yml#L53-83",[],"deploying the review app"," and seeding it with ",[16,370,373],{"href":371,"rel":372},"https://gitlab.com/gitlab-org/gitlab/-/blob/8b1557c02fe5519ba952ea59c93b84912dd357b4/.gitlab/ci/review.gitlab-ci.yml#L83",[],"test data"," interesting.",[262,376,378],{"id":377},"identifying-relevant-rules-for-your-dast-scan","Identifying relevant rules for your DAST scan",[12,380,381],{},"As mentioned above, a DAST full scan runs, by default, all rules against any discovered page. Therefore, another way to reduce scan duration is to disable irrelevant rules or rules that you have determined are low-risk for your application context. To determine rule relevance, consider the following:",[383,384,385,388,391,394],"ul",{},[29,386,387],{},"Does the rule apply to my web framework?",[29,389,390],{},"Does the rule apply to my web server?",[29,392,393],{},"Does the rule apply to my database server?",[29,395,396],{},"Does the type of vulnerability a rule tests for apply to my application?",[12,398,399,400,404,405,243,410,243,414,419,420,425,426,431],{},"For example, if your application is not built with Java, rules that test for ",[16,401,403],{"href":240,"rel":402},[],"Java-specific vulnerabilities"," can be disabled. There are many rules that are specific to a web framework, server, or database being used like ",[16,406,409],{"href":407,"rel":408},"https://www.zaproxy.org/docs/alerts/10053/",[],"Apache HTTP Server",[16,411,413],{"href":246,"rel":412},[],"ASP.NET",[16,415,418],{"href":416,"rel":417},"https://www.zaproxy.org/docs/alerts/40022/",[],"PostgreSQL"," etc. If in doubt around which rule(s) are applicable to which tech stack, you can find the information either in the ",[16,421,424],{"href":422,"rel":423},"https://www.zaproxy.org/docs/alerts/",[],"ZAP user docs"," or directly in the ",[16,427,430],{"href":428,"rel":429},"https://github.com/zaproxy/zap-extensions/blob/master/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/CodeInjectionScanRule.java#L86-L91",[],"rule implementation",":",[70,433,437],{"className":434,"code":435,"language":436,"meta":75,"style":75},"language-java shiki shiki-themes github-light","public boolean targets(TechSet technologies) {\n    if (technologies.includes(Tech.ASP) || technologies.includes(Tech.PHP)) {\n        return true;\n    }\n    return false;\n}\n","java",[65,438,439,455,480,492,497,507],{"__ignoreMap":75},[79,440,441,445,448,452],{"class":81,"line":82},[79,442,444],{"class":443},"sD7c4","public",[79,446,447],{"class":443}," boolean",[79,449,451],{"class":450},"s7eDp"," targets",[79,453,454],{"class":89},"(TechSet technologies) {\n",[79,456,457,460,463,466,469,472,475,477],{"class":81,"line":93},[79,458,459],{"class":443},"    if",[79,461,462],{"class":89}," (technologies.",[79,464,465],{"class":450},"includes",[79,467,468],{"class":89},"(Tech.ASP) ",[79,470,471],{"class":443},"||",[79,473,474],{"class":89}," technologies.",[79,476,465],{"class":450},[79,478,479],{"class":89},"(Tech.PHP)) {\n",[79,481,482,485,489],{"class":81,"line":109},[79,483,484],{"class":443},"        return",[79,486,488],{"class":487},"sYu0t"," true",[79,490,491],{"class":89},";\n",[79,493,494],{"class":81,"line":116},[79,495,496],{"class":89},"    }\n",[79,498,499,502,505],{"class":81,"line":124},[79,500,501],{"class":443},"    return",[79,503,504],{"class":487}," false",[79,506,491],{"class":89},[79,508,509],{"class":81,"line":135},[79,510,511],{"class":89},"}\n",[12,513,514,515,518],{},"Note: Most rules classes have a function ",[65,516,517],{},"targets"," that defines to which technologies a rule is applicable.",[12,520,521,522,527],{},"Another example of a rule that might not apply to your application is the ",[16,523,526],{"href":524,"rel":525},"https://www.zaproxy.org/docs/alerts/10062/",[],"PII Disclosure"," rule if your application does not process any PII.",[262,529,531],{"id":530},"excluding-irrelevant-rules","Excluding irrelevant rules",[12,533,534],{},"The execution time of individual rules varies substantially. To understand how much time a particular rule adds to the total scan duration and how much we could gain from disabling it, we turn again to the job log. Each rule prints its duration on completion, for example:",[70,536,539],{"className":537,"code":538,"language":274,"meta":75},[272],"[zap.out] 3937350 [Thread-8] INFO org.parosproxy.paros.core.scanner.HostProcess - completed host/plugin https://gitlab-review.app | TestExternalRedirect in 2813.043s with 33151 message(s) sent and 0 alert\n",[65,540,538],{"__ignoreMap":75},[12,542,543,544,547],{},"From this message we learn that rule ",[65,545,546],{},"TestExternalRedirect"," took 47 minutes to complete, hence disabling this rule reduces the scan duration by about 47 minutes.",[12,549,550,551,554],{},"We can disable individual rules with the environment variable ",[65,552,553],{},"DAST_EXCLUDE_RULES",". Here is an example:",[70,556,558],{"className":72,"code":557,"language":74,"meta":75,"style":75},"variables:\n  DAST_EXCLUDE_RULES=”41,42,43,10027,...,90019”\n\n",[65,559,560,566],{"__ignoreMap":75},[79,561,562,564],{"class":81,"line":82},[79,563,119],{"class":85},[79,565,90],{"class":89},[79,567,568],{"class":81,"line":93},[79,569,570],{"class":105},"  DAST_EXCLUDE_RULES=”41,42,43,10027,...,90019”\n",[12,572,573,575],{},[65,574,553],{}," takes a comma-separated list of rule ids. You can find the id of a particular rule in the summary printed to the job log:",[70,577,580],{"className":578,"code":579,"language":274,"meta":75},[272],"PASS: External Redirect [20019]\n…\nSUMMARY - PASS: 106 | WARN: 2\n",[65,581,579],{"__ignoreMap":75},[12,583,584,585,587],{},"We can see from the log that rule External Redirect, which we found earlier to take 47 minutes, has rule id 20019. To disable this rule in addition to the rules from the previous example, we would need to add it to ",[65,586,553],{}," like so:",[70,589,591],{"className":72,"code":590,"language":74,"meta":75,"style":75},"variables:\n  DAST_EXCLUDE_RULES=”20019,41,42,43,10027,...,90019”\n\n",[65,592,593,599],{"__ignoreMap":75},[79,594,595,597],{"class":81,"line":82},[79,596,119],{"class":85},[79,598,90],{"class":89},[79,600,601],{"class":81,"line":93},[79,602,603],{"class":105},"  DAST_EXCLUDE_RULES=”20019,41,42,43,10027,...,90019”\n",[262,605,607],{"id":606},"parallelizing-dast-jobs-to-further-reduce-pipeline-duration","Parallelizing DAST jobs to further reduce pipeline duration",[12,609,610],{},"To reduce the total duration of the pipeline that is running the DAST job, we can split up the rules that we want to execute into multiple DAST jobs and run the jobs in parallel. Below is an example that demonstrates how to split up the rules.",[70,612,614],{"className":72,"code":613,"language":74,"meta":75,"style":75},"# Any configuration that is shared between jobs goes here\n.dast-conf:\n  image:\n    name: \"registry.gitlab.com/gitlab-org/security-products/dast:1.22.1\"\n  services:\n  - name: \"gitlab/gitlab-ee:nightly\"\n    alias: gitlab\n  script:\n  - /analyze -t \"http://gitlab\"\n\n# First DAST job executing rules 6 to 10\ndast-1/2:\n  extends:\n  - .dast-conf\n  variables:\n    DAST_EXCLUDE_RULES: \"1,2,3,4,5\"\n\n# Second DAST job executing rules 1 to 5\ndast-2/2:\n  extends:\n  - .dast-conf\n  variables:\n    DAST_EXCLUDE_RULES: \"5,6,7,8,9\"\n\n",[65,615,616,622,629,636,646,653,665,675,682,689,694,700,708,716,724,732,743,748,754,762,769,776,783],{"__ignoreMap":75},[79,617,618],{"class":81,"line":82},[79,619,621],{"class":620},"sAwPA","# Any configuration that is shared between jobs goes here\n",[79,623,624,627],{"class":81,"line":93},[79,625,626],{"class":85},".dast-conf",[79,628,90],{"class":89},[79,630,631,634],{"class":81,"line":109},[79,632,633],{"class":85},"  image",[79,635,90],{"class":89},[79,637,638,641,643],{"class":81,"line":116},[79,639,640],{"class":85},"    name",[79,642,102],{"class":89},[79,644,645],{"class":105},"\"registry.gitlab.com/gitlab-org/security-products/dast:1.22.1\"\n",[79,647,648,651],{"class":81,"line":124},[79,649,650],{"class":85},"  services",[79,652,90],{"class":89},[79,654,655,657,660,662],{"class":81,"line":135},[79,656,96],{"class":89},[79,658,659],{"class":85},"name",[79,661,102],{"class":89},[79,663,664],{"class":105},"\"gitlab/gitlab-ee:nightly\"\n",[79,666,667,670,672],{"class":81,"line":146},[79,668,669],{"class":85},"    alias",[79,671,102],{"class":89},[79,673,674],{"class":105},"gitlab\n",[79,676,677,680],{"class":81,"line":157},[79,678,679],{"class":85},"  script",[79,681,90],{"class":89},[79,683,684,686],{"class":81,"line":168},[79,685,96],{"class":89},[79,687,688],{"class":105},"/analyze -t \"http://gitlab\"\n",[79,690,692],{"class":81,"line":691},10,[79,693,113],{"emptyLinePlaceholder":112},[79,695,697],{"class":81,"line":696},11,[79,698,699],{"class":620},"# First DAST job executing rules 6 to 10\n",[79,701,703,706],{"class":81,"line":702},12,[79,704,705],{"class":85},"dast-1/2",[79,707,90],{"class":89},[79,709,711,714],{"class":81,"line":710},13,[79,712,713],{"class":85},"  extends",[79,715,90],{"class":89},[79,717,719,721],{"class":81,"line":718},14,[79,720,96],{"class":89},[79,722,723],{"class":105},".dast-conf\n",[79,725,727,730],{"class":81,"line":726},15,[79,728,729],{"class":85},"  variables",[79,731,90],{"class":89},[79,733,735,738,740],{"class":81,"line":734},16,[79,736,737],{"class":85},"    DAST_EXCLUDE_RULES",[79,739,102],{"class":89},[79,741,742],{"class":105},"\"1,2,3,4,5\"\n",[79,744,746],{"class":81,"line":745},17,[79,747,113],{"emptyLinePlaceholder":112},[79,749,751],{"class":81,"line":750},18,[79,752,753],{"class":620},"# Second DAST job executing rules 1 to 5\n",[79,755,757,760],{"class":81,"line":756},19,[79,758,759],{"class":85},"dast-2/2",[79,761,90],{"class":89},[79,763,765,767],{"class":81,"line":764},20,[79,766,713],{"class":85},[79,768,90],{"class":89},[79,770,772,774],{"class":81,"line":771},21,[79,773,96],{"class":89},[79,775,723],{"class":105},[79,777,779,781],{"class":81,"line":778},22,[79,780,729],{"class":85},[79,782,90],{"class":89},[79,784,786,788,790],{"class":81,"line":785},23,[79,787,737],{"class":85},[79,789,102],{"class":89},[79,791,792],{"class":105},"\"5,6,7,8,9\"\n",[12,794,795,796,801,802,804,805,807,808,810,811,813],{},"For the sake of brevity, we assume in the example above that our DAST job runs rules with id 1 to 10. As described in the previous section, refer to the job log to find which rules were executed (we are working on printing a tidy ",[16,797,800],{"href":798,"rel":799},"https://gitlab.com/gitlab-org/gitlab/-/issues/230893",[],"summary of executed rules","). The example defines two DAST jobs ",[65,803,705],{}," and ",[65,806,759],{},". ",[65,809,705],{}," is excluding rules 1 to 5 and, hence, executes rules 6 to 10. Vice versa, ",[65,812,759],{}," is excluding rules 6 to 10 and, hence, executes rules 1 to 5.",[12,815,816],{},"Following the same pattern, you can split up the rules into as many jobs as necessary, keeping the rules executed in a job mutually exclusive with respect to all other jobs.",[12,818,819,820,822,823,826,827,829],{},"Note that new releases of GitLab DAST may contain new rules, which will get executed if the rule ids are not manually added to ",[65,821,553],{},". In the example above, we pinned the version of the DAST image to a specific version using the ",[65,824,825],{},"image"," keyword. This allows us to review new releases manually and adjust ",[65,828,553],{}," as necessary before upgrading to a new DAST version.",[12,831,832,833,840],{},"When running multiple DAST jobs in parallel against the same target application, make sure that the application isn’t overloaded and becomes a bottleneck. If you observe connection timeouts in the DAST job logs, chances are your target site is overloaded. To mitigate this issue, consider spinning up additional instances of your target application and distribute the test load among the instances. GitLab CI offers, through the ",[16,834,837],{"href":835,"rel":836},"https://docs.gitlab.com/ci/docker/using_docker_images/#what-is-a-service",[],[65,838,839],{},"services"," keyword, a convenient way of creating a dedicated application instance for each DAST job. In the example above, we start a dedicated GitLab instance for each DAST job with:",[70,842,844],{"className":72,"code":843,"language":74,"meta":75,"style":75},"\n  services:\n  - name: \"gitlab/gitlab-ee:nightly\"\n    alias: gitlab\n\n",[65,845,846,850,856,866],{"__ignoreMap":75},[79,847,848],{"class":81,"line":82},[79,849,113],{"emptyLinePlaceholder":112},[79,851,852,854],{"class":81,"line":93},[79,853,650],{"class":85},[79,855,90],{"class":89},[79,857,858,860,862,864],{"class":81,"line":109},[79,859,96],{"class":89},[79,861,659],{"class":85},[79,863,102],{"class":89},[79,865,664],{"class":105},[79,867,868,870,872],{"class":81,"line":116},[79,869,669],{"class":85},[79,871,102],{"class":89},[79,873,674],{"class":105},[57,875,877],{"id":876},"summary","Summary",[12,879,880],{},"In this blog post, we walked you through common challenges encountered when testing complex web applications with DAST and solutions that worked well for our internal projects at GitLab.",[12,882,883,884,889],{},"As we continue and broaden our use of DAST full scans within GitLab and our Security department, we’re excited to identify vulnerabilities in GitLab earlier in the SDLC and look forward to sharing interesting findings with the community. In addition, we take our lessons learned from setting up DAST full scans back to our engineering team to continue improving user experience. We also plan to explore additional dynamic testing techniques such as ",[16,885,888],{"href":886,"rel":887},"https://docs.gitlab.com/user/application_security/coverage_fuzzing/",[],"fuzzing"," to complement our DAST results.",[12,891,892],{},"Is there a problem area that you’ve encountered or solution for fine-tuning DAST full scans we've missed that's worked well for you? We want to hear about it and would love your feedback below in the comments.",[12,894,895,896,901,902],{},"Cover image by ",[16,897,900],{"href":898,"rel":899},"https://www.pexels.com/@pixabay",[],"Pixabay"," on ",[16,903,906],{"href":904,"rel":905},"https://www.pexels.com/photo/blur-bowed-stringed-instrument-classic-classical-237454/",[],"Pexels",[908,909,910],"style",{},"html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}",{"title":75,"searchDepth":93,"depth":93,"links":912},[913,914,921],{"id":59,"depth":93,"text":60},{"id":215,"depth":93,"text":216,"children":915},[916,917,918,919,920],{"id":264,"depth":109,"text":265},{"id":333,"depth":109,"text":334},{"id":377,"depth":109,"text":378},{"id":530,"depth":109,"text":531},{"id":606,"depth":109,"text":607},{"id":876,"depth":93,"text":877},"security","2020-08-31","Keep your DAST job within timeout limits and fine-tune job configurations for better results","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679617/Blog/Hero%20Images/tuning-237454.jpg",{},"/en-us/blog/how-to-configure-dast-full-scans-for-complex-web-applications",{"title":5,"description":924,"ogTitle":5,"ogDescription":924,"noIndex":927,"ogImage":928,"ogUrl":932,"ogSiteName":933,"ogType":934,"canonicalUrls":932},"https://about.gitlab.com/blog/how-to-configure-dast-full-scans-for-complex-web-applications","https://about.gitlab.com","article","how-to-configure-dast-full-scans-for-complex-web-applications","en-us/blog/how-to-configure-dast-full-scans-for-complex-web-applications",[922,938,939],"security research","open source","BlogPost","anqvGGvGOBNAs-0cMeZ63jc7cGcoTMcS0N4Qa-bV--Q",{"logo":943,"freeTrial":948,"sales":953,"login":958,"items":963,"search":1289,"minimal":1320,"duo":1339,"switchNav":1348,"pricingDeployment":1359},{"config":944},{"href":945,"dataGaName":946,"dataGaLocation":947},"/","gitlab logo","header",{"text":949,"config":950},"Get free trial",{"href":951,"dataGaName":952,"dataGaLocation":947},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":954,"config":955},"Request a demo",{"href":956,"dataGaName":957,"dataGaLocation":947},"/sales/?contact-topic=request-demo","sales",{"text":959,"config":960},"Sign in",{"href":961,"dataGaName":962,"dataGaLocation":947},"https://gitlab.com/users/sign_in/","sign in",[964,993,1093,1098,1211,1267],{"text":965,"config":966,"menu":968},"Platform",{"dataNavLevelOne":967},"platform",{"type":969,"columns":970},"cards",[971,977,985],{"title":965,"description":972,"link":973},"The intelligent orchestration platform for DevSecOps",{"text":974,"config":975},"Explore our Platform",{"href":976,"dataGaName":967,"dataGaLocation":947},"/platform/",{"title":978,"description":979,"link":980},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":981,"config":982},"Meet GitLab Duo",{"href":983,"dataGaName":984,"dataGaLocation":947},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":986,"description":987,"link":988},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":989,"config":990},"Learn more",{"href":991,"dataGaName":992,"dataGaLocation":947},"/why-gitlab/","why gitlab",{"text":994,"left":112,"config":995,"menu":997},"Product",{"dataNavLevelOne":996},"solutions",{"type":998,"link":999,"columns":1003,"feature":1072},"lists",{"text":1000,"config":1001},"View all Solutions",{"href":1002,"dataGaName":996,"dataGaLocation":947},"/solutions/",[1004,1028,1051],{"title":1005,"description":1006,"link":1007,"items":1012},"Automation","CI/CD and automation to accelerate deployment",{"config":1008},{"icon":1009,"href":1010,"dataGaName":1011,"dataGaLocation":947},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[1013,1017,1020,1024],{"text":1014,"config":1015},"CI/CD",{"href":1016,"dataGaLocation":947,"dataGaName":1014},"/solutions/continuous-integration/",{"text":978,"config":1018},{"href":983,"dataGaLocation":947,"dataGaName":1019},"gitlab duo agent platform - product menu",{"text":1021,"config":1022},"Source Code Management",{"href":1023,"dataGaLocation":947,"dataGaName":1021},"/solutions/source-code-management/",{"text":1025,"config":1026},"Automated Software Delivery",{"href":1010,"dataGaLocation":947,"dataGaName":1027},"Automated software delivery",{"title":1029,"description":1030,"link":1031,"items":1036},"Security","Deliver code faster without compromising security",{"config":1032},{"href":1033,"dataGaName":1034,"dataGaLocation":947,"icon":1035},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[1037,1041,1046],{"text":1038,"config":1039},"Application Security Testing",{"href":1033,"dataGaName":1040,"dataGaLocation":947},"Application security testing",{"text":1042,"config":1043},"Software Supply Chain Security",{"href":1044,"dataGaLocation":947,"dataGaName":1045},"/solutions/supply-chain/","Software supply chain security",{"text":1047,"config":1048},"Software Compliance",{"href":1049,"dataGaName":1050,"dataGaLocation":947},"/solutions/software-compliance/","software compliance",{"title":1052,"link":1053,"items":1058},"Measurement",{"config":1054},{"icon":1055,"href":1056,"dataGaName":1057,"dataGaLocation":947},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[1059,1063,1067],{"text":1060,"config":1061},"Visibility & Measurement",{"href":1056,"dataGaLocation":947,"dataGaName":1062},"Visibility and Measurement",{"text":1064,"config":1065},"Value Stream Management",{"href":1066,"dataGaLocation":947,"dataGaName":1064},"/solutions/value-stream-management/",{"text":1068,"config":1069},"Analytics & Insights",{"href":1070,"dataGaLocation":947,"dataGaName":1071},"/solutions/analytics-and-insights/","Analytics and insights",{"title":1073,"type":998,"items":1074},"GitLab for",[1075,1081,1087],{"text":1076,"config":1077},"Enterprise",{"icon":1078,"href":1079,"dataGaLocation":947,"dataGaName":1080},"Building","/enterprise/","enterprise",{"text":1082,"config":1083},"Small Business",{"icon":1084,"href":1085,"dataGaLocation":947,"dataGaName":1086},"Work","/small-business/","small business",{"text":1088,"config":1089},"Public Sector",{"icon":1090,"href":1091,"dataGaLocation":947,"dataGaName":1092},"Organization","/solutions/public-sector/","public sector",{"text":1094,"config":1095},"Pricing",{"href":1096,"dataGaName":1097,"dataGaLocation":947,"dataNavLevelOne":1097},"/pricing/","pricing",{"text":1099,"config":1100,"menu":1102},"Resources",{"dataNavLevelOne":1101},"resources",{"type":998,"link":1103,"columns":1107,"feature":1200},{"text":1104,"config":1105},"View all resources",{"href":1106,"dataGaName":1101,"dataGaLocation":947},"/resources/",[1108,1141,1168],{"title":1109,"items":1110},"Getting started",[1111,1116,1121,1126,1131,1136],{"text":1112,"config":1113},"Install",{"href":1114,"dataGaName":1115,"dataGaLocation":947},"/install/","install",{"text":1117,"config":1118},"Quick start guides",{"href":1119,"dataGaName":1120,"dataGaLocation":947},"/get-started/","quick setup checklists",{"text":1122,"config":1123},"Learn",{"href":1124,"dataGaLocation":947,"dataGaName":1125},"https://university.gitlab.com/","learn",{"text":1127,"config":1128},"Product documentation",{"href":1129,"dataGaName":1130,"dataGaLocation":947},"https://docs.gitlab.com/","product documentation",{"text":1132,"config":1133},"Best practice videos",{"href":1134,"dataGaName":1135,"dataGaLocation":947},"/getting-started-videos/","best practice videos",{"text":1137,"config":1138},"Integrations",{"href":1139,"dataGaName":1140,"dataGaLocation":947},"/integrations/","integrations",{"title":1142,"items":1143},"Discover",[1144,1149,1154,1159,1163],{"text":1145,"config":1146},"Customer success stories",{"href":1147,"dataGaName":1148,"dataGaLocation":947},"/customers/","customer success stories",{"text":1150,"config":1151},"Blog",{"href":1152,"dataGaName":1153,"dataGaLocation":947},"/blog/","blog",{"text":1155,"config":1156},"Demo Hub",{"href":1157,"dataGaName":1158,"dataGaLocation":947},"/demo-hub/","demo hub",{"text":1160,"config":1161},"The Source",{"href":1162,"dataGaName":1153,"dataGaLocation":947},"/the-source/",{"text":1164,"config":1165},"Remote",{"href":1166,"dataGaName":1167,"dataGaLocation":947},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":1169,"items":1170},"Connect",[1171,1175,1180,1185,1190,1195],{"text":1172,"config":1173},"GitLab Services",{"href":1174,"dataGaName":839,"dataGaLocation":947},"/services/",{"text":1176,"config":1177},"Contribute",{"href":1178,"dataGaName":1179,"dataGaLocation":947},"https://contributors.gitlab.com","contribute",{"text":1181,"config":1182},"Community",{"href":1183,"dataGaName":1184,"dataGaLocation":947},"/community/","community",{"text":1186,"config":1187},"Forum",{"href":1188,"dataGaName":1189,"dataGaLocation":947},"https://forum.gitlab.com/","forum",{"text":1191,"config":1192},"Events",{"href":1193,"dataGaName":1194,"dataGaLocation":947},"/events/","events",{"text":1196,"config":1197},"Partners",{"href":1198,"dataGaName":1199,"dataGaLocation":947},"/partners/","partners",{"config":1201,"title":1204,"text":1205,"link":1206},{"background":1202,"textColor":1203},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":1207,"config":1208},"Read the latest",{"href":1209,"dataGaName":1210,"dataGaLocation":947},"/whats-new/","whats new",{"text":1212,"config":1213,"menu":1215},"Company",{"dataNavLevelOne":1214},"company",{"type":998,"columns":1216},[1217],{"items":1218},[1219,1224,1230,1232,1237,1242,1247,1252,1257,1262],{"text":1220,"config":1221},"About",{"href":1222,"dataGaName":1223,"dataGaLocation":947},"/company/","about",{"text":1225,"config":1226,"footerGa":1229},"Jobs",{"href":1227,"dataGaName":1228,"dataGaLocation":947},"/jobs/","jobs",{"dataGaName":1228},{"text":1191,"config":1231},{"href":1193,"dataGaName":1194,"dataGaLocation":947},{"text":1233,"config":1234},"Leadership",{"href":1235,"dataGaName":1236,"dataGaLocation":947},"/company/team/e-group/","leadership",{"text":1238,"config":1239},"Handbook",{"href":1240,"dataGaName":1241,"dataGaLocation":947},"https://handbook.gitlab.com/","handbook",{"text":1243,"config":1244},"Investor relations",{"href":1245,"dataGaName":1246,"dataGaLocation":947},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":1248,"config":1249},"Trust Center",{"href":1250,"dataGaName":1251,"dataGaLocation":947},"/security/","trust center",{"text":1253,"config":1254},"AI Transparency Center",{"href":1255,"dataGaName":1256,"dataGaLocation":947},"/ai-transparency-center/","ai transparency center",{"text":1258,"config":1259},"Newsletter",{"href":1260,"dataGaName":1261,"dataGaLocation":947},"/company/contact/#contact-forms","newsletter",{"text":1263,"config":1264},"Press",{"href":1265,"dataGaName":1266,"dataGaLocation":947},"/press/","press",{"text":1268,"config":1269,"menu":1270},"Contact us",{"dataNavLevelOne":1214},{"type":998,"columns":1271},[1272],{"items":1273},[1274,1279,1284],{"text":1275,"config":1276},"Talk to sales",{"href":1277,"dataGaName":1278,"dataGaLocation":947},"/sales/","talk to sales",{"text":1280,"config":1281},"Support portal",{"href":1282,"dataGaName":1283,"dataGaLocation":947},"https://support.gitlab.com/hc/en-us","support portal",{"text":1285,"config":1286},"Customer portal",{"href":1287,"dataGaName":1288,"dataGaLocation":947},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":1290,"login":1291,"suggestions":1298},"Close",{"text":1292,"link":1293},"To search repositories and projects, login to",{"text":1294,"config":1295},"gitlab.com",{"href":961,"dataGaName":1296,"dataGaLocation":1297},"search login","search",{"text":1299,"default":1300},"Suggestions",[1301,1303,1307,1309,1313,1317],{"text":978,"config":1302},{"href":983,"dataGaName":978,"dataGaLocation":1297},{"text":1304,"config":1305},"Code Suggestions (AI)",{"href":1306,"dataGaName":1304,"dataGaLocation":1297},"/solutions/code-suggestions/",{"text":1014,"config":1308},{"href":1016,"dataGaName":1014,"dataGaLocation":1297},{"text":1310,"config":1311},"GitLab on AWS",{"href":1312,"dataGaName":1310,"dataGaLocation":1297},"/partners/technology-partners/aws/",{"text":1314,"config":1315},"GitLab on Google Cloud",{"href":1316,"dataGaName":1314,"dataGaLocation":1297},"/partners/technology-partners/google-cloud-platform/",{"text":1318,"config":1319},"Why GitLab?",{"href":991,"dataGaName":1318,"dataGaLocation":1297},{"freeTrial":1321,"mobileIcon":1326,"desktopIcon":1331,"secondaryButton":1334},{"text":1322,"config":1323},"Start free trial",{"href":1324,"dataGaName":952,"dataGaLocation":1325},"https://gitlab.com/-/trials/new/","nav",{"altText":1327,"config":1328},"Gitlab Icon",{"src":1329,"dataGaName":1330,"dataGaLocation":1325},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1327,"config":1332},{"src":1333,"dataGaName":1330,"dataGaLocation":1325},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1335,"config":1336},"Get Started",{"href":1337,"dataGaName":1338,"dataGaLocation":1325},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":1340,"mobileIcon":1344,"desktopIcon":1346},{"text":1341,"config":1342},"Learn more about GitLab Duo",{"href":983,"dataGaName":1343,"dataGaLocation":1325},"gitlab duo",{"altText":1327,"config":1345},{"src":1329,"dataGaName":1330,"dataGaLocation":1325},{"altText":1327,"config":1347},{"src":1333,"dataGaName":1330,"dataGaLocation":1325},{"button":1349,"mobileIcon":1354,"desktopIcon":1356},{"text":1350,"config":1351},"/switch",{"href":1352,"dataGaName":1353,"dataGaLocation":1325},"#contact","switch",{"altText":1327,"config":1355},{"src":1329,"dataGaName":1330,"dataGaLocation":1325},{"altText":1327,"config":1357},{"src":1358,"dataGaName":1330,"dataGaLocation":1325},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1360,"mobileIcon":1365,"desktopIcon":1367},{"text":1361,"config":1362},"Back to pricing",{"href":1096,"dataGaName":1363,"dataGaLocation":1325,"icon":1364},"back to pricing","GoBack",{"altText":1327,"config":1366},{"src":1329,"dataGaName":1330,"dataGaLocation":1325},{"altText":1327,"config":1368},{"src":1333,"dataGaName":1330,"dataGaLocation":1325},{"title":1370,"titleMobile":1371,"button":1372,"config":1377},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":989,"config":1373},{"href":1374,"dataGaName":1375,"dataGaLocation":1376},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":1378,"disabled":927},"release",{"data":1380},{"text":1381,"source":1382,"edit":1388,"contribute":1393,"config":1398,"items":1403,"minimal":1613},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":1383,"config":1384},"View page source",{"href":1385,"dataGaName":1386,"dataGaLocation":1387},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1389,"config":1390},"Edit this page",{"href":1391,"dataGaName":1392,"dataGaLocation":1387},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1394,"config":1395},"Please contribute",{"href":1396,"dataGaName":1397,"dataGaLocation":1387},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1399,"facebook":1400,"youtube":1401,"linkedin":1402},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1404,1451,1505,1549,1581],{"title":1094,"links":1405,"subMenu":1420},[1406,1410,1415],{"text":1407,"config":1408},"View plans",{"href":1096,"dataGaName":1409,"dataGaLocation":1387},"view plans",{"text":1411,"config":1412},"Why Premium?",{"href":1413,"dataGaName":1414,"dataGaLocation":1387},"/pricing/premium/","why premium",{"text":1416,"config":1417},"Why Ultimate?",{"href":1418,"dataGaName":1419,"dataGaLocation":1387},"/pricing/ultimate/","why ultimate",[1421],{"title":1422,"links":1423},"Contact Us",[1424,1427,1429,1431,1436,1441,1446],{"text":1425,"config":1426},"Contact sales",{"href":1277,"dataGaName":957,"dataGaLocation":1387},{"text":1280,"config":1428},{"href":1282,"dataGaName":1283,"dataGaLocation":1387},{"text":1285,"config":1430},{"href":1287,"dataGaName":1288,"dataGaLocation":1387},{"text":1432,"config":1433},"Status",{"href":1434,"dataGaName":1435,"dataGaLocation":1387},"https://status.gitlab.com/","status",{"text":1437,"config":1438},"Terms of use",{"href":1439,"dataGaName":1440,"dataGaLocation":1387},"/terms/","terms of use",{"text":1442,"config":1443},"Privacy statement",{"href":1444,"dataGaName":1445,"dataGaLocation":1387},"/privacy/","privacy statement",{"text":1447,"config":1448},"Cookie preferences",{"dataGaName":1449,"dataGaLocation":1387,"id":1450,"isOneTrustButton":112},"cookie preferences","ot-sdk-btn",{"title":994,"links":1452,"subMenu":1461},[1453,1457],{"text":1454,"config":1455},"DevSecOps platform",{"href":976,"dataGaName":1456,"dataGaLocation":1387},"devsecops platform",{"text":1458,"config":1459},"AI-Assisted Development",{"href":983,"dataGaName":1460,"dataGaLocation":1387},"ai-assisted development",[1462],{"title":1463,"links":1464},"Topics",[1465,1470,1475,1480,1485,1490,1495,1500],{"text":1466,"config":1467},"CICD",{"href":1468,"dataGaName":1469,"dataGaLocation":1387},"/topics/ci-cd/","cicd",{"text":1471,"config":1472},"GitOps",{"href":1473,"dataGaName":1474,"dataGaLocation":1387},"/topics/gitops/","gitops",{"text":1476,"config":1477},"DevOps",{"href":1478,"dataGaName":1479,"dataGaLocation":1387},"/topics/devops/","devops",{"text":1481,"config":1482},"Version Control",{"href":1483,"dataGaName":1484,"dataGaLocation":1387},"/topics/version-control/","version control",{"text":1486,"config":1487},"DevSecOps",{"href":1488,"dataGaName":1489,"dataGaLocation":1387},"/topics/devsecops/","devsecops",{"text":1491,"config":1492},"Cloud Native",{"href":1493,"dataGaName":1494,"dataGaLocation":1387},"/topics/cloud-native/","cloud native",{"text":1496,"config":1497},"AI for Coding",{"href":1498,"dataGaName":1499,"dataGaLocation":1387},"/topics/devops/ai-for-coding/","ai for coding",{"text":1501,"config":1502},"Agentic AI",{"href":1503,"dataGaName":1504,"dataGaLocation":1387},"/topics/agentic-ai/","agentic ai",{"title":1506,"links":1507},"Solutions",[1508,1510,1512,1517,1521,1524,1528,1531,1533,1536,1539,1544],{"text":1038,"config":1509},{"href":1033,"dataGaName":1038,"dataGaLocation":1387},{"text":1027,"config":1511},{"href":1010,"dataGaName":1011,"dataGaLocation":1387},{"text":1513,"config":1514},"Agile development",{"href":1515,"dataGaName":1516,"dataGaLocation":1387},"/solutions/agile-delivery/","agile delivery",{"text":1518,"config":1519},"SCM",{"href":1023,"dataGaName":1520,"dataGaLocation":1387},"source code management",{"text":1466,"config":1522},{"href":1016,"dataGaName":1523,"dataGaLocation":1387},"continuous integration & delivery",{"text":1525,"config":1526},"Value stream management",{"href":1066,"dataGaName":1527,"dataGaLocation":1387},"value stream management",{"text":1471,"config":1529},{"href":1530,"dataGaName":1474,"dataGaLocation":1387},"/solutions/gitops/",{"text":1076,"config":1532},{"href":1079,"dataGaName":1080,"dataGaLocation":1387},{"text":1534,"config":1535},"Small business",{"href":1085,"dataGaName":1086,"dataGaLocation":1387},{"text":1537,"config":1538},"Public sector",{"href":1091,"dataGaName":1092,"dataGaLocation":1387},{"text":1540,"config":1541},"Education",{"href":1542,"dataGaName":1543,"dataGaLocation":1387},"/solutions/education/","education",{"text":1545,"config":1546},"Financial services",{"href":1547,"dataGaName":1548,"dataGaLocation":1387},"/solutions/finance/","financial services",{"title":1099,"links":1550},[1551,1553,1555,1557,1560,1562,1565,1567,1569,1571,1573,1575,1577,1579],{"text":1112,"config":1552},{"href":1114,"dataGaName":1115,"dataGaLocation":1387},{"text":1117,"config":1554},{"href":1119,"dataGaName":1120,"dataGaLocation":1387},{"text":1122,"config":1556},{"href":1124,"dataGaName":1125,"dataGaLocation":1387},{"text":1127,"config":1558},{"href":1129,"dataGaName":1559,"dataGaLocation":1387},"docs",{"text":1150,"config":1561},{"href":1152,"dataGaName":1153,"dataGaLocation":1387},{"text":1563,"config":1564},"What's new",{"href":1209,"dataGaName":1210,"dataGaLocation":1387},{"text":1145,"config":1566},{"href":1147,"dataGaName":1148,"dataGaLocation":1387},{"text":1164,"config":1568},{"href":1166,"dataGaName":1167,"dataGaLocation":1387},{"text":1172,"config":1570},{"href":1174,"dataGaName":839,"dataGaLocation":1387},{"text":1176,"config":1572},{"href":1178,"dataGaName":1179,"dataGaLocation":1387},{"text":1181,"config":1574},{"href":1183,"dataGaName":1184,"dataGaLocation":1387},{"text":1186,"config":1576},{"href":1188,"dataGaName":1189,"dataGaLocation":1387},{"text":1191,"config":1578},{"href":1193,"dataGaName":1194,"dataGaLocation":1387},{"text":1196,"config":1580},{"href":1198,"dataGaName":1199,"dataGaLocation":1387},{"title":1212,"links":1582},[1583,1585,1587,1589,1591,1593,1597,1602,1604,1606,1608],{"text":1220,"config":1584},{"href":1222,"dataGaName":1214,"dataGaLocation":1387},{"text":1225,"config":1586},{"href":1227,"dataGaName":1228,"dataGaLocation":1387},{"text":1233,"config":1588},{"href":1235,"dataGaName":1236,"dataGaLocation":1387},{"text":1238,"config":1590},{"href":1240,"dataGaName":1241,"dataGaLocation":1387},{"text":1243,"config":1592},{"href":1245,"dataGaName":1246,"dataGaLocation":1387},{"text":1594,"config":1595},"Sustainability",{"href":1596,"dataGaName":1594,"dataGaLocation":1387},"/sustainability/",{"text":1598,"config":1599},"Diversity, inclusion and belonging (DIB)",{"href":1600,"dataGaName":1601,"dataGaLocation":1387},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":1248,"config":1603},{"href":1250,"dataGaName":1251,"dataGaLocation":1387},{"text":1258,"config":1605},{"href":1260,"dataGaName":1261,"dataGaLocation":1387},{"text":1263,"config":1607},{"href":1265,"dataGaName":1266,"dataGaLocation":1387},{"text":1609,"config":1610},"Modern Slavery Transparency Statement",{"href":1611,"dataGaName":1612,"dataGaLocation":1387},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1614},[1615,1618,1621],{"text":1616,"config":1617},"Terms",{"href":1439,"dataGaName":1440,"dataGaLocation":1387},{"text":1619,"config":1620},"Cookies",{"dataGaName":1449,"dataGaLocation":1387,"id":1450,"isOneTrustButton":112},{"text":1622,"config":1623},"Privacy",{"href":1444,"dataGaName":1445,"dataGaLocation":1387},[1625],{"id":1626,"title":7,"body":926,"config":1627,"content":1629,"description":926,"extension":1633,"meta":1634,"navigation":112,"path":1635,"seo":1636,"stem":1637,"__hash__":1638},"blogAuthors/en-us/blog/authors/dennis-appelt.yml",{"template":1628},"BlogAuthor",{"name":7,"config":1630},{"headshot":1631,"ctfId":1632},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749672032/Blog/Author%20Headshots/dappelt-headshot.jpg","dappelt","yml",{},"/en-us/blog/authors/dennis-appelt",{},"en-us/blog/authors/dennis-appelt","s0eKcsSwHvpcru4Dk7IkXJyRfuBEWrMhfVAJ_Fan-L4",[1640,1648,1656],{"title":1641,"description":1642,"heroImage":1643,"category":922,"date":1644,"authors":1645,"slug":1647,"externalUrl":926},"How GitLab tracks vulnerabilities through refactors and reformatting","Learn how GitLab's improved Scope+Offset fingerprinting keeps vulnerability tracking stable across comments, blank lines, and reformatting.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1759320418/xjmqcozxzt4frx0hori3.png","2026-08-12",[1646],"Julian Thome","improved-scope-offset-fingerprinting",{"title":1649,"description":1650,"heroImage":1643,"category":922,"date":1651,"authors":1652,"slug":1655,"externalUrl":926},"GitLab Secrets Manager adds ESO, Terraform, API support","Simplify credential management across your stack. GitLab Secrets Manager provides secure retrieval in Kubernetes, Terraform, and external workflows.","2026-08-06",[1653,1654],"Erick Bajao","Joe Randazzo","gitlab-secrets-manager-add-eso-terraform-api-support",{"title":1657,"description":1658,"heroImage":1659,"category":922,"date":1660,"authors":1661,"slug":1663,"externalUrl":926},"Secure every commit to production with Claude and GitLab","Claude Security catches vulnerabilities inside a coding session. GitLab picks up from there, scanning, enforcing policy, and producing audit evidence for the software lifecycle. ","https://res.cloudinary.com/about-gitlab-com/image/upload/v1756122536/akivvcnafog9c4dhhzkp.png","2026-08-03",[1662],"Alisa Ho","claude-security-and-gitlab",{"promotions":1665},[1666,1680,1692,1703],{"id":1667,"categories":1668,"header":1670,"text":1671,"button":1672,"image":1677},"ai-modernization",[1669],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1673,"config":1674},"Get your AI maturity score",{"href":1675,"dataGaName":1676,"dataGaLocation":1153},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1678},{"src":1679},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1681,"categories":1682,"header":1684,"text":1671,"button":1685,"image":1689},"devops-modernization",[1683,1489],"product","Are you just managing tools or shipping innovation?",{"text":1686,"config":1687},"Get your DevOps maturity score",{"href":1688,"dataGaName":1676,"dataGaLocation":1153},"/assessments/devops-modernization-assessment/",{"config":1690},{"src":1691},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1693,"categories":1694,"header":1695,"text":1671,"button":1696,"image":1700},"security-modernization",[922],"Are you trading speed for security?",{"text":1697,"config":1698},"Get your security maturity score",{"href":1699,"dataGaName":1676,"dataGaLocation":1153},"/assessments/security-modernization-assessment/",{"config":1701},{"src":1702},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1704,"paths":1705,"header":1708,"text":1709,"button":1710,"image":1715},"github-azure-migration",[1706,1707],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":1711,"config":1712},"See how GitLab compares to GitHub",{"href":1713,"dataGaName":1714,"dataGaLocation":1153},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1716},{"src":1691},{"header":1718,"blurb":1719,"button":1720,"secondaryButton":1725},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1721,"config":1722},"Get your free trial",{"href":1723,"dataGaName":952,"dataGaLocation":1724},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":1425,"config":1726},{"href":1277,"dataGaName":957,"dataGaLocation":1724},1786803769870]