It is possible to gather sensitive information about the web application such as usernames, passwords, machine name and/or sensitive file locations
21
L
It is possible to persuade a naive user to supply sensitive information such as username, password, credit card number, social security number etc.
6
L
It is possible to retrieve the source code of server-side scripts, which may expose the application logic and other sensitive information such as usernames and passwords
5
I
It is possible to gather sensitive debugging information
46
I
The worst case scenario for this attack depends on the context and role of the cookies that are created at the client side
2
I
It is possible to retrieve the absolute path of the web server installation, which might help an attacker to develop further attacks and to gain information about the file system structure of the web application
6
I
It is possible to prevent the web application from serving other users (denial of service)
AppScan detected that the Content-Security-Policy response header is missing or with an insecure policy, which increases exposure to various cross-site injection attacks
Test Requests and Responses:
GET /adjuncts/50d72996/lib/layout/progressiveRendering/progressiveRendering.js HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer: https://99.85.165.247:9043/asynchPeople/?auto_refresh=true
Cookie: JSESSIONID=node0ufhag3b0oozsup3wq99xd5882279; screenResolution=1280x800; JSESSIONID=node0ufhag3b0oozsup3wq99xd5882279; JSESSIONID.3b8af5e7=node0ufhag3b0oozsup3wq99xd5882279.node0; JSESSIONID=node0d3ra70bqwooaika5vrnbajm5760; hudson_auto_refresh=true
Connection: keep-alive
Host: 99.85.165.247:9043
Accept: */*
Accept-Language: en-US
HTTP/1.1 200 OK
Last-Modified: Mon, 21 Sep 2020 03:52:36 GMT
csrftoken: 1617853616
X-XSS-Protection: 1; mode=block
Server: Jetty(9.4.z-SNAPSHOT)
Accept-Ranges: bytes
Pragma: no-cache
Content-Length: 2342
X-Content-Type-Options: nosniff
Cache-Control: no-store
Strict-Transport-Security: max-age=31536000;includeSubDomains
Set-Cookie: JSESSIONID=node01tvp4ve09ngbi1pztvdo5xefnc770;Secure;HttpOnly;
Date: Tue, 22 Sep 2020 02:12:46 GMT
Content-Security-Policy: script-src 'self'
Expires: Wed, 22 Sep 2021 02:12:46 GMT
Content-Type: application/javascript
/*
* The MIT License
*
* Copyright 2012 Jesse Glick.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
function progressivelyRender(handler, callback, statusId) {
function checkNews(response) {
var r = response.responseObject();
if (r.status == 'done') {
callback(r.data);
$(statusId).style.display = 'none';
} else if (r.status == 'canceled') {
// TODO ugly; replace with single tr of class=unknown?
$$('#' + statusId + ' .progress-bar-done')[0].innerHTML = 'Aborted.';
} else if (r.status == 'error') {
$$('#' + statusId + ' .progress-bar-done')[0].style.width = '100%';
$$('#' + statusId + ' .progress-bar-left')[0].style.width = '0%';
$(statusId).className = 'progress-bar red';
} else {
callback(r.data);
$$('#' + statusId + ' .progress-bar-done')[0].style.width = (100 * r.status) + '%';
$$('#' + statusId + ' .progress-bar-left')[0].style.width = (100 - 100 * r.status) + '%';
checkNewsLater(500);
}
}
function checkNewsLater(timeout) {
setTimeout(function() {
handler.news(checkNews);
}, timeout);
}
handler.start(function(response) {
checkNewsLater(0);
});
}
AppScan detected that the Content-Security-Policy response header is missing or with an insecure policy, which increases exposure to various cross-site injection attacks
Test Requests and Responses:
GET /static/50d72996/scripts/yui/cookie/cookie-min.js HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer: https://99.85.165.247:9043/
Cookie: screenResolution=1280x800; JSESSIONID=node0ufhag3b0oozsup3wq99xd5882279; JSESSIONID=node0ufhag3b0oozsup3wq99xd5882279; JSESSIONID.3b8af5e7=node0ufhag3b0oozsup3wq99xd5882279.node0; JSESSIONID=node0d3ra70bqwooaika5vrnbajm5760; hudson_auto_refresh=false
Connection: keep-alive
Host: 99.85.165.247:9043
Accept: */*
Accept-Language: en-US
HTTP/1.1 200 OK
Last-Modified: Mon, 21 Sep 2020 03:52:36 GMT
csrftoken: -1905870016
X-XSS-Protection: 1; mode=block
Server: Jetty(9.4.z-SNAPSHOT)
Accept-Ranges: bytes
Pragma: no-cache
Content-Length: 4556
X-Content-Type-Options: nosniff
Cache-Control: no-store
Strict-Transport-Security: max-age=31536000;includeSubDomains
Set-Cookie: JSESSIONID=node0mjvl85h143vt1lciatqc266i5774;Secure;HttpOnly;
Date: Tue, 22 Sep 2020 02:12:47 GMT
Content-Security-Policy: script-src 'self'
Expires: Wed, 22 Sep 2021 02:12:47 GMT
Content-Type: application/javascript
/*
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 2.9.0
*/
YAHOO.namespace("util");YAHOO.util.Cookie={_createCookieString:function(B,D,C,A){var F=YAHOO.lang,E=encodeURIComponent(B)+"="+(C?encodeURIComponent(D):D);if(F.isObject(A)){if(A.expires instanceof Date){E+="; expires="+A.expires.toUTCString();}if(F.isString(A.path)&&A.path!==""){E+="; path="+A.path;}if(F.isString(A.domain)&&A.domain!==""){E+="; domain="+A.domain;}if(A.secure===true){E+="; secure";}}return E;},_createCookieHashString:function(B){var D=YAHOO.lang;if(!D.isObject(B)){throw new TypeError("Cookie._createCookieHashString(): Argument must be an object.");}var C=[];for(var A in B){if(D.hasOwnProperty(B,A)&&!D.isFunction(B[A])&&!D.isUndefined(B[A])){C.push(encodeURIComponent(A)+"="+encodeURIComponent(String(B[A])));}}return C.join("&");},_parseCookieHash:function(E){var D=E.split("&"),F=null,C={};if(E.length>0){for(var B=0,A=D.length;B<A;B++){F=D[B].split("=");C[decodeURIComponent(F[0])]=decodeURIComponent(F[1]);}}return C;},_parseCookieString:function(J,A){var K={};if(YAHOO.lang.isString(J)&&J.length>0){var B=(A===false?function(L){return L;}:decodeURIComponent);var H=J.split(/;\s/g),I=null,C=null,E=null;for(var D=0,F=H.length;D<F;D++){E=H[D].match(/([^=]+)=/i);if(E instanceof Array){try{I=decodeURIComponent(E[1]);C=B(H[D].substring(E[1].length+1));}catch(G){}}else{I=decodeURIComponent(H[D]);C="";}K[I]=C;}}return K;},exists:function(A){if(!YAHOO.lang.isString(A)||A===""){throw new TypeError("Cookie.exists(): Cookie name must be a non-empty string.");}var B=this._parseCookieString(document.cookie,true);return B.hasOwnProperty(A);},get:function(B,A){var E=YAHOO.lang,C;if(E.isFunction(A)){C=A;A={};}else{if(E.isObject(A)){C=A.converter;}else{A={};}}var D=this._parseCookieString(document.cookie,!A.raw);if(!E.isString(B)||B===""){throw new TypeError("Cookie.get(): Cookie name must be a non-empty string.");}if(E.isUndefined(D[B])){return null;}if(!E.isFunction(C)){return D[B];}else{return C(D[B]);}},getSub:function(A,C,B){var E=YAHOO.lang,D=this.getSubs(A);if(D!==null){if(!E.isString(C)||C===""){throw new TypeError("Cookie.getSub(): Subcookie name must be a non-empty string.");}if(E.isUndefined(D[C])){return null;}if(!E.isFunction(B)){return D[C];}else{return B(D[C]);}}else{return null;}},getSubs:function(B){var A=YAHOO.lang.isString;if(!A(B)||B===""){throw new TypeError("Cookie.getSubs(): Cookie name must be a non-empty string.");}var C=this._parseCookieString(document.cookie,false);if(A(C[B])){return this._parseCookieHash(C[B]);}return null;},remove:function(B,A){if(!YAHOO.lang.isString(B)||B===""){throw new TypeError("Cookie.remove(): Cookie name must be a non-empty string.");}A=YAHOO.lang.merge(A||{},{expires:new Date(0)});return this.set(B,"",A);},removeSub:function(B,E,A){var F=YAHOO.lang;A=A||{};if(!F.isString(B)||B===""){throw new TypeError("Cookie.removeSub(): Cookie name must be a non-empty string.");}if(!F.isString(E)||E===""){throw new TypeError("Cookie.removeSub(): Subcookie name must be a non-empty string.");}var D=this.getSubs(B);if(F.isObject(D)&&F.hasOwnProperty(D,E)){delete D[E];if(!A.removeIfEmpty){return this.setSubs(B,D,A);}else{for(var C in D){if(F.hasOwnProperty(D,C)&&!F.isFunction(D[C])&&!F.isUndefined(D[C])){return this.setSubs(B,D,A);}}return this.remove(B,A);}}else{return"";}},set:function(B,C,A){var E=YAHOO.lang;A=A||{};if(!E.isString(B)){throw new TypeError("Cookie.set(): Cookie name must be a string.");}if(E.isUndefined(C)){throw new TypeError("Cookie.set(): Value cannot be undefined.");}var D=this._createCookieString(B,C,!A.raw,A);document.cookie=D;return D;},setSub:function(B,D,C,A){var F=YAHOO.lang;if(!F.isString(B)||B===""){throw new TypeError("Cookie.s
...
...
...
AppScan detected that the Content-Security-Policy response header is missing or with an insecure policy, which increases exposure to various cross-site injection attacks
AppScan detected that the Content-Security-Policy response header is missing or with an insecure policy, which increases exposure to various cross-site injection attacks
AppScan detected that the Content-Security-Policy response header is missing or with an insecure policy, which increases exposure to various cross-site injection attacks
It is possible to retrieve the source code of server-side scripts, which may expose the application logic and other sensitive information such as usernames and passwords
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
Temporary files were left in production environment
Debugging information was left by the programmer in web pages
It is possible to retrieve the source code of server-side scripts, which may expose the application logic and other sensitive information such as usernames and passwords
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
Temporary files were left in production environment
Debugging information was left by the programmer in web pages
The response contains source code of script files, which may expose sensitive information about the site and the application logic.
Test Requests and Responses:
GET /me/my-views/view/all/job/01.Load_Source_UAT/lastSuccessfulBuild/logText/progressiveHtml?start=0 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer: https://99.85.165.247:9043/me/my-views/view/all/job/01.Load_Source_UAT/lastSuccessfulBuild/api/
Cookie: JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID.3b8af5e7=node0ihfl48itxzxdrnzngz6aj1a65403.node0; JSESSIONID=node0d3ra70bqwooaika5vrnbajm5760; ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE=amtzYWRtaW46MTYwMTQ1MDE2NDgyNjo1MDNiOGU3ZjRkZTQ3ZjkxMTcxYjA5MGIyNzk4OTA4MGUzZjg1NzQxNTg3YWQ2M2Y0MWNhYTI0ZjVlODc2MzFh
Connection: Keep-Alive
Host: 99.85.165.247:9043
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US
HTTP/1.1 200 OK
csrftoken: 860813526
X-XSS-Protection: 1; mode=block
Server: Jetty(9.4.z-SNAPSHOT)
Pragma: no-cache
Content-Length: 16085
X-Content-Type-Options: nosniff
Cache-Control: no-store
Strict-Transport-Security: max-age=31536000;includeSubDomains
X-Text-Size: 57507
X-ConsoleAnnotator: gJtYuPTr6Qa+zYlXiEDstErWdWVQA49NIjWuGH7Ra4qWxeDh0Lou6aluD9tHvXCciJo8+n51emfhvefutQ+GHa+TRwjyKy65/zGRHCnYYZkiSnNxR5f8vUJ3ShlC342o
Set-Cookie: JSESSIONID=node016yypp5kwa5k3swmet4bov3i8775;Secure;HttpOnly;
Date: Tue, 22 Sep 2020 02:12:47 GMT
Content-Security-Policy: default-src 'self';style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; object-src 'none'; img-src 'self';
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/html;charset=utf-8
Started by timer
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/01.Load_Source_UAT
[01.Load_Source_UAT] $ /bin/sh -xe /tmp/jenkins7826826809105985722.sh
+ cd /var/lib/jenkins/workspace/load_source_test/
+ sh rtc_load.sh '**CONFIDENTIAL 1**'
[list] NO user is being logged
[login] User(jksadmin) logged to rtc(<a href='https://10.100.65.151/ccm/'>https://10.100.65.151/ccm/</a>) successfully!
[show] Workspace 'JENKINS_UAT_PKG_migration_workspace_jksadmin' exists, and then delete it.
[unload] Unload operation completed successfully.
[delete] Workspace was successfully deleted.
[create] Workspace (5467) "JENKINS_UAT_PKG_migration_workspace_jksadmin" successfully created
scm_cmd:/var/lib/jenkins/jazz/scmtools/eclipse/scm.sh
local_dir:/var/lib/jenkins/workspace/load_source_test/
wsn :JENKINS_UAT_PKG_migration_workspace_jksadmin
reomote_dir:PROD_Build Default Component/rel/2020/Q3/Agree/20200918
[load] Successfully loaded items into the sandbox.
[list] User( jksadmin) is being logged to RTC(<a href='https://10.100.65.151/ccm/'>https://10.100.65.151/ccm/</a>) now!
[logout] User( jksadmin) is logged out successfully!
+ cd /var/lib/jenkins/workspace/scripts/prd
+ python Copyfiles_version3.py
ordered_date is ['20200918']
[SUCCESS]Today is :[20200918], RTC date dir is same as actual date
[CORRECT ZIP NAME]CTSEPAD-PRD-JENKINS-20200918091248.zip
[CORRECT ZIP NAME]TB-PRD-JENKINS-20200918114119.zip
[CORRECT ZIP NAME]TB-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]IPO-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]SYLN-PRD-JENKINS-20200918122550.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200917202121.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200918122550.zip
[CORRECT ZIP NAME]CPM-PRD-JENKINS-20200918103000.zip
[CORRECT ZIP NAME]COMMON-PRD-JENKINS-20200917202121.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200918091248.zip
[CORRECT ZIP NAME]CTS-PRD-JENKINS-20200917193727.zip
[CORRECT ZIP NAME]CTCORP-PRD-JENKINS-20200917191248.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918092143.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918142147.zip
[CORRECT ZIP NAME]CTSEPAD-PRD-JENKINS-20200918122550.zip
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CPM
each_proj is: CPM
ea
...
...
...
/var/lib/jenkins/workspace/load_source_test/20200918/Agree_Sunyard_Production Release SEQ_CTCORP_20200917191248.xlsx
10. TB
/var/lib/jenkins/workspace/load_source_test/20200918/TB-PRD-JENKINS-20200918114119.zip
/var/lib/jenkins/workspace/load_source_test/20200918/Agree_Sunyard_Production Release SEQ_TB_20200918114119.xlsx
[01.Load_Source_UAT] $ /bin/sh -xe /tmp/jenkins7217858680078432071.sh
+ cd '/var/lib/jenkins/workspace/scripts/prd/01. Load_Source'
+ python Gen01jobstatus.py
Status: 0
<b><span style="color: #00CD00;">[SUCCESS]01. Load_Source complete successfully!</span></b>
[01.Load_Source_UAT] $ /bin/sh -xe /tmp/jenkins4256702318865800287.sh
Triggering a new build of <a href='/job/02.%20Move%20migration%20packages/' class='model-link'>02. Move migration packages</a>
Finished: SUCCESS
It is possible to retrieve the source code of server-side scripts, which may expose the application logic and other sensitive information such as usernames and passwords
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
Temporary files were left in production environment
Debugging information was left by the programmer in web pages
The response contains source code of script files, which may expose sensitive information about the site and the application logic.
Test Requests and Responses:
GET /me/my-views/view/all/job/11.%20Hot%20Deployment-Branch/lastSuccessfulBuild/consoleText HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer: https://99.85.165.247:9043/me/my-views/view/all/job/11.%20Hot%20Deployment-Branch/lastSuccessfulBuild/console
Cookie: JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID.3b8af5e7=node0ihfl48itxzxdrnzngz6aj1a65403.node0; JSESSIONID=node0d3ra70bqwooaika5vrnbajm5760; ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE=amtzYWRtaW46MTYwMTQ1MDE2NDgyNjo1MDNiOGU3ZjRkZTQ3ZjkxMTcxYjA5MGIyNzk4OTA4MGUzZjg1NzQxNTg3YWQ2M2Y0MWNhYTI0ZjVlODc2MzFh
Connection: Keep-Alive
Host: 99.85.165.247:9043
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US
HTTP/1.1 200 OK
csrftoken: 442947012
X-XSS-Protection: 1; mode=block
Server: Jetty(9.4.z-SNAPSHOT)
Pragma: no-cache
Content-Length: 1831
X-Content-Type-Options: nosniff
Cache-Control: no-store
Strict-Transport-Security: max-age=31536000;includeSubDomains
Set-Cookie: JSESSIONID=node01vjm4azpkmyo3uhkai0a10xmt786;Secure;HttpOnly;
Date: Tue, 22 Sep 2020 02:12:47 GMT
Content-Security-Policy: default-src 'self';style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; object-src 'none'; img-src 'self';
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/plain;charset=utf-8
Started by upstream project "10. Start services-Master" build number 89
originally caused by:
Started by upstream project "09. Normal Deployment-Master" build number 89
originally caused by:
Started by upstream project "08. Stop Services-Master" build number 89
originally caused by:
Started by upstream project "07. Hot Deployment-Master" build number 89
originally caused by:
Started by upstream project "06. Classified Packages" build number 90
originally caused by:
Started by upstream project "05. Generate Hot Deployment List" build number 105
originally caused by:
Started by upstream project "04. Check Packages" build number 105
originally caused by:
Started by upstream project "03. Check services" build number 114
originally caused by:
Started by upstream project "02. Move migration packages" build number 214
originally caused by:
Started by upstream project "01.Load_Source_UAT" build number 239
originally caused by:
Started by timer
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/11. Hot Deployment-Branch
No emails were triggered.
[11. Hot Deployment-Branch] $ /bin/sh -xe /tmp/jenkins6263967136729302092.sh
+ cd '/var/lib/jenkins/workspace/scripts/prd/11. Hot Deployment-Branch'
+ python check_gen_Upload_Deploy_Nopwd.py
[Warning] /var/lib/jenkins/workspace/deploy_PKG/Jenkins_prd/packages/HotDeploy_List not exist!,will skip Hot deployment.
[SUCCESS]job:[10. Start services-Master] exec successful
true
Status: 0
[SUCCESS]11. Hot Deployment-Branch complete successfully!
Email was triggered for: Always
Sending email for trigger: Always
Request made to compress build log
Sending email to: taffyyan@it.cmbwinglungbank.com
Triggering a new build of 12. Stop Services-Branch
Finished: SUCCESS
It is possible to retrieve the source code of server-side scripts, which may expose the application logic and other sensitive information such as usernames and passwords
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
Temporary files were left in production environment
Debugging information was left by the programmer in web pages
It is possible to retrieve the source code of server-side scripts, which may expose the application logic and other sensitive information such as usernames and passwords
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
Temporary files were left in production environment
Debugging information was left by the programmer in web pages
The response contains source code of script files, which may expose sensitive information about the site and the application logic.
Test Requests and Responses:
GET /me/my-views/view/all/job/01.Load_Source_UAT/lastSuccessfulBuild/logText/progressiveText?start=0 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer: https://99.85.165.247:9043/me/my-views/view/all/job/01.Load_Source_UAT/lastSuccessfulBuild/api/?auto_refresh=true
Cookie: JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID.3b8af5e7=node0ihfl48itxzxdrnzngz6aj1a65403.node0; JSESSIONID=node0d3ra70bqwooaika5vrnbajm5760; ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE=amtzYWRtaW46MTYwMTQ1MDE2NDgyNjo1MDNiOGU3ZjRkZTQ3ZjkxMTcxYjA5MGIyNzk4OTA4MGUzZjg1NzQxNTg3YWQ2M2Y0MWNhYTI0ZjVlODc2MzFh; hudson_auto_refresh=true
Connection: Keep-Alive
Host: 99.85.165.247:9043
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US
HTTP/1.1 200 OK
csrftoken: -974354476
X-XSS-Protection: 1; mode=block
Server: Jetty(9.4.z-SNAPSHOT)
Pragma: no-cache
Content-Length: 14126
X-Content-Type-Options: nosniff
Cache-Control: no-store
Strict-Transport-Security: max-age=31536000;includeSubDomains
X-Text-Size: 57507
Set-Cookie: JSESSIONID=node01wx1d6vsz6d4w1hnf0wbut12oo782;Secure;HttpOnly;
Date: Tue, 22 Sep 2020 02:12:47 GMT
Content-Security-Policy: default-src 'self';style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; object-src 'none'; img-src 'self';
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/plain;charset=utf-8
Started by timer
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/01.Load_Source_UAT
[01.Load_Source_UAT] $ /bin/sh -xe /tmp/jenkins7826826809105985722.sh
+ cd /var/lib/jenkins/workspace/load_source_test/
+ sh rtc_load.sh '**CONFIDENTIAL 1**'
[list] NO user is being logged
[login] User(jksadmin) logged to rtc(https://10.100.65.151/ccm/) successfully!
[show] Workspace 'JENKINS_UAT_PKG_migration_workspace_jksadmin' exists, and then delete it.
[unload] Unload operation completed successfully.
[delete] Workspace was successfully deleted.
[create] Workspace (5467) "JENKINS_UAT_PKG_migration_workspace_jksadmin" successfully created
scm_cmd:/var/lib/jenkins/jazz/scmtools/eclipse/scm.sh
local_dir:/var/lib/jenkins/workspace/load_source_test/
wsn :JENKINS_UAT_PKG_migration_workspace_jksadmin
reomote_dir:PROD_Build Default Component/rel/2020/Q3/Agree/20200918
[load] Successfully loaded items into the sandbox.
[list] User( jksadmin) is being logged to RTC(https://10.100.65.151/ccm/) now!
[logout] User( jksadmin) is logged out successfully!
+ cd /var/lib/jenkins/workspace/scripts/prd
+ python Copyfiles_version3.py
ordered_date is ['20200918']
[SUCCESS]Today is :[20200918], RTC date dir is same as actual date
[CORRECT ZIP NAME]CTSEPAD-PRD-JENKINS-20200918091248.zip
[CORRECT ZIP NAME]TB-PRD-JENKINS-20200918114119.zip
[CORRECT ZIP NAME]TB-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]IPO-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]SYLN-PRD-JENKINS-20200918122550.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200917202121.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200918122550.zip
[CORRECT ZIP NAME]CPM-PRD-JENKINS-20200918103000.zip
[CORRECT ZIP NAME]COMMON-PRD-JENKINS-20200917202121.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200918091248.zip
[CORRECT ZIP NAME]CTS-PRD-JENKINS-20200917193727.zip
[CORRECT ZIP NAME]CTCORP-PRD-JENKINS-20200917191248.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918092143.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918142147.zip
[CORRECT ZIP NAME]CTSEPAD-PRD-JENKINS-20200918122550.zip
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CPM
each_proj is: CPM
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: IPO
each_proj i
...
...
...
/var/lib/jenkins/workspace/load_source_test/20200918/Agree_Sunyard_Production Release SEQ_CTCORP_20200917191248.xlsx
10. TB
/var/lib/jenkins/workspace/load_source_test/20200918/TB-PRD-JENKINS-20200918114119.zip
/var/lib/jenkins/workspace/load_source_test/20200918/Agree_Sunyard_Production Release SEQ_TB_20200918114119.xlsx
[01.Load_Source_UAT] $ /bin/sh -xe /tmp/jenkins7217858680078432071.sh
+ cd '/var/lib/jenkins/workspace/scripts/prd/01. Load_Source'
+ python Gen01jobstatus.py
Status: 0
[SUCCESS]01. Load_Source complete successfully!
[01.Load_Source_UAT] $ /bin/sh -xe /tmp/jenkins4256702318865800287.sh
Triggering a new build of 02. Move migration packages
Finished: SUCCESS
AppScan found a reference to cookies in the JavaScript.
Test Requests and Responses:
GET /static/50d72996/scripts/yui/cookie/cookie-min.js HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer: https://99.85.165.247:9043/
Cookie: JSESSIONID.3b8af5e7=node0ufhag3b0oozsup3wq99xd5882279.node0; JSESSIONID=node0ufhag3b0oozsup3wq99xd5882279
Connection: keep-alive
Host: 99.85.165.247:9043
Accept: */*
Accept-Language: en-US
HTTP/1.1 200 OK
Last-Modified: Mon, 14 Sep 2020 02:36:56 GMT
Server: Jetty(9.4.z-SNAPSHOT)
Accept-Ranges: bytes
Content-Length: 4556
X-Content-Type-Options: nosniff
Set-Cookie: JSESSIONID=node0ufhag3b0oozsup3wq99xd5882279;Secure;HttpOnly;
Date: Wed, 16 Sep 2020 06:25:21 GMT
Expires: Thu, 16 Sep 2021 06:25:21 GMT
Content-Type: application/javascript
/*
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 2.9.0
*/
YAHOO.namespace("util");YAHOO.util.Cookie={_createCookieString:function(B,D,C,A){var F=YAHOO.lang,E=encodeURIComponent(B)+"="+(C?encodeURIComponent(D):D);if(F.isObject(A)){if(A.expires instanceof Date){E+="; expires="+A.expires.toUTCString();}if(F.isString(A.path)&&A.path!==""){E+="; path="+A.path;}if(F.isString(A.domain)&&A.domain!==""){E+="; domain="+A.domain;}if(A.secure===true){E+="; secure";}}return E;},_createCookieHashString:function(B){var D=YAHOO.lang;if(!D.isObject(B)){throw new TypeError("Cookie._createCookieHashString(): Argument must be an object.");}var C=[];for(var A in B){if(D.hasOwnProperty(B,A)&&!D.isFunction(B[A])&&!D.isUndefined(B[A])){C.push(encodeURIComponent(A)+"="+encodeURIComponent(String(B[A])));}}return C.join("&");},_parseCookieHash:function(E){var D=E.split("&"),F=null,C={};if(E.length>0){for(var B=0,A=D.length;B<A;B++){F=D[B].split("=");C[decodeURIComponent(F[0])]=decodeURIComponent(F[1]);}}return C;},_parseCookieString:function(J,A){var K={};if(YAHOO.lang.isString(J)&&J.length>0){var B=(A===false?function(L){return L;}:decodeURIComponent);var H=J.split(/;\s/g),I=null,C=null,E=null;for(var D=0,F=H.length;D<F;D++){E=H[D].match(/([^=]+)=/i);if(E instanceof Array){try{I=decodeURIComponent(E[1]);C=B(H[D].substring(E[1].length+1));}catch(G){}}else{I=decodeURIComponent(H[D]);C="";}K[I]=C;}}return K;},exists:function(A){if(!YAHOO.lang.isString(A)||A===""){throw new TypeError("Cookie.exists(): Cookie name must be a non-empty string.");}var B=this._parseCookieString(document.cookie,true);return B.hasOwnProperty(A);},get:function(B,A){var E=YAHOO.lang,C;if(E.isFunction(A)){C=A;A={};}else{if(E.isObject(A)){C=A.converter;}else{A={};}}var D=this._parseCookieString(document.cookie,!A.raw);if(!E.isString(B)||B===""){throw new TypeError("Cookie.get(): Cookie name must be a non-empty string.");}if(E.isUndefined(D[B])){return null;}if(!E.isFunction(C)){return D[B];}else{return C(D[B]);}},getSub:function(A,C,B){var E=YAHOO.lang,D=this.getSubs(A);if(D!==null){if(!E.isString(C)||C===""){throw new TypeError("Cookie.getSub(): Subcookie name must be a
...
...
...
B)||B===""){throw new TypeError("Cookie.remove(): Cookie name must be a non-empty string.");}A=YAHOO.lang.merge(A||{},{expires:new Date(0)});return this.set(B,"",A);},removeSub:function(B,E,A){var F=YAHOO.lang;A=A||{};if(!F.isString(B)||B===""){throw new TypeError("Cookie.removeSub(): Cookie name must be a non-empty string.");}if(!F.isString(E)||E===""){throw new TypeError("Cookie.removeSub(): Subcookie name must be a non-empty string.");}var D=this.getSubs(B);if(F.isObject(D)&&F.hasOwnProperty(D,E)){delete D[E];if(!A.removeIfEmpty){return this.setSubs(B,D,A);}else{for(var C in D){if(F.hasOwnProperty(D,C)&&!F.isFunction(D[C])&&!F.isUndefined(D[C])){return this.setSubs(B,D,A);}}return this.remove(B,A);}}else{return"";}},set:function(B,C,A){var E=YAHOO.lang;A=A||{};if(!E.isString(B)){throw new TypeError("Cookie.set(): Cookie name must be a string.");}if(E.isUndefined(C)){throw new TypeError("Cookie.set(): Value cannot be undefined.");}var D=this._createCookieString(B,C,!A.raw,A);document.cookie=D;return D;},setSub:function(B,D,C,A){var F=YAHOO.lang;if(!F.isString(B)||B===""){throw new TypeError("Cookie.setSub(): Cookie name must be a non-empty string.");}if(!F.isString(D)||D===""){throw new TypeError("Cookie.setSub(): Subcookie name must be a non-empty string.");}if(F.isUndefined(C)){throw new TypeError("Cookie.setSub(): Subcookie value cannot be undefined.");}var E=this.getSubs(B);if(!F.isObject(E)){E={};}E[D]=C;return this.setSubs(B,E,A);},setSubs:function(B,C,A){var E=YAHOO.lang;if(!E.isString(B)){throw new TypeError("Cookie.setSubs(): Cookie name must be a string.");}if(!E.isObject(C)){throw new TypeError("Cookie.setSubs(): Cookie value must be an object.");}var D=this._createCookieString(B,this._createCookieHashString(C),false,A);document.cookie=D;return D;}};YAHOO.register("cookie",YAHOO.util.Cookie,{version:"2.9.0",build:"2800"});
The response contains an e-mail address that may be private.
Test Requests and Responses:
GET /me/my-views/view/all/job/11.%20Hot%20Deployment-Branch/lastSuccessfulBuild/consoleText HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer: https://99.85.165.247:9043/me/my-views/view/all/job/11.%20Hot%20Deployment-Branch/lastSuccessfulBuild/console
Cookie: JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID.3b8af5e7=node0ihfl48itxzxdrnzngz6aj1a65403.node0; JSESSIONID=node0d3ra70bqwooaika5vrnbajm5760; ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE=amtzYWRtaW46MTYwMTQ1MDE2NDgyNjo1MDNiOGU3ZjRkZTQ3ZjkxMTcxYjA5MGIyNzk4OTA4MGUzZjg1NzQxNTg3YWQ2M2Y0MWNhYTI0ZjVlODc2MzFh
Connection: Keep-Alive
Host: 99.85.165.247:9043
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US
HTTP/1.1 200 OK
csrftoken: 442947012
X-XSS-Protection: 1; mode=block
Server: Jetty(9.4.z-SNAPSHOT)
Pragma: no-cache
Content-Length: 1831
X-Content-Type-Options: nosniff
Cache-Control: no-store
Strict-Transport-Security: max-age=31536000;includeSubDomains
Set-Cookie: JSESSIONID=node01vjm4azpkmyo3uhkai0a10xmt786;Secure;HttpOnly;
Date: Tue, 22 Sep 2020 02:12:47 GMT
Content-Security-Policy: default-src 'self';style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; object-src 'none'; img-src 'self';
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/plain;charset=utf-8
Started by upstream project "10. Start services-Master" build number 89
originally caused by:
Started by upstream project "09. Normal Deployment-Master" build number 89
originally caused by:
Started by upstream project "08. Stop Services-Master" build number 89
originally caused by:
Started by upstream project "07. Hot Deployment-Master" build number 89
originally caused by:
Started by upstream project "06. Classified Packages" build number 90
originally caused by:
Started by upstream project "05. Generate Hot Deployment List" build number 105
originally caused by:
Started by upstream project "04. Check Packages" build number 105
originally caused by:
Started by upstream project "03. Check services" build number 114
originally caused by:
Started by upstream project "02. Move migration packages" build number 214
originally caused by:
Started by upstream project "01.Load_Source_UAT" build number 239
originally caused by:
Started by timer
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/11. Hot Deployment-Branch
No emails were triggered.
[11. Hot Deployment-Branch] $ /bin/sh -xe /tmp/jenkins6263967136729302092.sh
+ cd '/var/lib/jenkins/workspace/scripts/prd/11. Hot Deployment-Branch'
+ python check_gen_Upload_Deploy_Nopwd.py
[Warning] /var/lib/jenkins/workspace/deploy_PKG/Jenkins_prd/packages/HotDeploy_List not exist!,will skip Hot deployment.
[SUCCESS]job:[10. Start services-Master] exec successful
true
Status: 0
[SUCCESS]11. Hot Deployment-Branch complete successfully!
Email was triggered for: Always
Sending email for trigger: Always
Request made to compress build log
Sending email to: taffyyan@it.cmbwinglungbank.com
Triggering a new build of 12. Stop Services-Branch
Finished: SUCCESS
AppScan discovered what looks like an internal IP address in the response.
Test Requests and Responses:
GET /me/my-views/view/all/job/01.Load_Source_UAT/lastSuccessfulBuild/logText/progressiveHtml?start=0 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer: https://99.85.165.247:9043/me/my-views/view/all/job/01.Load_Source_UAT/lastSuccessfulBuild/api/
Cookie: JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID.3b8af5e7=node0ihfl48itxzxdrnzngz6aj1a65403.node0; JSESSIONID=node0d3ra70bqwooaika5vrnbajm5760; ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE=amtzYWRtaW46MTYwMTQ1MDE2NDgyNjo1MDNiOGU3ZjRkZTQ3ZjkxMTcxYjA5MGIyNzk4OTA4MGUzZjg1NzQxNTg3YWQ2M2Y0MWNhYTI0ZjVlODc2MzFh
Connection: Keep-Alive
Host: 99.85.165.247:9043
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US
HTTP/1.1 200 OK
csrftoken: 860813526
X-XSS-Protection: 1; mode=block
Server: Jetty(9.4.z-SNAPSHOT)
Pragma: no-cache
Content-Length: 16085
X-Content-Type-Options: nosniff
Cache-Control: no-store
Strict-Transport-Security: max-age=31536000;includeSubDomains
X-Text-Size: 57507
X-ConsoleAnnotator: gJtYuPTr6Qa+zYlXiEDstErWdWVQA49NIjWuGH7Ra4qWxeDh0Lou6aluD9tHvXCciJo8+n51emfhvefutQ+GHa+TRwjyKy65/zGRHCnYYZkiSnNxR5f8vUJ3ShlC342o
Set-Cookie: JSESSIONID=node016yypp5kwa5k3swmet4bov3i8775;Secure;HttpOnly;
Date: Tue, 22 Sep 2020 02:12:47 GMT
Content-Security-Policy: default-src 'self';style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; object-src 'none'; img-src 'self';
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/html;charset=utf-8
Started by timer
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/01.Load_Source_UAT
[01.Load_Source_UAT] $ /bin/sh -xe /tmp/jenkins7826826809105985722.sh
+ cd /var/lib/jenkins/workspace/load_source_test/
+ sh rtc_load.sh '**CONFIDENTIAL 1**'
[list] NO user is being logged
[login] User(jksadmin) logged to rtc(<a href='https://10.100.65.151/ccm/'>https://10.100.65.151/ccm/</a>) successfully!
[show] Workspace 'JENKINS_UAT_PKG_migration_workspace_jksadmin' exists, and then delete it.
[unload] Unload operation completed successfully.
[delete] Workspace was successfully deleted.
[create] Workspace (5467) "JENKINS_UAT_PKG_migration_workspace_jksadmin" successfully created
scm_cmd:/var/lib/jenkins/jazz/scmtools/eclipse/scm.sh
local_dir:/var/lib/jenkins/workspace/load_source_test/
wsn :JENKINS_UAT_PKG_migration_workspace_jksadmin
reomote_dir:PROD_Build Default Component/rel/2020/Q3/Agree/20200918
[load] Successfully loaded items into the sandbox.
[list] User( jksadmin) is being logged to RTC(<a href='https://10.100.65.151/ccm/'>https://10.100.65.151/ccm/</a>) now!
[logout] User( jksadmin) is logged out successfully!
+ cd /var/lib/jenkins/workspace/scripts/prd
+ python Copyfiles_version3.py
ordered_date is ['20200918']
[SUCCESS]Today is :[20200918], RTC date dir is same as actual date
[CORRECT ZIP NAME]CTSEPAD-PRD-JENKINS-20200918091248.zip
[CORRECT ZIP NAME]TB-PRD-JENKINS-20200918114119.zip
[CORRECT ZIP NAME]TB-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]IPO-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]SYLN-PRD-JENKINS-20200918122550.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200917202121.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200918122550.zip
[CORRECT ZIP NAME]CPM-PRD-JENKINS-20200918103000.zip
[CORRECT ZIP NAME]COMMON-PRD-JENKINS-20200917202121.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200918091248.zip
[CORRECT ZIP NAME]CTS-PRD-JENKINS-20200917193727.zip
[CORRECT ZIP NAME]CTCORP-PRD-JENKINS-20200917191248.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918092143.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918142147.zip
[CORRECT ZIP NAME]CTSEPAD-PRD-JENKINS-20200918122550.zip
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CPM
each_proj is: CPM
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: IPO
each_proj is: IPO
each_proj is: SYLN
each_proj is: SYLN
each_proj is: ST
each_proj is: ST
each_proj is: ST
each_proj is: ST
each_proj is: ST
each_proj is: ST
each_proj is: COMMON
each_proj is: COMMON
each_proj is: CTCORP
each_proj is: CTCORP
each_proj is: TB
each_proj is: TB
each_proj is: TB
each_proj is: TB
dict_all is: {'20200918': {'CTSEPAD': {'RedeployList': [], 'ZIP': ['CTSEPAD-PRD-JENKINS-20200918091248.zip', 'CTSEPAD-PRD-JENKINS-20200918122550.zip'], 'S
...
...
...
AppScan discovered what looks like an internal IP address in the response.
Test Requests and Responses:
GET /me/my-views/view/all/job/01.Load_Source_UAT/lastSuccessfulBuild/logText/progressiveText?start=0 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer: https://99.85.165.247:9043/me/my-views/view/all/job/01.Load_Source_UAT/lastSuccessfulBuild/api/?auto_refresh=true
Cookie: JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID.3b8af5e7=node0ihfl48itxzxdrnzngz6aj1a65403.node0; JSESSIONID=node0d3ra70bqwooaika5vrnbajm5760; ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE=amtzYWRtaW46MTYwMTQ1MDE2NDgyNjo1MDNiOGU3ZjRkZTQ3ZjkxMTcxYjA5MGIyNzk4OTA4MGUzZjg1NzQxNTg3YWQ2M2Y0MWNhYTI0ZjVlODc2MzFh; hudson_auto_refresh=true
Connection: Keep-Alive
Host: 99.85.165.247:9043
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US
HTTP/1.1 200 OK
csrftoken: -974354476
X-XSS-Protection: 1; mode=block
Server: Jetty(9.4.z-SNAPSHOT)
Pragma: no-cache
Content-Length: 14126
X-Content-Type-Options: nosniff
Cache-Control: no-store
Strict-Transport-Security: max-age=31536000;includeSubDomains
X-Text-Size: 57507
Set-Cookie: JSESSIONID=node01wx1d6vsz6d4w1hnf0wbut12oo782;Secure;HttpOnly;
Date: Tue, 22 Sep 2020 02:12:47 GMT
Content-Security-Policy: default-src 'self';style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; object-src 'none'; img-src 'self';
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/plain;charset=utf-8
Started by timer
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/01.Load_Source_UAT
[01.Load_Source_UAT] $ /bin/sh -xe /tmp/jenkins7826826809105985722.sh
+ cd /var/lib/jenkins/workspace/load_source_test/
+ sh rtc_load.sh '**CONFIDENTIAL 1**'
[list] NO user is being logged
[login] User(jksadmin) logged to rtc(https://10.100.65.151/ccm/) successfully!
[show] Workspace 'JENKINS_UAT_PKG_migration_workspace_jksadmin' exists, and then delete it.
[unload] Unload operation completed successfully.
[delete] Workspace was successfully deleted.
[create] Workspace (5467) "JENKINS_UAT_PKG_migration_workspace_jksadmin" successfully created
scm_cmd:/var/lib/jenkins/jazz/scmtools/eclipse/scm.sh
local_dir:/var/lib/jenkins/workspace/load_source_test/
wsn :JENKINS_UAT_PKG_migration_workspace_jksadmin
reomote_dir:PROD_Build Default Component/rel/2020/Q3/Agree/20200918
[load] Successfully loaded items into the sandbox.
[list] User( jksadmin) is being logged to RTC(https://10.100.65.151/ccm/) now!
[logout] User( jksadmin) is logged out successfully!
+ cd /var/lib/jenkins/workspace/scripts/prd
+ python Copyfiles_version3.py
ordered_date is ['20200918']
[SUCCESS]Today is :[20200918], RTC date dir is same as actual date
[CORRECT ZIP NAME]CTSEPAD-PRD-JENKINS-20200918091248.zip
[CORRECT ZIP NAME]TB-PRD-JENKINS-20200918114119.zip
[CORRECT ZIP NAME]TB-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]IPO-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]SYLN-PRD-JENKINS-20200918122550.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200917202121.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200918122550.zip
[CORRECT ZIP NAME]CPM-PRD-JENKINS-20200918103000.zip
[CORRECT ZIP NAME]COMMON-PRD-JENKINS-20200917202121.zip
[CORRECT ZIP NAME]ST-PRD-JENKINS-20200918091248.zip
[CORRECT ZIP NAME]CTS-PRD-JENKINS-20200917193727.zip
[CORRECT ZIP NAME]CTCORP-PRD-JENKINS-20200917191248.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918092143.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918105231.zip
[CORRECT ZIP NAME]CAAS-PRD-JENKINS-20200918142147.zip
[CORRECT ZIP NAME]CTSEPAD-PRD-JENKINS-20200918122550.zip
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CTSEPAD
each_proj is: CPM
each_proj is: CPM
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CTS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: CAAS
each_proj is: IPO
each_proj is: IPO
each_proj is: SYLN
each_proj is: SYLN
each_proj is: ST
each_proj is: ST
each_proj is: ST
each_proj is: ST
each_proj is: ST
each_proj is: ST
each_proj is: COMMON
each_proj is: COMMON
each_proj is: CTCORP
each_proj is: CTCORP
each_proj is: TB
each_proj is: TB
each_proj is: TB
each_proj is: TB
dict_all is: {'20200918': {'CTSEPAD': {'RedeployList': [], 'ZIP': ['CTSEPAD-PRD-JENKINS-20200918091248.zip', 'CTSEPAD-PRD-JENKINS-20200918122550.zip'], 'SequenceList': ['Agree_Sunyard_Production Release SEQ_CTSEPAD_20200918091248.xlsx', 'Agree_Sunyard_Production Release SEQ_CTSEPAD_20200918122550.xlsx']}, 'CPM': {'RedeployList': [], 'ZIP': ['CPM-PRD-JENKINS-20200918103000.zip'], 'SequenceList': ['Agree_Sunyard_Production Re
...
...
...
It is possible to retrieve the absolute path of the web server installation, which might help an attacker to develop further attacks and to gain information about the file system structure of the web application
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
It is possible to retrieve the absolute path of the web server installation, which might help an attacker to develop further attacks and to gain information about the file system structure of the web application
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
It is possible to retrieve the absolute path of the web server installation, which might help an attacker to develop further attacks and to gain information about the file system structure of the web application
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
It is possible to retrieve the absolute path of the web server installation, which might help an attacker to develop further attacks and to gain information about the file system structure of the web application
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
It is possible to retrieve the absolute path of the web server installation, which might help an attacker to develop further attacks and to gain information about the file system structure of the web application
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
The response contains the absolute paths and/or filenames of files on the server.
Test Requests and Responses:
GET /me/my-views/view/all/job/11.%20Hot%20Deployment-Branch/lastSuccessfulBuild/consoleText HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer: https://99.85.165.247:9043/me/my-views/view/all/job/11.%20Hot%20Deployment-Branch/lastSuccessfulBuild/console
Cookie: JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID=node0ihfl48itxzxdrnzngz6aj1a65403; JSESSIONID.3b8af5e7=node0ihfl48itxzxdrnzngz6aj1a65403.node0; JSESSIONID=node0d3ra70bqwooaika5vrnbajm5760; ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE=amtzYWRtaW46MTYwMTQ1MDE2NDgyNjo1MDNiOGU3ZjRkZTQ3ZjkxMTcxYjA5MGIyNzk4OTA4MGUzZjg1NzQxNTg3YWQ2M2Y0MWNhYTI0ZjVlODc2MzFh
Connection: Keep-Alive
Host: 99.85.165.247:9043
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US
HTTP/1.1 200 OK
csrftoken: 442947012
X-XSS-Protection: 1; mode=block
Server: Jetty(9.4.z-SNAPSHOT)
Pragma: no-cache
Content-Length: 1831
X-Content-Type-Options: nosniff
Cache-Control: no-store
Strict-Transport-Security: max-age=31536000;includeSubDomains
Set-Cookie: JSESSIONID=node01vjm4azpkmyo3uhkai0a10xmt786;Secure;HttpOnly;
Date: Tue, 22 Sep 2020 02:12:47 GMT
Content-Security-Policy: default-src 'self';style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; object-src 'none'; img-src 'self';
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/plain;charset=utf-8
Started by upstream project "10. Start services-Master" build number 89
originally caused by:
Started by upstream project "09. Normal Deployment-Master" build number 89
originally caused by:
Started by upstream project "08. Stop Services-Master" build number 89
originally caused by:
Started by upstream project "07. Hot Deployment-Master" build number 89
originally caused by:
Started by upstream project "06. Classified Packages" build number 90
originally caused by:
Started by upstream project "05. Generate Hot Deployment List" build number 105
originally caused by:
Started by upstream project "04. Check Packages" build number 105
originally caused by:
Started by upstream project "03. Check services" build number 114
originally caused by:
Started by upstream project "02. Move migration packages" build number 214
originally caused by:
Started by upstream project "01.Load_Source_UAT" build number 239
originally caused by:
Started by timer
Running as SYSTEM
Building in workspace /var/lib/jenkins/workspace/11. Hot Deployment-Branch
No emails were triggered.
[11. Hot Deployment-Branch] $ /bin/sh -xe /tmp/jenkins6263967136729302092.sh
+ cd '/var/lib/jenkins/workspace/scripts/prd/11. Hot Deployment-Branch'
+ python check_gen_Upload_Deploy_Nopwd.py
[Warning] /var/lib/jenkins/workspace/deploy_PKG/Jenkins_prd/packages/HotDeploy_List not exist!,will skip Hot deployment.
[SUCCESS]job:[10. Start services-Master] exec successful
true
Status: 0
[SUCCESS]11. Hot Deployment-Branch complete successfully!
Email was triggered for: Always
Sending email for trigger: Always
Request made to compress build log
Sending email to: taffyyan@it.cmbwinglungbank.com
Triggering a new build of 12. Stop Services-Branch
Finished: SUCCESS
It is possible to retrieve the absolute path of the web server installation, which might help an attacker to develop further attacks and to gain information about the file system structure of the web application
Causes:
Latest patches or hotfixes for 3rd. party products were not installed
[1] In case the vulnerability is in the application itself, fix the server code so it doesn’t include file locations in any output.
[2] Otherwise, if the application is in a 3rd party product, download the relevant security patch depending on the 3rd party product you are using on your web server or web application.
L
Remove business and security logic from the client side
Contact your Certificate Authority and update your SSL certificate. Make sure that all attributes such as the validation date, expiration date, common name, etc. are correct.
L
Verify that parameter values are in their expected ranges and types. Do not output debugging error messages and exceptions
[1] Check incoming requests for the presence of all expected parameters and values. When a parameter is missing, issue a proper error message or use default values.
[2] The application should verify that its input consists of valid characters (after decoding). For example, an input value containing the null byte (encoded as %00), apostrophe, quotes, etc. should be rejected.
[3] Enforce values in their expected ranges and types. If your application expects a certain parameter to have a value from a certain set, then the application should ensure that the value it receives indeed belongs to the set. For example, if your application expects a value in the range 10..99, then it should make sure that the value is indeed numeric, and that its value is in 10..99.
[4] Verify that the data belongs to the set offered to the client.
[5] Do not output debugging error messages and exceptions in a production environment.
Integer Overflow
[1] Check incoming requests for the presence of all expected parameters and values. When a parameter is missing, issue a proper error message or use default values.
[2] The application should verify that its input consists of valid characters (after decoding). For example, an input value containing the null byte (encoded as %00), apostrophe, quotes, etc. should be rejected.
[3] Enforce values in their expected ranges and types. If your application expects a certain parameter to have a value from a certain set, then the application should ensure that the value it receives indeed belongs to the set. For example, if your application expects a value in the range 10..99, then it should make sure that the value is indeed numeric, and that its value is in 10..99.
[4] Verify that the data belongs to the set offered to the client.
[5] Do not output debugging error messages and exceptions in a production environment.
.Net
Application Error
In order to disable debugging in ASP.NET, edit your web.config file to contain the following:
<compilation
debug="false"
/>
For more information, see "HOW TO: Disable Debugging for ASP.NET Applications" in:
You can add input validation to Web Forms pages by using validation controls. Validation controls provide an easy-to-use mechanism for all common types of standard validation (for example, testing for valid dates or values within a range), plus ways to provide custom-written validation. In addition, validation controls allow you to completely customize how error information is displayed to the user. Validation controls can be used with any controls that are processed in a Web Forms page's class file, including both HTML and Web server controls.
To make sure that all the required parameters exist in a request, use the "RequiredFieldValidator" validation control. This control ensures that the user does not skip an entry in the web form.
To make sure user input contains only valid values, you can use one of the following validation controls:
[1] "RangeValidator": checks that a user's entry (value) is between specified lower and upper boundaries. You can check ranges within pairs of numbers, alphabetic characters, and dates.
[2] "RegularExpressionValidator": checks that the entry matches a pattern defined by a regular expression. This type of validation allows you to check for predictable sequences of characters, such as those in social security numbers, e-mail addresses, telephone numbers, postal codes, and so on.
Important note: validation controls do not block user input or change the flow of page processing; they only set an error state, and produce error messages. It is the programmer's responsibility to test the state of the controls in the code before performing further application-specific actions.
There are two ways to check for user input validity:
1. Test for a general error state:
In your code, test the page's IsValid property. This property rolls up the values of the IsValid properties of all the validation controls on the page (using a logical AND). If one of the validation controls is set to invalid, the page's property will return false.
2. Test for the error state of individual controls:
Loop through the page's Validators collection, which contains references to all the validation controls. You can then examine the IsValid property of each validation control.
Integer Overflow
In order to disable debugging in ASP.NET, edit your web.config file to contain the following:
<compilation
debug="false"
/>
For more information, see "HOW TO: Disable Debugging for ASP.NET Applications" in:
You can add input validation to Web Forms pages by using validation controls. Validation controls provide an easy-to-use mechanism for all common types of standard validation (for example, testing for valid dates or values within a range), plus ways to provide custom-written validation. In addition, validation controls allow you to completely customize how error information is displayed to the user. Validation controls can be used with any controls that are processed in a Web Forms page's class file, including both HTML and Web server controls.
To make sure that all the required parameters exist in a request, use the "RequiredFieldValidator" validation control. This control ensures that the user does not skip an entry in the web form.
To make sure user input contains only valid values, you can use one of the following validation controls:
[1] "RangeValidator": checks that a user's entry (value) is between specified lower and upper boundaries. You can check ranges within pairs of numbers, alphabetic characters, and dates.
[2] "RegularExpressionValidator": checks that the entry matches a pattern defined by a regular expression. This type of validation allows you to check for predictable sequences of characters, such as those in social security numbers, e-mail addresses, telephone numbers, postal codes, and so on.
Important note: validation controls do not block user input or change the flow of page processing; they only set an error state, and produce error messages. It is the programmer's responsibility to test the state of the controls in the code before performing further application-specific actions.
There are two ways to check for user input validity:
1. Test for a general error state:
In your code, test the page's IsValid property. This property rolls up the values of the IsValid properties of all the validation controls on the page (using a logical AND). If one of the validation controls is set to invalid, the page's property will return false.
2. Test for the error state of individual controls:
Loop through the page's Validators collection, which contains references to all the validation controls. You can then examine the IsValid property of each validation control.
J2EE
Application Error
** Input Data Validation:
While data validations may be provided as a user convenience on the client-tier, data validation must be performed on the server-tier using Servlets. Client-side validations are inherently insecure because they can be easily bypassed, e.g. by disabling Javascript.
A good design usually requires the web application framework to provide server-side utility routines to validate the following:
[1] Required field
[2] Field data type (all HTTP request parameters are Strings by default)
[3] Field length
[4] Field range
[5] Field options
[6] Field pattern
[7] Cookie values
[8] HTTP Response
A good practice is to implement the above routine as static methods in a "Validator" utility class. The following sections describe an example validator class.
[1] Required field
Always check that the field is not null and its length is greater than zero, excluding leading and trailing white spaces.
Example of how to validate required fields:
// Java example to validate required fields
public Class Validator {
...
public static boolean validateRequired(String value) {
boolean isFieldValid = false;
if (value != null && value.trim().length() > 0) {
isFieldValid = true;
}
return isFieldValid;
}
...
}
...
String fieldValue = request.getParameter("fieldName");
if (Validator.validateRequired(fieldValue)) {
// fieldValue is valid, continue processing request
...
}
[2] Field data type
In web applications, input parameters are poorly typed. For example, all HTTP request parameters or cookie values are of type String. The developer is responsible for verifying the input is of the correct data type. Use the Java primitive wrapper classes to check if the field value can be safely converted to the desired primitive data type.
Example of how to validate a numeric field (type int):
// Java example to validate that a field is an int number
public Class Validator {
...
public static boolean validateInt(String value) {
boolean isFieldValid = false;
try {
Integer.parseInt(value);
isFieldValid = true;
} catch (Exception e) {
isFieldValid = false;
}
return isFieldValid;
}
...
}
...
// check if the HTTP request parameter is of type int
String fieldValue = request.getParameter("fieldName");
if (Validator.validateInt(fieldValue)) {
// fieldValue is valid, continue processing request
...
}
A good practice is to convert all HTTP request parameters to their respective data types. For example, store the "integerValue" of a request parameter in a request attribute and use it as shown in the following example:
// Example to convert the HTTP request parameter to a primitive wrapper data type
// and store this value in a request attribute for further processing
String fieldValue = request.getParameter("fieldName");
if (Validator.validateInt(fieldValue)) {
// convert fieldValue to an Integer
Integer integerValue = Integer.getInteger(fieldValue);
// store integerValue in a request attribute
request.setAttribute("fieldName", integerValue);
}
...
// Use the request attribute for further processing
Integer integerValue = (Integer)request.getAttribute("fieldName");
...
The primary Java data types that the application should handle:
- Byte
- Short
- Integer
- Long
- Float
- Double
- Date
[3] Field length
Always ensure that the input parameter (whether HTTP request parameter or cookie value) is bounded by a minimum length and/or a maximum length.
Example to validate that the length of the userName field is between 8 and 20 characters:
// Example to validate the field length
public Class Validator {
...
public static boolean validateLength(String value, int minLength, int maxLength) {
String validatedValue = value;
if (!validateRequired(value)) {
validatedValue = "";
}
return (validatedValue.length() >= minLength &&
validatedValue.length() <= maxLength);
}
...
}
...
String userName = request.getParameter("userName");
if (Validator.validateRequired(userName)) {
if (Validator.validateLength(userName, 8, 20)) {
// userName is valid, continue further processing
...
}
}
[4] Field range
Always ensure that the input parameter is within a range as defined by the functional requirements.
Example to validate that the input numberOfChoices is between 10 and 20:
// Example to validate the field range
public Class Validator {
...
public static boolean validateRange(int value, int min, int max) {
return (value >= min && value <= max);
}
...
}
...
String fieldValue = request.getParameter("numberOfChoices");
if (Validator.validateRequired(fieldValue)) {
if (Validator.validateInt(fieldValue)) {
int numberOfChoices = Integer.parseInt(fieldValue);
if (Validator.validateRange(numberOfChoices, 10, 20)) {
// numberOfChoices is valid, continue processing request
...
}
}
}
[5] Field options
Often, the web application presents the user with a set of options to choose from, e.g. using the SELECT HTML tag, but fails to perform server-side validation to ensure that the selected value is one of the allowed options. Remember that a malicious user can easily modify any option value. Always validate the selected user value against the allowed options as defined by the functional requirements.
Example to validate the user selection against a list of allowed options:
// Example to validate user selection against a list of options
public Class Validator {
...
public static boolean validateOption(Object[] options, Object value) {
boolean isValidValue = false;
try {
List list = Arrays.asList(options);
if (list != null) {
isValidValue = list.contains(value);
}
} catch (Exception e) {
}
return isValidValue;
}
...
}
...
// Allowed options
String[] options = {"option1", "option2", "option3");
// Verify that the user selection is one of the allowed options
String userSelection = request.getParameter("userSelection");
if (Validator.validateOption(options, userSelection)) {
// valid user selection, continue processing request
...
}
[6] Field pattern
Always check that the user input matches a pattern as defined by the functionality requirements. For example, if the userName field should only allow alpha-numeric characters, case insensitive, then use the following regular expression:
^[a-zA-Z0-9]*$
Java 1.3 or earlier versions do not include any regular expression packages. Apache Regular Expression Package (see Resources below) is recommended for use with Java 1.3 to resolve this lack of support.
Example to perform regular expression validation:
// Example to validate that a given value matches a specified pattern
// using the Apache regular expression package
import org.apache.regexp.RE;
import org.apache.regexp.RESyntaxException;
public Class Validator {
...
public static boolean matchPattern(String value, String expression) {
boolean match = false;
if (validateRequired(expression)) {
RE r = new RE(expression);
match = r.match(value);
}
return match;
}
...
}
...
// Verify that the userName request parameter is alpha-numeric
String userName = request.getParameter("userName");
if (Validator.matchPattern(userName, "^[a-zA-Z0-9]*$")) {
// userName is valid, continue processing request
...
}
Java 1.4 introduced a new regular expression package (java.util.regex). Here is a modified version of Validator.matchPattern using the new Java 1.4 regular expression package:
// Example to validate that a given value matches a specified pattern
// using the Java 1.4 regular expression package
import java.util.regex.Pattern;
import java.util.regexe.Matcher;
public Class Validator {
...
public static boolean matchPattern(String value, String expression) {
boolean match = false;
if (validateRequired(expression)) {
match = Pattern.matches(expression, value);
}
return match;
}
...
}
[7] Cookie value
Use the javax.servlet.http.Cookie object to validate the cookie value. The same validation rules (described above) apply to cookie values depending on the application requirements, e.g. validate a required value, validate length, etc.
Example to validate a required cookie value:
// Example to validate a required cookie value
// First retrieve all available cookies submitted in the HTTP request
Cookie[] cookies = request.getCookies();
if (cookies != null) {
// find the "user" cookie
for (int i=0; i<cookies.length; ++i) {
if (cookies[i].getName().equals("user")) {
// validate the cookie value
if (Validator.validateRequired(cookies[i].getValue()) {
// valid cookie value, continue processing request
...
}
}
}
}
[8] HTTP Response
[8-1] Filter user input
To guard the application against cross-site scripting, sanitize HTML by converting sensitive characters to their corresponding character entities. These are the HTML sensitive characters:
< > " ' % ; ) ( & +
Example to filter a specified string by converting sensitive characters to their corresponding character entities:
// Example to filter sensitive data to prevent cross-site scripting
public Class Validator {
...
public static String filter(String value) {
if (value == null) {
return null;
}
StringBuffer result = new StringBuffer(value.length());
for (int i=0; i<value.length(); ++i) {
switch (value.charAt(i)) {
case '<':
result.append("<");
break;
case '>':
result.append(">");
break;
case '"':
result.append(""");
break;
case '\'':
result.append("'");
break;
case '%':
result.append("%");
break;
case ';':
result.append(";");
break;
case '(':
result.append("(");
break;
case ')':
result.append(")");
break;
case '&':
result.append("&");
break;
case '+':
result.append("+");
break;
default:
result.append(value.charAt(i));
break;
}
return result;
}
...
}
...
// Filter the HTTP response using Validator.filter
PrintWriter out = response.getWriter();
// set output response
out.write(Validator.filter(response));
out.close();
The Java Servlet API 2.3 introduced Filters, which supports the interception and transformation of HTTP requests or responses.
Example of using a Servlet Filter to sanitize the response using Validator.filter:
// Example to filter all sensitive characters in the HTTP response using a Java Filter.
// This example is for illustration purposes since it will filter all content in the response, including HTML tags!
public class SensitiveCharsFilter implements Filter {
...
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
PrintWriter out = response.getWriter();
ResponseWrapper wrapper = new ResponseWrapper((HttpServletResponse)response);
chain.doFilter(request, wrapper);
CharArrayWriter caw = new CharArrayWriter();
caw.write(Validator.filter(wrapper.toString()));
response.setContentType("text/html");
response.setContentLength(caw.toString().length());
out.write(caw.toString());
out.close();
}
...
public class CharResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter output;
public String toString() {
return output.toString();
}
public CharResponseWrapper(HttpServletResponse response){
super(response);
output = new CharArrayWriter();
}
public PrintWriter getWriter(){
return new PrintWriter(output);
}
}
}
}
[8-2] Secure the cookie
When storing sensitive data in a cookie, make sure to set the secure flag of the cookie in the HTTP response, using Cookie.setSecure(boolean flag) to instruct the browser to send the cookie using a secure protocol, such as HTTPS or SSL.
Example to secure the "user" cookie:
// Example to secure a cookie, i.e. instruct the browser to
// send the cookie using a secure protocol
Cookie cookie = new Cookie("user", "sensitive");
cookie.setSecure(true);
response.addCookie(cookie);
RECOMMENDED JAVA TOOLS
The two main Java frameworks for server-side validation are:
[1] Jakarta Commons Validator (integrated with Struts 1.1)
The Jakarta Commons Validator is a powerful framework that implements all the above data validation requirements. These rules are configured in an XML file that defines input validation rules for form fields. Struts supports output filtering of dangerous characters in the [8] HTTP Response by default on all data written using the Struts 'bean:write' tag. This filtering may be disabled by setting the 'filter=false' flag.
Struts defines the following basic input validators, but custom validators may also be defined:
required: succeeds if the field contains any characters other than white space.
mask: succeeds if the value matches the regular expression given by the mask attribute.
range: succeeds if the value is within the values given by the min and max attributes ((value >= min) & (value <= max)).
maxLength: succeeds if the field is length is less than or equal to the max attribute.
minLength: succeeds if the field is length is greater than or equal to the min attribute.
byte, short, integer, long, float, double: succeeds if the value can be converted to the corresponding primitive.
date: succeeds if the value represents a valid date. A date pattern may be provided.
creditCard: succeeds if the value could be a valid credit card number.
e-mail: succeeds if the value could be a valid e-mail address.
Example to validate the userName field of a loginForm using Struts Validator:
<form-validation>
<global>
...
<validator name="required"
classname="org.apache.struts.validator.FieldChecks"
method="validateRequired"
msg="errors.required">
</validator>
<validator name="mask"
classname="org.apache.struts.validator.FieldChecks"
method="validateMask"
msg="errors.invalid">
</validator>
...
</global>
<formset>
<form name="loginForm">
<!-- userName is required and is alpha-numeric case insensitive -->
<field property="userName" depends="required,mask">
<!-- message resource key to display if validation fails -->
<msg name="mask" key="login.userName.maskmsg"/>
<arg0 key="login.userName.displayname"/>
<var>
<var-name>mask</var-name>
<var-value>^[a-zA-Z0-9]*$</var-value>
</var>
</field>
...
</form>
...
</formset>
</form-validation>
[2] JavaServer Faces Technology
JavaServer Faces Technology is a set of Java APIs (JSR 127) to represent UI components, manage their state, handle events and input validation.
The JavaServer Faces API implements the following basic validators, but custom validators may be defined:
validate_doublerange: registers a DoubleRangeValidator on a component
validate_length: registers a LengthValidator on a component
validate_longrange: registers a LongRangeValidator on a component
validate_required: registers a RequiredValidator on a component
validate_stringrange: registers a StringRangeValidator on a component
validator: registers a custom Validator on a component
The JavaServer Faces API defines the following UIInput and UIOutput Renderers (Tags):
input_date: accepts a java.util.Date formatted with a java.text.Date instance
output_date: displays a java.util.Date formatted with a java.text.Date instance
input_datetime: accepts a java.util.Date formatted with a java.text.DateTime instance
output_datetime: displays a java.util.Date formatted with a java.text.DateTime instance
input_number: displays a numeric data type (java.lang.Number or primitive), formatted with a java.text.NumberFormat
output_number: displays a numeric data type (java.lang.Number or primitive), formatted with a java.text.NumberFormat
input_text: accepts a text string of one line.
output_text: displays a text string of one line.
input_time: accepts a java.util.Date, formatted with a java.text.DateFormat time instance
output_time: displays a java.util.Date, formatted with a java.text.DateFormat time instance
input_hidden: allows a page author to include a hidden variable in a page
input_secret: accepts one line of text with no spaces and displays it as a set of asterisks as it is typed
input_textarea: accepts multiple lines of text
output_errors: displays error messages for an entire page or error messages associated with a specified client identifier
output_label: displays a nested component as a label for a specified input field
output_message: displays a localized message
Example to validate the userName field of a loginForm using JavaServer Faces:
Many J2EE web application architectures follow the Model View Controller (MVC) pattern. In this pattern a Servlet acts as a Controller. A Servlet delegates the application processing to a JavaBean such as an EJB Session Bean (the Model). The Servlet then forwards the request to a JSP (View) to render the processing results. Servlets should check all input, output, return codes, error codes and known exceptions to ensure that the expected processing actually occurred.
While data validation protects applications against malicious data tampering, a sound error handling strategy is necessary to prevent the application from inadvertently disclosing internal error messages such as exception stack traces. A good error handling strategy addresses the following items:
[1] Defining Errors
[2] Reporting Errors
[3] Rendering Errors
[4] Error Mapping
[1] Defining Errors
Hard-coded error messages in the application layer (e.g. Servlets) should be avoided. Instead, the application should use error keys that map to known application failures. A good practice is to define error keys that map to validation rules for HTML form fields or other bean properties. For example, if the "user_name" field is required, is alphanumeric, and must be unique in the database, then the following error keys should be defined:
(a) ERROR_USERNAME_REQUIRED: this error key is used to display a message notifying the user that the "user_name" field is required;
(b) ERROR_USERNAME_ALPHANUMERIC: this error key is used to display a message notifying the user that the "user_name" field should be alphanumeric;
(c) ERROR_USERNAME_DUPLICATE: this error key is used to display a message notifying the user that the "user_name" value is a duplicate in the database;
(d) ERROR_USERNAME_INVALID: this error key is used to display a generic message notifying the user that the "user_name" value is invalid;
A good practice is to define the following framework Java classes which are used to store and report application errors:
- ErrorKeys: defines all error keys
// Example: ErrorKeys defining the following error keys:
// - ERROR_USERNAME_REQUIRED
// - ERROR_USERNAME_ALPHANUMERIC
// - ERROR_USERNAME_DUPLICATE
// - ERROR_USERNAME_INVALID
// ...
public Class ErrorKeys {
public static final String ERROR_USERNAME_REQUIRED = "error.username.required";
public static final String ERROR_USERNAME_ALPHANUMERIC = "error.username.alphanumeric";
public static final String ERROR_USERNAME_DUPLICATE = "error.username.duplicate";
public static final String ERROR_USERNAME_INVALID = "error.username.invalid";
...
}
- Error: encapsulates an individual error
// Example: Error encapsulates an error key.
// Error is serializable to support code executing in multiple JVMs.
public Class Error implements Serializable {
// Constructor given a specified error key
public Error(String key) {
this(key, null);
}
// Constructor given a specified error key and array of placeholder objects
public Error(String key, Object[] values) {
this.key = key;
this.values = values;
}
// Returns the error key
public String getKey() {
return this.key;
}
// Returns the placeholder values
public Object[] getValues() {
return this.values;
}
private String key = null;
private Object[] values = null;
}
- Errors: encapsulates a Collection of errors
// Example: Errors encapsulates the Error objects being reported to the presentation layer.
// Errors are stored in a HashMap where the key is the bean property name and value is an
// ArrayList of Error objects.
public Class Errors implements Serializable {
// Adds an Error object to the Collection of errors for the specified bean property.
public void addError(String property, Error error) {
ArrayList propertyErrors = (ArrayList)errors.get(property);
if (propertyErrors == null) {
propertyErrors = new ArrayList();
errors.put(property, propertyErrors);
}
propertyErrors.put(error);
}
// Returns true if there are any errors
public boolean hasErrors() {
return (errors.size > 0);
}
// Returns the Errors for the specified property
public ArrayList getErrors(String property) {
return (ArrayList)errors.get(property);
}
private HashMap errors = new HashMap();
}
Using the above framework classes, here is an example to process validation errors of the "user_name" field:
// Example to process validation errors of the "user_name" field.
Errors errors = new Errors();
String userName = request.getParameter("user_name");
// (a) Required validation rule
if (!Validator.validateRequired(userName)) {
errors.addError("user_name", new Error(ErrorKeys.ERROR_USERNAME_REQUIRED));
} // (b) Alpha-numeric validation rule
else if (!Validator.matchPattern(userName, "^[a-zA-Z0-9]*$")) {
errors.addError("user_name", new Error(ErrorKeys.ERROR_USERNAME_ALPHANUMERIC));
}
else
{
// (c) Duplicate check validation rule
// We assume that there is an existing UserValidationEJB session bean that implements
// a checkIfDuplicate() method to verify if the user already exists in the database.
try {
...
if (UserValidationEJB.checkIfDuplicate(userName)) {
errors.addError("user_name", new Error(ErrorKeys.ERROR_USERNAME_DUPLICATE));
}
} catch (RemoteException e) {
// log the error
logger.error("Could not validate user for specified userName: " + userName);
errors.addError("user_name", new Error(ErrorKeys.ERROR_USERNAME_DUPLICATE);
}
}
// set the errors object in a request attribute called "errors"
request.setAttribute("errors", errors);
...
[2] Reporting Errors
There are two ways to report web-tier application errors:
(a) Servlet Error Mechanism
(b) JSP Error Mechanism
[2-a] Servlet Error Mechanism
A Servlet may report errors by:
- forwarding to the input JSP (having already stored the errors in a request attribute), OR
- calling response.sendError with an HTTP error code argument, OR
- throwing an exception
It is good practice to process all known application errors (as described in section [1]), store them in a request attribute, and forward to the input JSP. The input JSP should display the error messages and prompt the user to re-enter the data. The following example illustrates how to forward to an input JSP (userInput.jsp):
// Example to forward to the userInput.jsp following user validation errors
RequestDispatcher rd = getServletContext().getRequestDispatcher("/user/userInput.jsp");
if (rd != null) {
rd.forward(request, response);
}
If the Servlet cannot forward to a known JSP page, the second option is to report an error using the response.sendError method with HttpServletResponse.SC_INTERNAL_SERVER_ERROR (status code 500) as argument. Refer to the javadoc of javax.servlet.http.HttpServletResponse for more details on the various HTTP status codes.
Example to return a HTTP error:
// Example to return a HTTP error code
RequestDispatcher rd = getServletContext().getRequestDispatcher("/user/userInput.jsp");
if (rd == null) {
// messages is a resource bundle with all message keys and values
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
messages.getMessage(ErrorKeys.ERROR_USERNAME_INVALID));
}
As a last resort, Servlets can throw an exception, which must be a subclass of one of the following classes:
- RuntimeException
- ServletException
- IOException
[2-b] JSP Error Mechanism
JSP pages provide a mechanism to handle runtime exceptions by defining an errorPage directive as shown in the following example:
Uncaught JSP exceptions are forwarded to the specified errorPage, and the original exception is set in a request parameter called javax.servlet.jsp.jspException. The error page must include a isErrorPage directive as shown below:
<%@ page isErrorPage="true" %>
The isErrorPage directive causes the "exception" variable to be initialized to the exception object being thrown.
[3] Rendering Errors
The J2SE Internationalization APIs provide utility classes for externalizing application resources and formatting messages including:
(a) Resource Bundles
(b) Message Formatting
[3-a] Resource Bundles
Resource bundles support internationalization by separating localized data from the source code that uses it. Each resource bundle stores a map of key/value pairs for a specific locale.
It is common to use or extend java.util.PropertyResourceBundle, which stores the content in an external properties file as shown in the following example:
################################################
# ErrorMessages.properties
################################################
# required user name error message
error.username.required=User name field is required
# invalid user name format
error.username.alphanumeric=User name must be alphanumeric
# duplicate user name error message
error.username.duplicate=User name {0} already exists, please choose another one
...
Multiple resources can be defined to support different locales (hence the name resource bundle). For example, ErrorMessages_fr.properties can be defined to support the French member of the bundle family. If the resource member of the requested locale does not exist, the default member is used. In the above example, the default resource is ErrorMessages.properties. Depending on the user's locale, the application (JSP or Servlet) retrieves content from the appropriate resource.
[3-b] Message Formatting
The J2SE standard class java.util.MessageFormat provides a generic way to create messages with replacement placeholders. A MessageFormat object contains a pattern string with embedded format specifiers as shown below:
// Example to show how to format a message using placeholder parameters
String pattern = "User name {0} already exists, please choose another one";
String userName = request.getParameter("user_name");
Object[] args = new Object[1];
args[0] = userName;
String message = MessageFormat.format(pattern, args);
Here is a more comprehensive example to render error messages using ResourceBundle and MessageFormat:
// Example to render an error message from a localized ErrorMessages resource (properties file)
// Utility class to retrieve locale-specific error messages
public Class ErrorMessageResource {
// Returns the error message for the specified error key in the environment locale
public String getErrorMessage(String errorKey) {
return getErrorMessage(errorKey, defaultLocale);
}
// Returns the error message for the specified error key in the specified locale
public String getErrorMessage(String errorKey, Locale locale) {
return getErrorMessage(errorKey, null, locale);
}
// Returns a formatted error message for the specified error key in the specified locale
public String getErrorMessage(String errorKey, Object[] args, Locale locale) {
// Get localized ErrorMessageResource
ResourceBundle errorMessageResource = ResourceBundle.getBundle("ErrorMessages", locale);
// Get localized error message
String errorMessage = errorMessageResource.getString(errorKey);
if (args != null) {
// Format the message using the specified placeholders args
return MessageFormat.format(errorMessage, args);
} else {
return errorMessage;
}
}
// default environment locale
private Locale defaultLocale = Locale.getDefaultLocale();
}
...
// Get the user's locale
Locale userLocale = request.getLocale();
// Check if there were any validation errors
Errors errors = (Errors)request.getAttribute("errors");
if (errors != null && errors.hasErrors()) {
// iterate through errors and output error messages corresponding to the "user_name" property
ArrayList userNameErrors = errors.getErrors("user_name");
ListIterator iterator = userNameErrors.iterator();
while (iterator.hasNext()) {
// Get the next error object
Error error = (Error)iterator.next();
String errorMessage = ErrorMessageResource.getErrorMessage(error.getKey(), userLocale);
output.write(errorMessage + "\r\n");
}
}
It is recommended to define a custom JSP tag, e.g. displayErrors, to iterate through and render error messages as shown in the above example.
[4] Error Mapping
Normally, the Servlet Container will return a default error page corresponding to either the response status code or the exception. A mapping between the status code or the exception and a web resource may be specified using custom error pages. It is a good practice to develop static error pages that do not disclose internal error states (by default, most Servlet containers will report internal error messages). This mapping is configured in the Web Deployment Descriptor (web.xml) as specified in the following example:
<!-- Mapping of HTTP error codes and application exceptions to error pages -->
<error-page>
<exception-type>UserValidationException</exception-type>
<location>/errors/validationError.html</error-page>
</error-page>
<error-page>
<error-code>500</exception-type>
<location>/errors/internalError.html</error-page>
</error-page>
<error-page>
...
</error-page>
...
RECOMMENDED JAVA TOOLS
The two main Java frameworks for server-side validation are:
[1] Jakarta Commons Validator (integrated with Struts 1.1)
The Jakarta Commons Validator is a Java framework that defines the error handling mechanism as described above. Validation rules are configured in an XML file that defines input validation rules for form fields and the corresponding validation error keys. Struts provides internationalization support to build localized applications using resource bundles and message formatting.
Example to validate the userName field of a loginForm using Struts Validator:
<form-validation>
<global>
...
<validator name="required"
classname="org.apache.struts.validator.FieldChecks"
method="validateRequired"
msg="errors.required">
</validator>
<validator name="mask"
classname="org.apache.struts.validator.FieldChecks"
method="validateMask"
msg="errors.invalid">
</validator>
...
</global>
<formset>
<form name="loginForm">
<!-- userName is required and is alpha-numeric case insensitive -->
<field property="userName" depends="required,mask">
<!-- message resource key to display if validation fails -->
<msg name="mask" key="login.userName.maskmsg"/>
<arg0 key="login.userName.displayname"/>
<var>
<var-name>mask</var-name>
<var-value>^[a-zA-Z0-9]*$</var-value>
</var>
</field>
...
</form>
...
</formset>
</form-validation>
The Struts JSP tag library defines the "errors" tag that conditionally displays a set of accumulated error messages as shown in the following example:
JavaServer Faces Technology is a set of Java APIs (JSR 127) to represent UI components, manage their state, handle events, validate input, and support internationalization.
The JavaServer Faces API defines the "output_errors" UIOutput Renderer, which displays error messages for an entire page or error messages associated with a specified client identifier.
Example to validate the userName field of a loginForm using JavaServer Faces:
While data validations may be provided as a user convenience on the client-tier, data validation must be performed on the server-tier using Servlets. Client-side validations are inherently insecure because they can be easily bypassed, e.g. by disabling Javascript.
A good design usually requires the web application framework to provide server-side utility routines to validate the following:
[1] Required field
[2] Field data type (all HTTP request parameters are Strings by default)
[3] Field length
[4] Field range
[5] Field options
[6] Field pattern
[7] Cookie values
[8] HTTP Response
A good practice is to implement the above routine as static methods in a "Validator" utility class. The following sections describe an example validator class.
[1] Required field
Always check that the field is not null and its length is greater than zero, excluding leading and trailing white spaces.
Example of how to validate required fields:
// Java example to validate required fields
public Class Validator {
...
public static boolean validateRequired(String value) {
boolean isFieldValid = false;
if (value != null && value.trim().length() > 0) {
isFieldValid = true;
}
return isFieldValid;
}
...
}
...
String fieldValue = request.getParameter("fieldName");
if (Validator.validateRequired(fieldValue)) {
// fieldValue is valid, continue processing request
...
}
[2] Field data type
In web applications, input parameters are poorly typed. For example, all HTTP request parameters or cookie values are of type String. The developer is responsible for verifying the input is of the correct data type. Use the Java primitive wrapper classes to check if the field value can be safely converted to the desired primitive data type.
Example of how to validate a numeric field (type int):
// Java example to validate that a field is an int number
public Class Validator {
...
public static boolean validateInt(String value) {
boolean isFieldValid = false;
try {
Integer.parseInt(value);
isFieldValid = true;
} catch (Exception e) {
isFieldValid = false;
}
return isFieldValid;
}
...
}
...
// check if the HTTP request parameter is of type int
String fieldValue = request.getParameter("fieldName");
if (Validator.validateInt(fieldValue)) {
// fieldValue is valid, continue processing request
...
}
A good practice is to convert all HTTP request parameters to their respective data types. For example, store the "integerValue" of a request parameter in a request attribute and use it as shown in the following example:
// Example to convert the HTTP request parameter to a primitive wrapper data type
// and store this value in a request attribute for further processing
String fieldValue = request.getParameter("fieldName");
if (Validator.validateInt(fieldValue)) {
// convert fieldValue to an Integer
Integer integerValue = Integer.getInteger(fieldValue);
// store integerValue in a request attribute
request.setAttribute("fieldName", integerValue);
}
...
// Use the request attribute for further processing
Integer integerValue = (Integer)request.getAttribute("fieldName");
...
The primary Java data types that the application should handle:
- Byte
- Short
- Integer
- Long
- Float
- Double
- Date
[3] Field length
Always ensure that the input parameter (whether HTTP request parameter or cookie value) is bounded by a minimum length and/or a maximum length.
Example to validate that the length of the userName field is between 8 and 20 characters:
// Example to validate the field length
public Class Validator {
...
public static boolean validateLength(String value, int minLength, int maxLength) {
String validatedValue = value;
if (!validateRequired(value)) {
validatedValue = "";
}
return (validatedValue.length() >= minLength &&
validatedValue.length() <= maxLength);
}
...
}
...
String userName = request.getParameter("userName");
if (Validator.validateRequired(userName)) {
if (Validator.validateLength(userName, 8, 20)) {
// userName is valid, continue further processing
...
}
}
[4] Field range
Always ensure that the input parameter is within a range as defined by the functional requirements.
Example to validate that the input numberOfChoices is between 10 and 20:
// Example to validate the field range
public Class Validator {
...
public static boolean validateRange(int value, int min, int max) {
return (value >= min && value <= max);
}
...
}
...
String fieldValue = request.getParameter("numberOfChoices");
if (Validator.validateRequired(fieldValue)) {
if (Validator.validateInt(fieldValue)) {
int numberOfChoices = Integer.parseInt(fieldValue);
if (Validator.validateRange(numberOfChoices, 10, 20)) {
// numberOfChoices is valid, continue processing request
...
}
}
}
[5] Field options
Often, the web application presents the user with a set of options to choose from, e.g. using the SELECT HTML tag, but fails to perform server-side validation to ensure that the selected value is one of the allowed options. Remember that a malicious user can easily modify any option value. Always validate the selected user value against the allowed options as defined by the functional requirements.
Example to validate the user selection against a list of allowed options:
// Example to validate user selection against a list of options
public Class Validator {
...
public static boolean validateOption(Object[] options, Object value) {
boolean isValidValue = false;
try {
List list = Arrays.asList(options);
if (list != null) {
isValidValue = list.contains(value);
}
} catch (Exception e) {
}
return isValidValue;
}
...
}
...
// Allowed options
String[] options = {"option1", "option2", "option3");
// Verify that the user selection is one of the allowed options
String userSelection = request.getParameter("userSelection");
if (Validator.validateOption(options, userSelection)) {
// valid user selection, continue processing request
...
}
[6] Field pattern
Always check that the user input matches a pattern as defined by the functionality requirements. For example, if the userName field should only allow alpha-numeric characters, case insensitive, then use the following regular expression:
^[a-zA-Z0-9]*$
Java 1.3 or earlier versions do not include any regular expression packages. Apache Regular Expression Package (see Resources below) is recommended for use with Java 1.3 to resolve this lack of support.
Example to perform regular expression validation:
// Example to validate that a given value matches a specified pattern
// using the Apache regular expression package
import org.apache.regexp.RE;
import org.apache.regexp.RESyntaxException;
public Class Validator {
...
public static boolean matchPattern(String value, String expression) {
boolean match = false;
if (validateRequired(expression)) {
RE r = new RE(expression);
match = r.match(value);
}
return match;
}
...
}
...
// Verify that the userName request parameter is alpha-numeric
String userName = request.getParameter("userName");
if (Validator.matchPattern(userName, "^[a-zA-Z0-9]*$")) {
// userName is valid, continue processing request
...
}
Java 1.4 introduced a new regular expression package (java.util.regex). Here is a modified version of Validator.matchPattern using the new Java 1.4 regular expression package:
// Example to validate that a given value matches a specified pattern
// using the Java 1.4 regular expression package
import java.util.regex.Pattern;
import java.util.regexe.Matcher;
public Class Validator {
...
public static boolean matchPattern(String value, String expression) {
boolean match = false;
if (validateRequired(expression)) {
match = Pattern.matches(expression, value);
}
return match;
}
...
}
[7] Cookie value
Use the javax.servlet.http.Cookie object to validate the cookie value. The same validation rules (described above) apply to cookie values depending on the application requirements, e.g. validate a required value, validate length, etc.
Example to validate a required cookie value:
// Example to validate a required cookie value
// First retrieve all available cookies submitted in the HTTP request
Cookie[] cookies = request.getCookies();
if (cookies != null) {
// find the "user" cookie
for (int i=0; i<cookies.length; ++i) {
if (cookies[i].getName().equals("user")) {
// validate the cookie value
if (Validator.validateRequired(cookies[i].getValue()) {
// valid cookie value, continue processing request
...
}
}
}
}
[8] HTTP Response
[8-1] Filter user input
To guard the application against cross-site scripting, sanitize HTML by converting sensitive characters to their corresponding character entities. These are the HTML sensitive characters:
< > " ' % ; ) ( & +
Example to filter a specified string by converting sensitive characters to their corresponding character entities:
// Example to filter sensitive data to prevent cross-site scripting
public Class Validator {
...
public static String filter(String value) {
if (value == null) {
return null;
}
StringBuffer result = new StringBuffer(value.length());
for (int i=0; i<value.length(); ++i) {
switch (value.charAt(i)) {
case '<':
result.append("<");
break;
case '>':
result.append(">");
break;
case '"':
result.append(""");
break;
case '\'':
result.append("'");
break;
case '%':
result.append("%");
break;
case ';':
result.append(";");
break;
case '(':
result.append("(");
break;
case ')':
result.append(")");
break;
case '&':
result.append("&");
break;
case '+':
result.append("+");
break;
default:
result.append(value.charAt(i));
break;
}
return result;
}
...
}
...
// Filter the HTTP response using Validator.filter
PrintWriter out = response.getWriter();
// set output response
out.write(Validator.filter(response));
out.close();
The Java Servlet API 2.3 introduced Filters, which supports the interception and transformation of HTTP requests or responses.
Example of using a Servlet Filter to sanitize the response using Validator.filter:
// Example to filter all sensitive characters in the HTTP response using a Java Filter.
// This example is for illustration purposes since it will filter all content in the response, including HTML tags!
public class SensitiveCharsFilter implements Filter {
...
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
PrintWriter out = response.getWriter();
ResponseWrapper wrapper = new ResponseWrapper((HttpServletResponse)response);
chain.doFilter(request, wrapper);
CharArrayWriter caw = new CharArrayWriter();
caw.write(Validator.filter(wrapper.toString()));
response.setContentType("text/html");
response.setContentLength(caw.toString().length());
out.write(caw.toString());
out.close();
}
...
public class CharResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter output;
public String toString() {
return output.toString();
}
public CharResponseWrapper(HttpServletResponse response){
super(response);
output = new CharArrayWriter();
}
public PrintWriter getWriter(){
return new PrintWriter(output);
}
}
}
}
[8-2] Secure the cookie
When storing sensitive data in a cookie, make sure to set the secure flag of the cookie in the HTTP response, using Cookie.setSecure(boolean flag) to instruct the browser to send the cookie using a secure protocol, such as HTTPS or SSL.
Example to secure the "user" cookie:
// Example to secure a cookie, i.e. instruct the browser to
// send the cookie using a secure protocol
Cookie cookie = new Cookie("user", "sensitive");
cookie.setSecure(true);
response.addCookie(cookie);
RECOMMENDED JAVA TOOLS
The two main Java frameworks for server-side validation are:
[1] Jakarta Commons Validator (integrated with Struts 1.1)
The Jakarta Commons Validator is a powerful framework that implements all the above data validation requirements. These rules are configured in an XML file that defines input validation rules for form fields. Struts supports output filtering of dangerous characters in the [8] HTTP Response by default on all data written using the Struts 'bean:write' tag. This filtering may be disabled by setting the 'filter=false' flag.
Struts defines the following basic input validators, but custom validators may also be defined:
required: succeeds if the field contains any characters other than white space.
mask: succeeds if the value matches the regular expression given by the mask attribute.
range: succeeds if the value is within the values given by the min and max attributes ((value >= min) & (value <= max)).
maxLength: succeeds if the field is length is less than or equal to the max attribute.
minLength: succeeds if the field is length is greater than or equal to the min attribute.
byte, short, integer, long, float, double: succeeds if the value can be converted to the corresponding primitive.
date: succeeds if the value represents a valid date. A date pattern may be provided.
creditCard: succeeds if the value could be a valid credit card number.
e-mail: succeeds if the value could be a valid e-mail address.
Example to validate the userName field of a loginForm using Struts Validator:
<form-validation>
<global>
...
<validator name="required"
classname="org.apache.struts.validator.FieldChecks"
method="validateRequired"
msg="errors.required">
</validator>
<validator name="mask"
classname="org.apache.struts.validator.FieldChecks"
method="validateMask"
msg="errors.invalid">
</validator>
...
</global>
<formset>
<form name="loginForm">
<!-- userName is required and is alpha-numeric case insensitive -->
<field property="userName" depends="required,mask">
<!-- message resource key to display if validation fails -->
<msg name="mask" key="login.userName.maskmsg"/>
<arg0 key="login.userName.displayname"/>
<var>
<var-name>mask</var-name>
<var-value>^[a-zA-Z0-9]*$</var-value>
</var>
</field>
...
</form>
...
</formset>
</form-validation>
[2] JavaServer Faces Technology
JavaServer Faces Technology is a set of Java APIs (JSR 127) to represent UI components, manage their state, handle events and input validation.
The JavaServer Faces API implements the following basic validators, but custom validators may be defined:
validate_doublerange: registers a DoubleRangeValidator on a component
validate_length: registers a LengthValidator on a component
validate_longrange: registers a LongRangeValidator on a component
validate_required: registers a RequiredValidator on a component
validate_stringrange: registers a StringRangeValidator on a component
validator: registers a custom Validator on a component
The JavaServer Faces API defines the following UIInput and UIOutput Renderers (Tags):
input_date: accepts a java.util.Date formatted with a java.text.Date instance
output_date: displays a java.util.Date formatted with a java.text.Date instance
input_datetime: accepts a java.util.Date formatted with a java.text.DateTime instance
output_datetime: displays a java.util.Date formatted with a java.text.DateTime instance
input_number: displays a numeric data type (java.lang.Number or primitive), formatted with a java.text.NumberFormat
output_number: displays a numeric data type (java.lang.Number or primitive), formatted with a java.text.NumberFormat
input_text: accepts a text string of one line.
output_text: displays a text string of one line.
input_time: accepts a java.util.Date, formatted with a java.text.DateFormat time instance
output_time: displays a java.util.Date, formatted with a java.text.DateFormat time instance
input_hidden: allows a page author to include a hidden variable in a page
input_secret: accepts one line of text with no spaces and displays it as a set of asterisks as it is typed
input_textarea: accepts multiple lines of text
output_errors: displays error messages for an entire page or error messages associated with a specified client identifier
output_label: displays a nested component as a label for a specified input field
output_message: displays a localized message
Example to validate the userName field of a loginForm using JavaServer Faces:
Many J2EE web application architectures follow the Model View Controller (MVC) pattern. In this pattern a Servlet acts as a Controller. A Servlet delegates the application processing to a JavaBean such as an EJB Session Bean (the Model). The Servlet then forwards the request to a JSP (View) to render the processing results. Servlets should check all input, output, return codes, error codes and known exceptions to ensure that the expected processing actually occurred.
While data validation protects applications against malicious data tampering, a sound error handling strategy is necessary to prevent the application from inadvertently disclosing internal error messages such as exception stack traces. A good error handling strategy addresses the following items:
[1] Defining Errors
[2] Reporting Errors
[3] Rendering Errors
[4] Error Mapping
[1] Defining Errors
Hard-coded error messages in the application layer (e.g. Servlets) should be avoided. Instead, the application should use error keys that map to known application failures. A good practice is to define error keys that map to validation rules for HTML form fields or other bean properties. For example, if the "user_name" field is required, is alphanumeric, and must be unique in the database, then the following error keys should be defined:
(a) ERROR_USERNAME_REQUIRED: this error key is used to display a message notifying the user that the "user_name" field is required;
(b) ERROR_USERNAME_ALPHANUMERIC: this error key is used to display a message notifying the user that the "user_name" field should be alphanumeric;
(c) ERROR_USERNAME_DUPLICATE: this error key is used to display a message notifying the user that the "user_name" value is a duplicate in the database;
(d) ERROR_USERNAME_INVALID: this error key is used to display a generic message notifying the user that the "user_name" value is invalid;
A good practice is to define the following framework Java classes which are used to store and report application errors:
- ErrorKeys: defines all error keys
// Example: ErrorKeys defining the following error keys:
// - ERROR_USERNAME_REQUIRED
// - ERROR_USERNAME_ALPHANUMERIC
// - ERROR_USERNAME_DUPLICATE
// - ERROR_USERNAME_INVALID
// ...
public Class ErrorKeys {
public static final String ERROR_USERNAME_REQUIRED = "error.username.required";
public static final String ERROR_USERNAME_ALPHANUMERIC = "error.username.alphanumeric";
public static final String ERROR_USERNAME_DUPLICATE = "error.username.duplicate";
public static final String ERROR_USERNAME_INVALID = "error.username.invalid";
...
}
- Error: encapsulates an individual error
// Example: Error encapsulates an error key.
// Error is serializable to support code executing in multiple JVMs.
public Class Error implements Serializable {
// Constructor given a specified error key
public Error(String key) {
this(key, null);
}
// Constructor given a specified error key and array of placeholder objects
public Error(String key, Object[] values) {
this.key = key;
this.values = values;
}
// Returns the error key
public String getKey() {
return this.key;
}
// Returns the placeholder values
public Object[] getValues() {
return this.values;
}
private String key = null;
private Object[] values = null;
}
- Errors: encapsulates a Collection of errors
// Example: Errors encapsulates the Error objects being reported to the presentation layer.
// Errors are stored in a HashMap where the key is the bean property name and value is an
// ArrayList of Error objects.
public Class Errors implements Serializable {
// Adds an Error object to the Collection of errors for the specified bean property.
public void addError(String property, Error error) {
ArrayList propertyErrors = (ArrayList)errors.get(property);
if (propertyErrors == null) {
propertyErrors = new ArrayList();
errors.put(property, propertyErrors);
}
propertyErrors.put(error);
}
// Returns true if there are any errors
public boolean hasErrors() {
return (errors.size > 0);
}
// Returns the Errors for the specified property
public ArrayList getErrors(String property) {
return (ArrayList)errors.get(property);
}
private HashMap errors = new HashMap();
}
Using the above framework classes, here is an example to process validation errors of the "user_name" field:
// Example to process validation errors of the "user_name" field.
Errors errors = new Errors();
String userName = request.getParameter("user_name");
// (a) Required validation rule
if (!Validator.validateRequired(userName)) {
errors.addError("user_name", new Error(ErrorKeys.ERROR_USERNAME_REQUIRED));
} // (b) Alpha-numeric validation rule
else if (!Validator.matchPattern(userName, "^[a-zA-Z0-9]*$")) {
errors.addError("user_name", new Error(ErrorKeys.ERROR_USERNAME_ALPHANUMERIC));
}
else
{
// (c) Duplicate check validation rule
// We assume that there is an existing UserValidationEJB session bean that implements
// a checkIfDuplicate() method to verify if the user already exists in the database.
try {
...
if (UserValidationEJB.checkIfDuplicate(userName)) {
errors.addError("user_name", new Error(ErrorKeys.ERROR_USERNAME_DUPLICATE));
}
} catch (RemoteException e) {
// log the error
logger.error("Could not validate user for specified userName: " + userName);
errors.addError("user_name", new Error(ErrorKeys.ERROR_USERNAME_DUPLICATE);
}
}
// set the errors object in a request attribute called "errors"
request.setAttribute("errors", errors);
...
[2] Reporting Errors
There are two ways to report web-tier application errors:
(a) Servlet Error Mechanism
(b) JSP Error Mechanism
[2-a] Servlet Error Mechanism
A Servlet may report errors by:
- forwarding to the input JSP (having already stored the errors in a request attribute), OR
- calling response.sendError with an HTTP error code argument, OR
- throwing an exception
It is good practice to process all known application errors (as described in section [1]), store them in a request attribute, and forward to the input JSP. The input JSP should display the error messages and prompt the user to re-enter the data. The following example illustrates how to forward to an input JSP (userInput.jsp):
// Example to forward to the userInput.jsp following user validation errors
RequestDispatcher rd = getServletContext().getRequestDispatcher("/user/userInput.jsp");
if (rd != null) {
rd.forward(request, response);
}
If the Servlet cannot forward to a known JSP page, the second option is to report an error using the response.sendError method with HttpServletResponse.SC_INTERNAL_SERVER_ERROR (status code 500) as argument. Refer to the javadoc of javax.servlet.http.HttpServletResponse for more details on the various HTTP status codes.
Example to return a HTTP error:
// Example to return a HTTP error code
RequestDispatcher rd = getServletContext().getRequestDispatcher("/user/userInput.jsp");
if (rd == null) {
// messages is a resource bundle with all message keys and values
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
messages.getMessage(ErrorKeys.ERROR_USERNAME_INVALID));
}
As a last resort, Servlets can throw an exception, which must be a subclass of one of the following classes:
- RuntimeException
- ServletException
- IOException
[2-b] JSP Error Mechanism
JSP pages provide a mechanism to handle runtime exceptions by defining an errorPage directive as shown in the following example:
Uncaught JSP exceptions are forwarded to the specified errorPage, and the original exception is set in a request parameter called javax.servlet.jsp.jspException. The error page must include a isErrorPage directive as shown below:
<%@ page isErrorPage="true" %>
The isErrorPage directive causes the "exception" variable to be initialized to the exception object being thrown.
[3] Rendering Errors
The J2SE Internationalization APIs provide utility classes for externalizing application resources and formatting messages including:
(a) Resource Bundles
(b) Message Formatting
[3-a] Resource Bundles
Resource bundles support internationalization by separating localized data from the source code that uses it. Each resource bundle stores a map of key/value pairs for a specific locale.
It is common to use or extend java.util.PropertyResourceBundle, which stores the content in an external properties file as shown in the following example:
################################################
# ErrorMessages.properties
################################################
# required user name error message
error.username.required=User name field is required
# invalid user name format
error.username.alphanumeric=User name must be alphanumeric
# duplicate user name error message
error.username.duplicate=User name {0} already exists, please choose another one
...
Multiple resources can be defined to support different locales (hence the name resource bundle). For example, ErrorMessages_fr.properties can be defined to support the French member of the bundle family. If the resource member of the requested locale does not exist, the default member is used. In the above example, the default resource is ErrorMessages.properties. Depending on the user's locale, the application (JSP or Servlet) retrieves content from the appropriate resource.
[3-b] Message Formatting
The J2SE standard class java.util.MessageFormat provides a generic way to create messages with replacement placeholders. A MessageFormat object contains a pattern string with embedded format specifiers as shown below:
// Example to show how to format a message using placeholder parameters
String pattern = "User name {0} already exists, please choose another one";
String userName = request.getParameter("user_name");
Object[] args = new Object[1];
args[0] = userName;
String message = MessageFormat.format(pattern, args);
Here is a more comprehensive example to render error messages using ResourceBundle and MessageFormat:
// Example to render an error message from a localized ErrorMessages resource (properties file)
// Utility class to retrieve locale-specific error messages
public Class ErrorMessageResource {
// Returns the error message for the specified error key in the environment locale
public String getErrorMessage(String errorKey) {
return getErrorMessage(errorKey, defaultLocale);
}
// Returns the error message for the specified error key in the specified locale
public String getErrorMessage(String errorKey, Locale locale) {
return getErrorMessage(errorKey, null, locale);
}
// Returns a formatted error message for the specified error key in the specified locale
public String getErrorMessage(String errorKey, Object[] args, Locale locale) {
// Get localized ErrorMessageResource
ResourceBundle errorMessageResource = ResourceBundle.getBundle("ErrorMessages", locale);
// Get localized error message
String errorMessage = errorMessageResource.getString(errorKey);
if (args != null) {
// Format the message using the specified placeholders args
return MessageFormat.format(errorMessage, args);
} else {
return errorMessage;
}
}
// default environment locale
private Locale defaultLocale = Locale.getDefaultLocale();
}
...
// Get the user's locale
Locale userLocale = request.getLocale();
// Check if there were any validation errors
Errors errors = (Errors)request.getAttribute("errors");
if (errors != null && errors.hasErrors()) {
// iterate through errors and output error messages corresponding to the "user_name" property
ArrayList userNameErrors = errors.getErrors("user_name");
ListIterator iterator = userNameErrors.iterator();
while (iterator.hasNext()) {
// Get the next error object
Error error = (Error)iterator.next();
String errorMessage = ErrorMessageResource.getErrorMessage(error.getKey(), userLocale);
output.write(errorMessage + "\r\n");
}
}
It is recommended to define a custom JSP tag, e.g. displayErrors, to iterate through and render error messages as shown in the above example.
[4] Error Mapping
Normally, the Servlet Container will return a default error page corresponding to either the response status code or the exception. A mapping between the status code or the exception and a web resource may be specified using custom error pages. It is a good practice to develop static error pages that do not disclose internal error states (by default, most Servlet containers will report internal error messages). This mapping is configured in the Web Deployment Descriptor (web.xml) as specified in the following example:
<!-- Mapping of HTTP error codes and application exceptions to error pages -->
<error-page>
<exception-type>UserValidationException</exception-type>
<location>/errors/validationError.html</error-page>
</error-page>
<error-page>
<error-code>500</exception-type>
<location>/errors/internalError.html</error-page>
</error-page>
<error-page>
...
</error-page>
...
RECOMMENDED JAVA TOOLS
The two main Java frameworks for server-side validation are:
[1] Jakarta Commons Validator (integrated with Struts 1.1)
The Jakarta Commons Validator is a Java framework that defines the error handling mechanism as described above. Validation rules are configured in an XML file that defines input validation rules for form fields and the corresponding validation error keys. Struts provides internationalization support to build localized applications using resource bundles and message formatting.
Example to validate the userName field of a loginForm using Struts Validator:
<form-validation>
<global>
...
<validator name="required"
classname="org.apache.struts.validator.FieldChecks"
method="validateRequired"
msg="errors.required">
</validator>
<validator name="mask"
classname="org.apache.struts.validator.FieldChecks"
method="validateMask"
msg="errors.invalid">
</validator>
...
</global>
<formset>
<form name="loginForm">
<!-- userName is required and is alpha-numeric case insensitive -->
<field property="userName" depends="required,mask">
<!-- message resource key to display if validation fails -->
<msg name="mask" key="login.userName.maskmsg"/>
<arg0 key="login.userName.displayname"/>
<var>
<var-name>mask</var-name>
<var-value>^[a-zA-Z0-9]*$</var-value>
</var>
</field>
...
</form>
...
</formset>
</form-validation>
The Struts JSP tag library defines the "errors" tag that conditionally displays a set of accumulated error messages as shown in the following example:
JavaServer Faces Technology is a set of Java APIs (JSR 127) to represent UI components, manage their state, handle events, validate input, and support internationalization.
The JavaServer Faces API defines the "output_errors" UIOutput Renderer, which displays error messages for an entire page or error messages associated with a specified client identifier.
Example to validate the userName field of a loginForm using JavaServer Faces:
While data validations may be provided as a user convenience on the client-tier, data validation must always be performed on the server-tier. Client-side validations are inherently insecure because they can be easily bypassed, e.g. by disabling Javascript.
A good design usually requires the web application framework to provide server-side utility routines to validate the following:
[1] Required field
[2] Field data type (all HTTP request parameters are Strings by default)
[3] Field length
[4] Field range
[5] Field options
[6] Field pattern
[7] Cookie values
[8] HTTP Response
A good practice is to implement a function or functions that validates each application parameter. The following sections describe some example checking.
[1] Required field
Always check that the field is not null and its length is greater than zero, excluding leading and trailing white spaces.
Example of how to validate required fields:
// PHP example to validate required fields
function validateRequired($input) {
...
$pass = false;
if (strlen(trim($input))>0){
$pass = true;
}
return $pass;
...
}
...
if (validateRequired($fieldName)) {
// fieldName is valid, continue processing request
...
}
[2] Field data type
In web applications, input parameters are poorly typed. For example, all HTTP request parameters or cookie values are of type String. The developer is responsible for verifying the input is of the correct data type.
[3] Field length
Always ensure that the input parameter (whether HTTP request parameter or cookie value) is bounded by a minimum length and/or a maximum length.
[4] Field range
Always ensure that the input parameter is within a range as defined by the functional requirements.
[5] Field options
Often, the web application presents the user with a set of options to choose from, e.g. using the SELECT HTML tag, but fails to perform server-side validation to ensure that the selected value is one of the allowed options. Remember that a malicious user can easily modify any option value. Always validate the selected user value against the allowed options as defined by the functional requirements.
[6] Field pattern
Always check that user input matches a pattern as defined by the functionality requirements. For example, if the userName field should only allow alpha-numeric characters, case insensitive, then use the following regular expression:
^[a-zA-Z0-9]+$
[7] Cookie value
The same validation rules (described above) apply to cookie values depending on the application requirements, e.g. validate a required value, validate length, etc.
[8] HTTP Response
[8-1] Filter user input
To guard the application against cross-site scripting, the developer should sanitize HTML by converting sensitive characters to their corresponding character entities. These are the HTML sensitive characters:
< > " ' % ; ) ( & +
PHP includes some automatic sanitization utility functions, such as htmlentities():
In addition, in order to avoid UTF-7 variants of Cross-site Scripting, you should explicitly define the Content-Type header of the response, for example:
When storing sensitive data in a cookie and transporting it over SSL, make sure that you first set the secure flag of the cookie in the HTTP response. This will instruct the browser to only use that cookie over SSL connections.
You can use the following code example, for securing the cookie:
In addition, we recommend that you use the HttpOnly flag. When the HttpOnly flag is set to TRUE the cookie will be made accessible only through the HTTP protocol. This means that the cookie won't be accessible by scripting languages, such as JavaScript. This setting can effectively help to reduce identity theft through XSS attacks (although it is not supported by all browsers).
The HttpOnly flag was Added in PHP 5.2.0.
REFERENCES
[1] Mitigating Cross-site Scripting With HTTP-only Cookies:
While data validations may be provided as a user convenience on the client-tier, data validation must always be performed on the server-tier. Client-side validations are inherently insecure because they can be easily bypassed, e.g. by disabling Javascript.
A good design usually requires the web application framework to provide server-side utility routines to validate the following:
[1] Required field
[2] Field data type (all HTTP request parameters are Strings by default)
[3] Field length
[4] Field range
[5] Field options
[6] Field pattern
[7] Cookie values
[8] HTTP Response
A good practice is to implement a function or functions that validates each application parameter. The following sections describe some example checking.
[1] Required field
Always check that the field is not null and its length is greater than zero, excluding leading and trailing white spaces.
Example of how to validate required fields:
// PHP example to validate required fields
function validateRequired($input) {
...
$pass = false;
if (strlen(trim($input))>0){
$pass = true;
}
return $pass;
...
}
...
if (validateRequired($fieldName)) {
// fieldName is valid, continue processing request
...
}
[2] Field data type
In web applications, input parameters are poorly typed. For example, all HTTP request parameters or cookie values are of type String. The developer is responsible for verifying the input is of the correct data type.
[3] Field length
Always ensure that the input parameter (whether HTTP request parameter or cookie value) is bounded by a minimum length and/or a maximum length.
[4] Field range
Always ensure that the input parameter is within a range as defined by the functional requirements.
[5] Field options
Often, the web application presents the user with a set of options to choose from, e.g. using the SELECT HTML tag, but fails to perform server-side validation to ensure that the selected value is one of the allowed options. Remember that a malicious user can easily modify any option value. Always validate the selected user value against the allowed options as defined by the functional requirements.
[6] Field pattern
Always check that user input matches a pattern as defined by the functionality requirements. For example, if the userName field should only allow alpha-numeric characters, case insensitive, then use the following regular expression:
^[a-zA-Z0-9]+$
[7] Cookie value
The same validation rules (described above) apply to cookie values depending on the application requirements, e.g. validate a required value, validate length, etc.
[8] HTTP Response
[8-1] Filter user input
To guard the application against cross-site scripting, the developer should sanitize HTML by converting sensitive characters to their corresponding character entities. These are the HTML sensitive characters:
< > " ' % ; ) ( & +
PHP includes some automatic sanitization utility functions, such as htmlentities():
In addition, in order to avoid UTF-7 variants of Cross-site Scripting, you should explicitly define the Content-Type header of the response, for example:
When storing sensitive data in a cookie and transporting it over SSL, make sure that you first set the secure flag of the cookie in the HTTP response. This will instruct the browser to only use that cookie over SSL connections.
You can use the following code example, for securing the cookie:
In addition, we recommend that you use the HttpOnly flag. When the HttpOnly flag is set to TRUE the cookie will be made accessible only through the HTTP protocol. This means that the cookie won't be accessible by scripting languages, such as JavaScript. This setting can effectively help to reduce identity theft through XSS attacks (although it is not supported by all browsers).
The HttpOnly flag was Added in PHP 5.2.0.
REFERENCES
[1] Mitigating Cross-site Scripting With HTTP-only Cookies:
The "Content-Security-Policy" header is designed to modify the way browsers render pages, and thus to protect from various cross-site injections, including Cross-Site Scripting. It is important to set the header value correctly, in a way that will not prevent proper operation of the web site. For example, if the header is set to prevent execution of inline JavaScript, the web site must not use inline JavaScript in it's pages.
To protect against Cross-Site Scripting, Cross-Frame Scripting and clickjacking, it is important to set the following policies with proper values:
Both of 'default-src' and 'frame-ancestors' policies, *OR* all of 'script-src', 'object-src' and 'frame-ancestors’ policies.
For 'default-src', 'script-src' and 'object-src', insecure values such as '*', 'data:', 'unsafe-inline' or 'unsafe-eval' should be avoided.
For 'frame-ancestors', insecure values such as '*' or 'data:' should be avoided.
Please refer the following links for more information.
Web Application Source Code Disclosure Pattern Found
Latest patches or hotfixes for 3rd. party products were not installed
Temporary files were left in production environment
Debugging information was left by the programmer in web pages
Security Risks:
It is possible to retrieve the source code of server-side scripts, which may expose the application logic and other sensitive information such as usernames and passwords
AppScan detected a response containing fragments of application source code.
Application source code should not be accessible to web users, as it may contain sensitive application information and back-end logic.
While such leakage does not necessarily represent a breach in security, it can give an attacker useful guidance for future exploitation. Leakage of sensitive information may carry various levels of risk and should be limited whenever possible.
If an attacker probes the application by forging a request that contains parameters or parameter values other than the ones expected by the application (examples are listed below), the application may enter an undefined state that makes it vulnerable to attack. The attacker can gain useful information from the application's response to this request, which information may be exploited to locate application weaknesses.
For example, if the parameter field should be an apostrophe-quoted string (e.g. in an ASP script or SQL query), the injected apostrophe symbol will prematurely terminate the string stream, thus changing the normal flow/syntax of the script.
Another cause of vital information being revealed in error messages, is when the scripting engine, web server, or database are misconfigured.
Here are some different variants:
[1] Remove parameter
[2] Remove parameter value
[3] Set parameter value to null
[4] Set parameter value to a numeric overflow (+/- 99999999)
[5] Set parameter value to hazardous characters, such as ' " \' \" ) ;
[6] Append some string to a numeric parameter value
[7] Append "." (dot) or "[]" (angle brackets) to the parameter name
A cookie is a piece of information usually created by the Web server and stored in the Web browser.
The cookie contains information used by web applications mainly (but not only) to identify users and maintain their state.
AppScan detected that the JavaScript code at the client side is used to manipulate (either create or modify) the site's cookies.
It is possible for an attacker to view this code, understand its logic, and use it to compose his own cookies, or modify existing ones, based on this knowledge.
The damage an attacker may cause depends on how the application uses its cookies, or what information it stores in them.
Among other things, cookie manipulation may lead to session hijacking or privilege escalation.
Other vulnerabilities caused by cookie poisoning contain SQL injection and Cross-Site scripting.
If an attacker probes the application by forging a request that contains parameters or parameter values other than the ones expected by the application (examples are listed below), the application may enter an undefined state that makes it vulnerable to attack. The attacker can gain useful information from the application's response to this request, which information may be exploited to locate application weaknesses.
For example, if the parameter field should be an apostrophe-quoted string (e.g. in an ASP script or SQL query), the injected apostrophe symbol will prematurely terminate the string stream, thus changing the normal flow/syntax of the script.
Another cause of vital information being revealed in error messages, is when the scripting engine, web server, or database are misconfigured.
Here are some different variants:
[1] Remove parameter
[2] Remove parameter value
[3] Set parameter value to null
[4] Set parameter value to a numeric overflow (+/- 99999999)
[5] Set parameter value to hazardous characters, such as ' " \' \" ) ;
[6] Append some string to a numeric parameter value
[7] Append "." (dot) or "[]" (angle brackets) to the parameter name
AppScan detected a response containing an internal IP address.
Internal IP is defined as an IP in the following IP ranges:
10.0.0.0 - 10.255.255.255
172.16.0.0 - 172.31.255.255
192.168.0.0 - 192.168.255.255
Internal IP disclosure is valuable for an attacker as it reveals the IP addressing scheme of the internal network. Knowing the IP addressing scheme of the internal network may help an attacker to devise further attacks against the internal network.
Latest patches or hotfixes for 3rd. party products were not installed
Security Risks:
It is possible to retrieve the absolute path of the web server installation, which might help an attacker to develop further attacks and to gain information about the file system structure of the web application
AppScan detected a response containing a file's absolute path (e.g. c:\dir\file in Windows, or /dir/file in Unix).
An attacker may be able to exploit this information to access sensitive information on the directory structure of the server machine which could be used for further attacks against the site.