Skip to content

Security: FlossWare/nexus-java

Security

SECURITY.md

Security Policy

Supported Versions

Version Supported
2.x
1.x

Reporting a Vulnerability

security.txt: /.well-known/security.txt (RFC 9116 compliant)

If you discover a security vulnerability in JNexus, please report it by:

  1. DO NOT open a public GitHub issue
  2. Preferred: GitHub Security Advisories
  3. Email: sfloess@redhat.com
  4. Include:
    • Description of the vulnerability
    • Steps to reproduce
    • Potential impact
    • Suggested fix (if available)

You can expect:

  • Acknowledgment within 48 hours
  • Assessment and response within 7 days
  • Credit in security advisory (if desired)

Software Bill of Materials (SBOM)

JNexus generates CycloneDX SBOMs for transparency and supply chain security:

Availability:

  • GitHub Releases: Attached to each release
    • jnexus-sbom.json - Machine-readable JSON format
    • jnexus-sbom.xml - CycloneDX XML format
    • jnexus-sbom.csv - Human-readable CSV format
  • Build Artifacts: Generated during Maven package phase
    • Location: target/jnexus-sbom.*

What's Included:

  • All direct dependencies (Picocli, Jackson, etc.)
  • All transitive dependencies
  • Version information
  • License information
  • Component hashes (SHA-256)
  • PURL identifiers

Standards Compliance:

  • ✅ CycloneDX 1.6 specification
  • ✅ NTIA Minimum Elements for SBOM
  • ✅ Executive Order 14028 requirements

Generate Manually:

mvn cyclonedx:makeAggregateBom
# Output: target/jnexus-sbom.{json,xml,csv}

Hall of Fame

Security researchers who have responsibly disclosed vulnerabilities:

No vulnerabilities reported yet

Security Best Practices

Credential Storage

Desktop Application:

Starting in version 1.30, the desktop application encrypts passwords using AES-256-GCM when stored in ~/.flossware/nexus/nexus.properties.

Encryption Details:

  • Algorithm: AES-256-GCM (authenticated encryption)
  • Key Derivation: PBKDF2-HMAC-SHA256 with 100,000 iterations
  • Key Material: Derived from hostname + user home directory (machine-specific)
  • IV: Random 12-byte IV per encryption
  • Authentication: 128-bit GCM authentication tag
  • Encoding: Base64 for storage in properties files

Automatic Behavior:

  • Passwords are automatically encrypted when saving credentials
  • Existing plaintext passwords are auto-migrated to encrypted format on next save
  • Encrypted passwords are transparently decrypted when loading

Important Limitations:

  • Encrypted credentials are machine-specific (tied to hostname and user home directory)
  • Cannot copy encrypted credentials to other machines
  • Changing hostname or user home directory invalidates encrypted credentials
  • If credentials become corrupted, delete ~/.flossware/nexus/nexus.properties and reconfigure

Security recommendations:

  1. File Permissions: Ensure your properties file has restrictive permissions:

    chmod 600 ~/.flossware/nexus/nexus.properties
  2. Use Environment Variables: For CI/CD and automated environments, use environment variables instead of files:

    export NEXUS_URL="https://nexus.example.com"
    export NEXUS_USER="your-username"
    export NEXUS_PASSWORD="your-token"
  3. Use Tokens, Not Passwords: Generate Nexus user tokens instead of using your actual password:

    • Log into Nexus UI
    • User → Profile → User Token
    • Generate and use the token as your password
  4. Never Commit Credentials: Add to .gitignore:

    # JNexus credentials
    .flossware/
    nexus.properties
  5. Use Profile-Based Configuration: Separate credentials for different environments:

    # Development
    ~/.flossware/nexus/nexus-dev.properties
    
    # Production (stored securely, restricted access)
    ~/.flossware/nexus/nexus-prod.properties

All Platforms Credential Encryption:

All platforms now provide encrypted credential storage:

  • Desktop (Java v1.30+):

    • Uses JEncrypt library for encryption
    • AES-256-GCM encryption with PBKDF2-HMAC-SHA256 key derivation (100,000 iterations)
    • Machine-specific encryption key (derived from hostname + user home directory)
    • Random 12-byte IV per encryption
    • 128-bit GCM authentication tag prevents tampering
    • Automatic migration from plaintext
    • Thread-safe concurrent encryption/decryption
  • Android:

    • AES256_GCM encryption via EncryptedSharedPreferences
    • Android Keystore for key management
    • Hardware-backed encryption when available
  • iOS/macOS:

    • AES-256 hardware-backed encryption via Keychain Services
    • Secure Enclave integration
    • System-level credential protection

Best Practice: Environment variables remain the most secure option for CI/CD and production environments as they never touch disk.

Network Security

Always Use HTTPS:

JNexus will warn you when using HTTP:

WARNING: Using HTTP instead of HTTPS. Credentials will be sent over an insecure connection.
         Consider using HTTPS for production environments.

Reasons to use HTTPS:

  • Credentials are sent using HTTP Basic Auth (Base64-encoded, not encrypted)
  • HTTP transmits credentials in cleartext over the network
  • Man-in-the-middle attacks can intercept credentials
  • HTTPS encrypts all traffic, protecting credentials in transit

Certificate Validation:

