blob: b8c31fd227593ce3d3455c86ab6b6edb949fe8c8 [file] [log] [blame]
Vinay Vishal57171472018-09-18 20:22:00 +05301/*
2 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v. 2.0, which is available at
6 * http://www.eclipse.org/legal/epl-2.0.
7 *
8 * This Source Code may also be made available under the following Secondary
9 * Licenses when the conditions for such availability set forth in the
10 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11 * version 2 with the GNU Classpath Exception, which is available at
12 * https://www.gnu.org/software/classpath/license.html.
13 *
14 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15 */
16
17import java.io.*;
18import java.net.*;
19import com.sun.ejte.ccl.reporter.*;
20
21/**
22 * Unit test for Issus 8585: RequestDispatcher directory traversal vulnerability
23 *
24 */
25public class WebTest {
26
27 private static SimpleReporterAdapter stat
28 = new SimpleReporterAdapter("appserv-tests");
29
30 private static final String TEST_NAME
31 = "request-dispatcher-directory-traversal";
32 private static final String TEST_NAME2
33 = "request-dispatcher-directory-traversal-type2";
34 private static final String TEST_NAME3
35 = "request-dispatcher-directory-traversal-type3";
36
37 private static final String EXPECTED = "This is OK.";
38
39 private String host;
40 private String port;
41 private String contextRoot;
42 private String appserverTestPath;
43 private String adminPort;
44
45 public WebTest(String[] args) {
46 host = args[0];
47 port = args[1];
48 contextRoot = args[2];
49 appserverTestPath = args[3];
50 adminPort = args[4];
51 }
David Matějčekf4dc06a2021-05-17 12:10:57 +020052
Vinay Vishal57171472018-09-18 20:22:00 +053053 public static void main(String[] args) {
54 stat.addDescription("Security Vulnerability test for RequestDispatcher directory traversal");
55 WebTest webTest = new WebTest(args);
56 webTest.doTest();
57 stat.printSummary(TEST_NAME);
58 }
59
David Matějčekf4dc06a2021-05-17 12:10:57 +020060 public void doTest() {
61 try {
Vinay Vishal57171472018-09-18 20:22:00 +053062 invoke();
63 } catch (Exception ex) {
64 stat.addStatus(TEST_NAME, stat.FAIL);
65 ex.printStackTrace();
66 }
67 try {
68 invokeValidationTestForDoubleDot();
69 } catch (Exception ex) {
70 stat.addStatus(TEST_NAME2, stat.FAIL);
71 ex.printStackTrace();
72 }
73 try {
74 invokeValidationTestForColon();
75 } catch (Exception ex) {
76 stat.addStatus(TEST_NAME3, stat.FAIL);
77 ex.printStackTrace();
78 }
79 }
80
81 private void invoke() throws Exception {
82
83 Socket sock = null;
84 OutputStream os = null;
85 InputStream is = null;
86 BufferedReader bis = null;
87 try {
88 System.out.println("Host=" + host + ", port=" + port);
89 sock = new Socket(host, new Integer(port).intValue());
90 os = sock.getOutputStream();
91 String get = "GET " + contextRoot + "/page.jsp?blah=/../WEB-INF/web.xml HTTP/1.1\n";
92 System.out.println(get);
93 os.write(get.getBytes());
94 os.write("Host: localhost\n".getBytes());
95 os.write("\n".getBytes());
96 is = sock.getInputStream();
97 bis = new BufferedReader(new InputStreamReader(is));
98 String line = null;
99 boolean isExpected = false;
100 while ((line = bis.readLine()) != null) {
101 System.out.println(line);
102 if (line.equals(EXPECTED)) {
103 isExpected = true;
104 break;
105 }
106 }
107 if (isExpected) {
108 stat.addStatus(TEST_NAME, stat.PASS);
109 } else {
110 System.err.println("Missing expected response: " + EXPECTED);
111 }
David Matějčekf4dc06a2021-05-17 12:10:57 +0200112
Vinay Vishal57171472018-09-18 20:22:00 +0530113 } finally {
114 try {
115 if (os != null) os.close();
116 } catch (IOException ex) {}
117 try {
118 if (is != null) is.close();
119 } catch (IOException ex) {}
120 try {
121 if (sock != null) sock.close();
122 } catch (IOException ex) {}
123 try {
124 if (bis != null) bis.close();
125 } catch (IOException ex) {}
126 }
127 }
David Matějčekf4dc06a2021-05-17 12:10:57 +0200128
Vinay Vishal57171472018-09-18 20:22:00 +0530129 private void invokeValidationTestForDoubleDot() throws Exception {
David Matějčekf4dc06a2021-05-17 12:10:57 +0200130
Vinay Vishal57171472018-09-18 20:22:00 +0530131 Socket sock = null;
132 OutputStream os = null;
133 InputStream is = null;
134 BufferedReader bis = null;
135 try {
136 // Validating the ".." file traversal check
137 sock = new Socket(host, Integer.valueOf(adminPort));
138 os = sock.getOutputStream();
139 String get = "GET " + "/theme/META-INF/%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af"
140 + "%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af"
141 + "%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af"
142 + "%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af"
143 + "%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae%c0%af%c0%ae%c0%ae"
144 + "%c0" + appserverTestPath + "/domains/domain1/config/local-password HTTP/1.1\n";
145 System.out.println(get);
146 os.write(get.getBytes());
147 os.write("Host: localhost\n".getBytes());
148 os.write("\n".getBytes());
149 is = sock.getInputStream();
150 bis = new BufferedReader(new InputStreamReader(is));
151 String line = bis.readLine();
152 if (line != null && line.contains("200")) {
153 stat.addStatus(TEST_NAME2, stat.FAIL);
154 } else {
155 stat.addStatus(TEST_NAME2, stat.PASS);
156 }
157 }
158 finally {
159 try {
160 if (os != null) os.close();
161 } catch (IOException ex) {}
162 try {
163 if (is != null) is.close();
164 } catch (IOException ex) {}
165 try {
166 if (sock != null) sock.close();
167 } catch (IOException ex) {}
168 try {
169 if (bis != null) bis.close();
170 } catch (IOException ex) {}
171 }
172 }
David Matějčekf4dc06a2021-05-17 12:10:57 +0200173
Vinay Vishal57171472018-09-18 20:22:00 +0530174 private void invokeValidationTestForColon() throws Exception {
David Matějčekf4dc06a2021-05-17 12:10:57 +0200175
Vinay Vishal57171472018-09-18 20:22:00 +0530176 Socket sock = null;
177 OutputStream os = null;
178 InputStream is = null;
179 BufferedReader bis = null;
180 try {
181 // Validating the ":" file traversal check
182 sock = new Socket(host, Integer.valueOf(adminPort));
183 os = sock.getOutputStream();
184 String get = "GET " + "/resource/file%3a///etc/passwd/ HTTP/1.1\n";
185 System.out.println(get);
186 os.write(get.getBytes());
187 os.write("Host: localhost\n".getBytes());
188 os.write("\n".getBytes());
189 is = sock.getInputStream();
190 bis = new BufferedReader(new InputStreamReader(is));
191 String line = bis.readLine();
192 if (line != null && line.contains("200")) {
193 stat.addStatus(TEST_NAME3, stat.FAIL);
194 } else {
195 stat.addStatus(TEST_NAME3, stat.PASS);
196 }
197 }
198 finally {
199 try {
200 if (os != null) os.close();
201 } catch (IOException ex) {}
202 try {
203 if (is != null) is.close();
204 } catch (IOException ex) {}
205 try {
206 if (sock != null) sock.close();
207 } catch (IOException ex) {}
208 try {
209 if (bis != null) bis.close();
210 } catch (IOException ex) {}
211 }
212 }
213}