Skip to content

Commit

Permalink
Merge branch 'feature/add-auth-to-ws-20241111' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
webpwnized committed Nov 19, 2024
2 parents d2207fc + 88c02ae commit a191a7a
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 10 deletions.
6 changes: 5 additions & 1 deletion src/webservices/includes/ws-constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
define('SECURITY_LEVEL_SECURE', 5);

define('CONTENT_TYPE_JSON', 'Content-Type: application/json');
define('CONTENT_TYPE_XML', 'Content-Type: text/xml; charset=UTF-8');
define('DATE_TIME_FORMAT', 'Y-m-d H:i:s');

define('JWT_SECRET_KEY', 'snowman');
Expand All @@ -100,11 +101,14 @@
JWT_BASE_URL . "/webservices/soap/ws-user-account.php"
]);

define('CORS_REQUEST_ORIGIN', isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : JWT_BASE_URL);
define('CORS_REQUEST_ORIGIN', isset($_SERVER['HTTP_ORIGIN']) && !empty($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : JWT_BASE_URL);
define('CORS_ACCESS_CONTROL_MAX_AGE', 'Access-Control-Max-Age: 600');
define('CORS_ACCESS_CONTROL_ALLOW_ORIGIN', 'Access-Control-Allow-Origin: ' . CORS_REQUEST_ORIGIN);
define('CORS_TRUSTED_ORIGINS', [
'http://mutillidae.localhost'
]);

define('ERROR_MESSAGE_METHOD_NOT_ALLOWED', '<?xml version="1.0" encoding="UTF-8"?><error><message>Method Not Allowed. Use POST for this endpoint.</message></error>');
define('ERROR_MESSAGE_UNAUTHORIZED', '<?xml version="1.0" encoding="UTF-8"?><error><message>Unauthorized</message></error>');

?>
64 changes: 55 additions & 9 deletions src/webservices/soap/ws-dns-lookup.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class LookupException extends Exception {}
'',
array(
'host' => array('name' => 'host', 'type' => 'xsd:string'),
'command' => array('name' => 'command', 'type' => 'xsd:string'),
'securityLevel' => array('name' => 'securityLevel', 'type' => 'xsd:string'),
'timestamp' => array('name' => 'timestamp', 'type' => 'xsd:string'),
'output' => array('name' => 'output', 'type' => 'xsd:string')
Expand Down Expand Up @@ -68,23 +69,67 @@ function lookupDNS($pTargetHost) {
$LogHandler = new LogHandler($lSecurityLevel);
$Encoder = new EncodingHandler();

// Determine security level and protection settings
require_once '../includes/ws-constants.php';

// Set CORS headers
header(CORS_ACCESS_CONTROL_ALLOW_ORIGIN);
header('Access-Control-Allow-Methods: POST, OPTIONS'); // Allowed methods
header('Access-Control-Allow-Headers: Content-Type, Authorization'); // Specify allowed headers
header('Access-Control-Expose-Headers: Authorization'); // Expose headers if needed
header(CONTENT_TYPE_XML); // Set content type as XML

// Handle preflight requests (OPTIONS)
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header(CORS_ACCESS_CONTROL_MAX_AGE); // Cache the preflight response for 600 seconds (10 minutes)
http_response_code(RESPONSE_CODE_NO_CONTENT); // No Content
exit();
}

// Allow only POST requests
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(RESPONSE_CODE_METHOD_NOT_ALLOWED);
header(CONTENT_TYPE_XML);
echo ERROR_MESSAGE_METHOD_NOT_ALLOWED;
exit();
}

switch ($lSecurityLevel) {
default: // Insecure
case "0": // Insecure
case "1": // Insecure
default:
case SECURITY_LEVEL_INSECURE:
$lProtectAgainstCommandInjection = false;
$lProtectAgainstXSS = false;
$lRequireAuthentication = false;
break;
case SECURITY_LEVEL_MEDIUM:
$lProtectAgainstCommandInjection = false;
$lProtectAgainstXSS = false;
$lRequireAuthentication = true;
break;
case "2": // Moderate security
case "3": // More secure
case "4": // Secure
case "5": // Fairly secure
case 2:
case 3:
case 4:
case SECURITY_LEVEL_SECURE:
$lProtectAgainstCommandInjection = true;
$lProtectAgainstXSS = true;
$lRequireAuthentication = true;
break;
}

// Shared: Include the shared JWT token authentication function
require_once '../includes/ws-authenticate-jwt-token.php';

// Shared: Authenticate the user if required
if ($lRequireAuthentication) {
try {
$lDecodedToken = authenticateJWTToken(); // Authenticate using the shared function
} catch (InvalidTokenException $e) {
http_response_code(RESPONSE_CODE_UNAUTHORIZED);
header(CONTENT_TYPE_XML);
echo '<?xml version="1.0" encoding="UTF-8"?><error><message>Unauthorized: ' . htmlspecialchars($e->getMessage()) . '</message></error>';
exit();
}
}

// Validate the target host to protect against command injection, if security is enabled
if ($lProtectAgainstCommandInjection) {
$lTargetHostValidated = preg_match(IPV4_REGEX_PATTERN, $pTargetHost) ||
Expand Down Expand Up @@ -117,6 +162,7 @@ function lookupDNS($pTargetHost) {
// Create a structured response as an associative array
$response = array(
'host' => $lTargetHost,
'command' => $lCommand,
'securityLevel' => $lSecurityLevel,
'timestamp' => $lTimestamp,
'output' => $lOutput
Expand All @@ -136,6 +182,6 @@ function lookupDNS($pTargetHost) {
$lSOAPWebService->service(file_get_contents("php://input"));
} catch (Exception $e) {
// Send a fault response back to the client if an error occurs
$lSOAPWebService->fault('Server', "SOAP Service Error: " . $e->getMessage());
$lSOAPWebService->fault('Server', "SOAP Service Error: " . htmlspecialchars($e->getMessage()));
}
?>

0 comments on commit a191a7a

Please sign in to comment.