Java's HttpClient validates SSL/TLS certificates by default. If you encounter certificate issues:

  1. Proper Fix: Add the certificate to your Java truststore:

    keytool -import -alias nexus -file nexus.crt -keystore $JAVA_HOME/lib/security/cacerts
  2. DO NOT: Disable certificate validation in production

  3. DO NOT: Use self-signed certificates in production

Input Validation

JNexus validates user input to prevent common attacks:

Repository Names:

  • Alphanumeric characters, dots, hyphens, underscores only
  • No path traversal sequences (../, /, \)
  • No leading/trailing special characters

URLs:

  • Valid URI/URL format required
  • Must include scheme (http:// or https://)
  • Must include hostname
  • Malformed URLs are rejected with clear error messages

Regular Expressions:

  • Regex patterns are validated before use
  • Invalid patterns throw IllegalArgumentException
  • No regex execution on untrusted input

Safe Deletion Practices

Always Test with Dry-Run First:

# Desktop CLI
./jnexus.sh delete my-repo --regex ".*SNAPSHOT.*" --dry-run

# Shows what would be deleted WITHOUT actually deleting

Review Before Confirming:

The CLI requires explicit "yes" confirmation (not just "y") to prevent accidental deletion from shell history or scripts.

Backup Critical Repositories:

Before bulk deletions:

  1. Export component list: Redirect output to file
  2. Create Nexus repository backup
  3. Test deletion on a non-production instance first

Deletion is Permanent:

Nexus does not provide an "undo" feature. Once deleted, components cannot be recovered unless you have a backup.

Access Control

Principle of Least Privilege:

  1. Create Dedicated Nexus Users: Don't use admin credentials
  2. Grant Minimum Permissions: Only grant delete permissions to repositories that need cleanup
  3. Use Role-Based Access Control: Nexus supports roles - create a "cleanup" role with limited permissions
  4. Rotate Credentials Regularly: Change passwords/tokens periodically
  5. Audit Access: Review Nexus audit logs for unauthorized access attempts

CI/CD Security

Secrets Management:

Use your CI/CD platform's secrets management:

# GitHub Actions
env:
  NEXUS_URL: ${{ secrets.NEXUS_URL }}
  NEXUS_USER: ${{ secrets.NEXUS_USER }}
  NEXUS_PASSWORD: ${{ secrets.NEXUS_TOKEN }}

# GitLab CI
variables:
  NEXUS_URL: $NEXUS_URL  # Defined in project settings
  NEXUS_USER: $NEXUS_USER
  NEXUS_PASSWORD: $NEXUS_PASSWORD

Never:

  • Hard-code credentials in CI/CD configuration files
  • Echo credentials in build logs
  • Store credentials in version control
  • Share credentials across multiple projects unnecessarily

Container Security

When Running in Docker:

# Use secrets, not environment variables in docker-compose.yml
docker run -e NEXUS_URL -e NEXUS_USER -e NEXUS_PASSWORD jnexus

# Better: Use Docker secrets
docker secret create nexus_password /path/to/password.txt
docker service create --secret nexus_password jnexus

Minimize Attack Surface:

  • Run as non-root user
  • Use minimal base image
  • Keep JDK updated
  • Scan images for vulnerabilities

Known Limitations

  1. Machine-Specific Encryption: Desktop credentials are encrypted with machine-specific keys

    • Encrypted credentials cannot be copied to other machines
    • Changing hostname or user home directory invalidates credentials
    • Mitigation: Use environment variables for multi-machine deployments
    • Mitigation: Maintain separate credential files per machine
  2. HTTP Basic Auth: Credentials sent in HTTP headers (Base64-encoded)

    • Mitigation: Always use HTTPS to encrypt network traffic
    • Mitigation: Use short-lived tokens instead of passwords
  3. No 2FA Support: JNexus does not support two-factor authentication

    • Nexus itself may support 2FA at the server level
    • Use Nexus server-side 2FA for web UI access

Security Checklist

Before deploying JNexus in production:

  • Using HTTPS URLs only (no HTTP)
  • Credentials file has chmod 600 permissions
  • Using Nexus user tokens (not passwords)
  • Credentials not committed to version control
  • CI/CD uses secrets management (not plaintext)
  • Tested dry-run before actual deletions
  • Nexus user has minimum required permissions
  • Regular credential rotation scheduled
  • Audit logging enabled in Nexus
  • Using latest JNexus version
  • Using Java 21 with latest security patches

Secure Deployment Example

# 1. Create restricted user in Nexus with cleanup permissions only
# (via Nexus UI)

# 2. Generate user token (not password)
# Nexus UI → User → Profile → User Token

# 3. Create properties file with restricted permissions
mkdir -p ~/.flossware/nexus
cat > ~/.flossware/nexus/nexus.properties <<EOF
nexus.url=https://nexus.example.com
nexus.user=cleanup-user
nexus.password=generated-token-here
EOF
chmod 600 ~/.flossware/nexus/nexus.properties

# 4. Verify HTTPS is used
grep "https://" ~/.flossware/nexus/nexus.properties

# 5. Test with dry-run first
./jnexus.sh delete my-repo --regex ".*old.*" --dry-run

# 6. Review output, then execute
./jnexus.sh delete my-repo --regex ".*old.*"

Security Updates

Subscribe to security advisories:

  • Watch this repository for security announcements
  • Follow releases for security patches
  • Update to latest version promptly

Additional Resources

There aren't any published security advisories