Skip to content

Web Service Security — Complete Guide to Protecting Services

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Web Service Security. We cover key concepts, practical examples, and best practices to help you master this topic.

Web service security protects SOAP and REST endpoints against unauthorized access, XML/JSON injection, replay attacks, and data exposure through authentication, authorization, encryption, and input validation.

What You'll Learn

  • Authentication methods for SOAP and REST services
  • XML and JSON injection prevention
  • WS-Security for SOAP and token-based auth for REST
  • Encryption and transport security

Why It Matters

Web services expose business logic and data over the network. A single unsecured endpoint can lead to data breaches, unauthorized actions, or denial of service, damaging reputation and incurring regulatory penalties.

Real-World Use

Durga Antivirus Pro secures its SOAP-based threat intelligence service with WS-Security (UsernameToken for authentication, XML Signature for integrity) and its REST endpoints with OAuth 2.0 and JWT tokens.

flowchart LR
    C["Client"] --> T["TLS"]
    T --> A["Authentication"]
    A --> V["Input Validation"]
    V --> AuthZ["Authorization"]
    AuthZ --> L["Audit Log"]
    L --> B["Backend"]
    style A fill:#dbeafe,stroke:#2563eb

Code Examples

# WS-Security UsernameToken for SOAP
from flask import Flask, request, Response
from lxml import etree
import base64

app = Flask(__name__)

@app.route('/soap/threats', methods=['POST'])
def soap_endpoint():
    xml = request.data
    root = etree.fromstring(xml)
    # Extract WS-Security header
    ns = {'wsse': 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'}
    username_token = root.find('.//wsse:UsernameToken', ns)
    if username_token is None:
        return Response('<soap:Fault><faultcode>401</faultcode></soap:Fault>',
                       status=401, mimetype='text/xml')
    username = username_token.find('wsse:Username', ns).text
    password = username_token.find('wsse:Password', ns).text
    if not authenticate(username, password):
        return Response('<soap:Fault><faultcode>401</faultcode></soap:Fault>',
                       status=401, mimetype='text/xml')
    # Process valid request
    return Response('<soap:Envelope>...</soap:Envelope>', mimetype='text/xml')

Expected output: SOAP requests without valid WS-Security credentials receive SOAP Fault with 401.

// JWT authentication for REST web services
const jwt = require('jsonwebtoken');
const express = require('express');
const app = express();

const SECRET = process.env.JWT_SECRET;

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  if (!token) return res.sendStatus(401);

  jwt.verify(token, SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
}

app.get('/api/threats', authenticateToken, (req, res) => {
  res.json({ threats: [], user: req.user.sub });
});

Expected output: Protected endpoint returns 401 without token, 403 with invalid token, 200 with valid token.

# Input validation preventing XML injection
from flask import Flask, request, jsonify
import defusedxml.ElementTree as ET

app = Flask(__name__)

@app.route('/api/search', methods=['POST'])
def search():
    # Use defusedxml to prevent XXE and XML bombs
    try:
        root = ET.fromstring(request.data)
        query = root.findtext('query', '')
        # Limit query length
        if len(query) > 200:
            return jsonify({'error': 'Query too long'}), 422
        # Sanitize query
        import re
        safe_query = re.sub(r'[<>\'"]', '', query)
        results = search_database(safe_query)
        return jsonify({'results': results})
    except ET.ParseError:
        return jsonify({'error': 'Invalid XML'}), 400

Expected output: XML injection attempts are blocked; safe queries proceed with sanitized input.

Common Mistakes

1. No Transport Layer Encryption

Without TLS, all data (including credentials) is sent in plaintext, visible to anyone on the network.

2. Weak Authentication for SOAP

Using plaintext passwords in SOAP headers without WS-Security or TLS exposes credentials.

3. No Input Validation

XML/JSON injection can execute arbitrary code or access unauthorized data. Always validate and sanitize input.

4. Ignoring XXE Attacks

XML External Entity (XXE) attacks can read server files or perform SSRF. Use defusedxml libraries.

5. No Audit Logging

Without audit logs, security incidents cannot be investigated. Log all authentication attempts and data access.

Practice Questions

  1. What are three layers of web service security?
  2. How does WS-Security protect SOAP messages?
  3. What is the difference between authentication and authorization?
  4. What is an XXE attack and how is it prevented?
  5. Why is transport layer encryption (TLS) essential?

Answers:

  1. Transport security (TLS), authentication/authorization, and input validation.
  2. WS-Security provides authentication (UsernameToken), integrity (XML Signature), and confidentiality (XML Encryption).
  3. Authentication verifies identity; authorization verifies what an authenticated user is allowed to do.
  4. XXE uses XML entity processing to read files or perform SSRF. Prevent with defusedxml library.
  5. TLS encrypts all data in transit, preventing eavesdropping and man-in-the-middle attacks.

Challenge: Perform a security audit of a SOAP-based banking service. Test for: missing TLS, weak WS-Security, XXE vulnerability, SQL Injection via XML input, and insufficient authorization checks.

FAQ

What is the difference between WS-Security and TLS?

: TLS encrypts the transport layer; WS-Security provides end-to-end message-level security independent of transport.

Can REST services use WS-Security?

: WS-Security is designed for SOAP. REST services typically use OAuth 2.0, JWT, or API keys.

What is OWASP and why is it relevant to web services?

: OWASP publishes the top security risks for web applications and APIs, providing guidance for secure development.

How do you prevent replay attacks?

: Use timestamps and nonces in message headers, combined with TLS to prevent interception and replay.

What is role-based access control (RBAC) for web services?

: RBAC restricts access based on user roles, ensuring users can only perform actions permitted by their role.

Mini Project

Secure a SOAP web service with: TLS certificate, WS-Security UsernameToken authentication, XML input validation using defusedxml, request size limiting (1MB max), audit logging, and Rate Limiting per IP. Test each security layer.

What's Next

Explore Web service architecture for designing security into service design, or learn about Web service security monitoring for detecting attacks.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro