diff --git a/.classpath b/.classpath
deleted file mode 100644
index bbcb4564b..000000000
--- a/.classpath
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.codenvy/project.json b/.codenvy/project.json
new file mode 100644
index 000000000..df32873a0
--- /dev/null
+++ b/.codenvy/project.json
@@ -0,0 +1 @@
+{"builders":{"configs":{},"default":"maven"},"mixinTypes":["contribution"],"runners":{"configs":{"system:/java/codenvy-cli":{"ram":1000,"variables":{},"options":{}}},"default":"system:/java/codenvy-cli"},"type":"maven","attributes":{"languageVersion":["1.6"],"language":["java"],"contribute_branch":["master"],"contribute_mode":["contribute"]}}
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..74f99db34
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,77 @@
+# Autodetect text files
+#
+# In addition:
+# Windows developers should set:
+# git config --global core.autocrlf true
+# UNIX / MacOS develoers should set:
+# git config --global core.autocrlf input
+* text=auto
+
+#
+# And configure default EOL terminators for various text types
+#
+
+# Explicitly declare text files you want to always be normalized and converted
+# to native line endings on checkout.
+*.java text
+*.properties text
+*.xml text
+*.xsd text
+*.dtd text
+*.MF text
+*.md text
+*.html text
+*.tld text
+*.json text
+
+# Declare files that will always have CRLF line endings on checkout.
+*.cmd text eol=crlf
+*.bat text eol=crlf
+# Because *nix editors / paginators can handle either way, but braindead
+# Windoze notepad which is used by default to handle text files in Windows,
+# not so much, we also make the concession here to use CRLF for EOL.
+*.txt text eol=crlf
+# Ditto for Eclipse related preferences
+*.prefs text eol=crlf
+
+# Declare files that will always have LF line endings on checkout
+*.sh text eol=lf
+*.bsh text eol=lf
+*.ksh text eol=lf
+
+# Eclipse stuff
+.settings/* text eol=crlf
+.classpath text eol=crlf
+.project text eol=crlf
+
+# Miscellaneous text
+.gitattributes text eol=lf
+.gitignore text eol=lf
+*.MF text eol=crlf
+LICENSE text eol=crlf
+LICENSE-CONTENT text eol=crlf
+LICENSE-README text eol=crlf
+
+
+# Denote all files that are truly binary and should not be modified,
+# or simply replaced in whole if committed.
+*.jpg binary
+*.JPG binary
+*.png binary
+*.jks binary
+*.ser binary
+*.doc binary
+*.docx binary
+*.xls binary
+*.xlsx binary
+*.pptx binary
+*.odt binary
+*.pdf binary
+*.zip binary
+*.jar binary
+*.war binary
+*.ear binary
+*.7z binary
+*.rar binary
+*.tgz binary
+*.tar binary
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 000000000..106bef3e2
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,40 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: bug
+assignees: ''
+---
+
+[**NOTE:** Please do NOT just ask general questions here as they will _not_ be answered. Instead, please use the GitHub Discussions and create a new topic under 'Questions and Answers". Also, please delete the instructions and replace them with actual text and delete the sections that are not relevant.]
+
+#### Describe the bug
+A clear and concise description of what the bug is.
+
+#### Specify what ESAPI version(s) you are experiencing this bug in
+This is especially important if it is not the latest version of ESAPI. Also, if you are using the Jakarta version (e.g., 'jakarta'), then please note that as well.
+
+#### To Reproduce
+List the steps to reproduce the behavior or (ideally) attach a small JUnit test to reproduce the problem. Please _be specific_.
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+Note also any specific configuration changes that are needed to replicate the problem. That is especially important if you are not using the default configuration files (ESAPI.properties, validation.properties, antisamy-esapi.xml, etc.)
+
+#### Expected behavior
+A clear and concise description of what you expected to happen.
+
+#### Screenshots
+If applicable, add screenshots to help explain your problem.
+[**NOTE:** Please do NOT just ask general questions here as they will _not_ be answered. Instead, please use the GitHub Discussions and create a new topic under 'Questions and Answers".
+Please delete any irrelevant portion of this template before submitting your GitHub issue. Thanks.]
+
+#### Platform environment (please complete the following information)
+ - OS: [e.g. iOS]
+ - Browser [e.g. chrome, safari]
+ - JDK version used with ESAPI
+
+#### Additional context
+Add any other context about the problem here.
+If known, please select the label corresponding to the affected ESAPI component.
diff --git a/.github/ISSUE_TEMPLATE/enhancement-request.md b/.github/ISSUE_TEMPLATE/enhancement-request.md
new file mode 100644
index 000000000..c525b5a48
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/enhancement-request.md
@@ -0,0 +1,21 @@
+---
+name: Enhancement request
+about: Suggest an enhancment for this project
+title: ''
+labels: enhancement
+assignees: ''
+---
+
+[**NOTE:** Please do NOT just ask general questions here as they will _not_ be answered. Instead, please use the GitHub Discussions and create a new topic under 'Questions and Answers". Please delete any irrelevant portion of this template before submitting your GitHub issue. Thanks.]
+
+#### Is your feature request related to a problem? Please describe.
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+#### Describe the solution you'd like
+A clear and concise description of what you want to happen. Note that this may include some appropriate type of documentation that is lacking or unclear.
+
+#### Describe alternatives you've considered including other security libraries
+A clear and concise description of any alternative solutions or features you've considered.
+
+#### Additional context
+Add any other context or screenshots about the feature request here.
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
new file mode 100644
index 000000000..a81c84710
--- /dev/null
+++ b/.github/workflows/maven.yml
@@ -0,0 +1,24 @@
+# This workflow will build a Java project with Maven
+# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
+
+name: Java CI with Maven
+
+on:
+ push:
+ branches: [ develop ]
+ pull_request:
+ branches: [ develop ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 1.8
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+ - name: Build with Maven
+ run: mvn -B package --file pom.xml
diff --git a/.github/workflows/superlinter.yml b/.github/workflows/superlinter.yml
new file mode 100644
index 000000000..b263fddf9
--- /dev/null
+++ b/.github/workflows/superlinter.yml
@@ -0,0 +1,26 @@
+name: Super-Linter
+
+# Run this workflow every time a new commit pushed to your repository
+on: push
+
+jobs:
+ # Set the job key. The key is displayed as the job name
+ # when a job name is not provided
+ super-lint:
+ # Name the Job
+ name: Lint code base
+ # Set the type of machine to run on
+ runs-on: ubuntu-latest
+
+ steps:
+ # Checks out a copy of your repository on the ubuntu-latest machine
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ # Runs the Super-Linter action and ignore errors
+ - name: Run Super-Linter
+ uses: github/super-linter@v4
+ env:
+ DEFAULT_BRANCH: develop
+ DISABLE_ERRORS: true
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..a9b3cec31
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,20 @@
+# Eclipse / IntelliJ / Maven / backup editor files
+/target
+/.settings/**
+.classpath
+.java-version
+.project
+*.swp
+*~
+*.iml
+.idea/
+*.iws
+*.eml
+out/
+bin/
+
+# Leftover test files
+ciphertext-portable.ser
+ReferenceEncryptedProperties.test.txt
+test.out
+.DS_Store
diff --git a/.project b/.project
deleted file mode 100644
index 7beea0bc3..000000000
--- a/.project
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- ESAPI
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.eclipse.wst.common.project.facet.core.builder
-
-
-
-
- org.eclipse.wst.validation.validationbuilder
-
-
-
-
-
- org.eclipse.wst.common.project.facet.core.nature
- org.eclipse.jdt.core.javanature
- org.eclipse.wst.common.modulecore.ModuleCoreNature
- org.eclipse.jem.workbench.JavaEMFNature
-
-
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index e50175cc7..000000000
--- a/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,12 +0,0 @@
-#Thu May 08 12:23:55 CDT 2008
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.4
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.4
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
-org.eclipse.jdt.core.compiler.source=1.4
diff --git a/.snyk b/.snyk
new file mode 100644
index 000000000..79fa52da9
--- /dev/null
+++ b/.snyk
@@ -0,0 +1,2 @@
+# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
+version: v1.14.0
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 000000000..e390cfab6
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,17 @@
+language: java
+jdk:
+- oraclejdk7
+env:
+ global:
+ - secure: "aDhH/FBa9CSX3P3UucVJGghHkzHwmw8DhEdklUnb5HI44CpQs5rVNBQLG6ClqrJGl5BEghaHG9mQ0alVrZoqGCR4UA0qhGCmeRyo+SL7z44tHFq/VdWbZJcnSXeq+CzGc4rgkIg2XBrgGKKq5EfUxXjsYQUA/mIslWhnmQtfn0gjiobJkOdGAOJ4RY6cAyTtgNbv8AZg71hnPDusz+F/Somy1GPp2oFW0gAJyOUbDqol6bx8ajTl/+NJkQL9uSlUEGqyeMwXGW0Z901Vbn+Btwl7QtnrSFxOOOlQSUIAFGKTqAt/DzOeKi0Guv5uE4nqR50veOge5StbpgDqTq6a101DYNTyMFeE4plTNKHawnnyMe7v0yTDsnk+PeeSe8hkkdqiRLiBufriVnlzlfQt9TbWfE7aRhy6U0wqvlMvMgOOmXl5+eyLf1CtdRCbWeh2eZFISbD35y8EZbGY/bP33sC8jHlWROtykdMkVzcZ6N+mP+pB+SSqy+5hUMFUCDKyzRoIjHioVJS0S+Ul7CpEeLNKTy23IzO5VSh9dysH+hf+dbdAhgEe/XBEpUxZnV400fww5LW+vAlDpY+QwqdzwpabofTYaRfyRT7nQC3qAgMrQZopqwehdKyOTgpGIKM4lqqsSLz0F/LZ57fUh8DD2sZl2M4VKL6SQ3KPEM+DC/w="
+after_success:
+ - mvn clean cobertura:cobertura coveralls:report
+addons:
+ coverity_scan:
+ project:
+ name: "bkimminich/esapi-java-legacy"
+ description: "OWASP ESAPI 2.x (Legacy) build submitted via Travis CI"
+ notification_email: bjoern.kimminich@owasp.org
+ build_command_prepend: "mvn clean"
+ build_command: "mvn -DskipTests=true compile"
+ branch_pattern: coverity_scan
\ No newline at end of file
diff --git a/CONTRIBUTING-TO-ESAPI.txt b/CONTRIBUTING-TO-ESAPI.txt
new file mode 100644
index 000000000..970efcac1
--- /dev/null
+++ b/CONTRIBUTING-TO-ESAPI.txt
@@ -0,0 +1,134 @@
+ Contributing to ESAPI
+
+Getting Started:
+ If you have not already done so, go back and read the section
+ "Contributing to ESAPI legacy" in ESAPI's README.md file. It
+ may contain updates and advice not contained herein.
+
+A Special Note on GitHub Authentication:
+ GitHub has announced that they are deprecating password based authentication
+ using username / password and beginning 2021-08-13, you will no longer be
+ able to your password to authenticate to 'git' operations on GitHub.com.
+ Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/
+ for details and plan accordingly.
+
+A Special Note Regarding Making Commits for PRs
+ Shortly after the 2.5.1.0 ESAPI release in late November 2022, the ESAPI
+ team decided to lock down the 'develop' amd 'main' branches. Merges from
+ PRs are done to the 'develop' branch. That means that if you intend to
+ contribute to ESAPI, you must be signing your commits. Please see the
+ GitHub instructions at
+ https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits
+ for details.
+
+
+Finding Something Interesting to Work on:
+
+ See the section "Contributing to ESAPI legacy in
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/README.md
+ While you don't *have* to work on something labeled "good first issue"
+ or "help wanted", those are good places to start for someone not yet
+ familiar with the ESAPI code base.
+
+ You will need a account on GitHub though. Once you create one, let us know
+ what it is. Then if you want to work on a particular issue, we can assign
+ it to you so someone else won't take it.
+
+ If you have questions, email Kevin Wall (Kevin.W.Wall@gmail.com) or Matt
+ Seil (xeno6696@gmail.com).
+
+Overview:
+ We are following the branching model described in
+ https://nvie.com/posts/a-successful-git-branching-model
+ If you are unfamiliar with it, you would be advised to give it a quick
+ perusal. The major point is that the 'main' (formerly 'master') branch is
+ reserved for official releases (which will be tagged), the 'develop' branch
+ is used for ongoing development work and is the default branch, and we
+ generally work off 'issue' branches named 'issue-#' where # is the GitHub
+ issue number. (The last is not an absolute requirement, but rather a
+ suggested approach.)
+
+ Finally, we recommend setting the git property 'core.autocrlf' to 'input'
+ in your $HOME/.gitconfig file; e.g., that file should contain something
+ like this:
+
+ [core]
+ autocrlf = input
+
+Required Software:
+ We use Maven for building. Maven 3.3.9 or later is required. You also need
+ JDK 8 or later. [Note: If you use JDK 9 or later, there will be multiple
+ failures when you try to run 'mvn test' as well as some general warnings.
+ See ESAPI GitHub issue #496 for details. We welcome volunteers to address
+ this.]
+
+Building ESAPI:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Building-ESAPI briefly discusses how to
+ build ESAPI via Maven.
+
+ Also https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-for-Java-with-Eclipse
+ describes how to use ESAPI with Eclipse and
+ https://www.owasp.org/index.php/ESAPI-BuildingWithEclipse is a very old
+ overview of how to build ESAPI in Eclipse.
+
+ As always, any contributions to ESAPI's admittedly skimpy documentation
+ in this area is welcome.
+
+Steps to work with ESAPI:
+ I usually do everything from the bash command prompt in Linux Mint,
+ but other people use Windows. If you prefer an IDE, I can't help you
+ much, but I can help with at least modest problems. If you have more
+ difficult problems, I will probably refer you to my project co-leader,
+ Matt who groks git a lot better than I.
+
+ But the basic high level steps are:
+ 1. Fork https://github.com/ESAPI/esapi-java-legacy to your own GitHub
+ repository using the GitHub web site.
+ 2. On your local laptop, clone your own GitHub ESAPI repo (i.e, the
+ forked repo created in previous step)
+ 3. Create a new branch to work on an issue. I usually name the branch
+ 'issue-#' where '#' is the GitHub issue # is will be working on, but
+ you can call it whatever. E.g.,
+ git checkout -b issue-#
+ 4. Work on the GitHub issue on this newly created issue-# branch. Be sure
+ that you also create new JUnit tests as required that confirm that the
+ issue is corrected, or if you are introducing new functionality, ensure
+ that functionality is sufficiently covered.
+ 5. Make sure everything builds correctly and all the JUnit tests pass
+ ('mvn test'). [Note: There are some known issues with test failures if
+ your are running under Windows and your local ESAPI Git repo located
+ anywhere other than the C: drive, where the test
+ ValidatorTest.testIsValidDirectoryPath() fails. Also, if you are using
+ JDK 7 on Mac-OS, there is one know test failure in
+ SecurityProviderLoaderTest.testWithBouncyCastle(). That same test works
+ with JDK 8.]
+ 6. If you have added any dependencies, please also run
+ mvn org.owasp:dependency-check-maven:check
+ to run OWASP Dependency-Check and look at the generated report
+ left in 'target/dependency-check-report.html' to make sure there
+ were not any CVEs introduced. (Alternately you can run 'mvn verify'
+ which will first run the tests and then run Dependency-Check.) Note
+ if this is the first time you have run Dependency-Check for ESAPI,
+ expect it to take a while (often 30 minutes or so!).
+ 7. Commit your changes locally.
+ 8. Push your 'issue-#' branch to your personal, forked ESAPI GitHub repo. E.g.,
+ $ git checkout issue-444
+ $ git remote -v | grep origin # Confirm 'origin' refers to YOUR PERSONAL GitHub repo
+ $ git push origin issue-444 # Push the committed changes on the 'issue-444' branch
+ 9. Go to your personal, forked ESAPI GitHub repo (web interface) and create a
+ 'Pull Request' (PR) from your 'issue-#' branch.
+ 10. Back on your local personal laptop / desktop, merge your issue branch with
+ your local 'develop' branch. I.e.,
+ $ git checkout develop
+ $ git merge issue-444
+ 11. Do not remove your branch on your forked repository until your PR from your
+ branch has been merged into the ESAPI/esapi-java/legacy 'develop' branch.
+ Note at least one the 3 main contributors on will review your commits before
+ merging them and they may do a formal code review and request further changes.
+ Once they are satisfied, they will merge your PR.
+
+In theory, you can do all this 'git' magic from Eclipse and presumably other
+IDEs like Oracle NetBeans or IntelliJ IDEA). From Eclipse, it is right-click
+on the project and then select 'Team' to do the commits, etc. If you choose that
+route, you're pretty much on your own because none of us use that for Git
+interactions.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..4c095cb35
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,118 @@
+# Contributing to ESAPI -- Details
+
+## Getting Started
+If you have not already done so, go back and read the section
+"[Contributing to ESAPI legacy](https://github.com/ESAPI/esapi-java-legacy/blob/develop/README.md#contributing-to-esapi-legacy)" in ESAPI's README.md file. It
+may contain updates and advice not contained herein.
+
+### A Special Note on GitHub Authentication
+GitHub has announced that they are deprecating password based authentication
+using username / password and beginning 2021-08-13, you will no longer be
+able to your password to authenticate to 'git' operations on GitHub.com.
+Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/
+for details and plan accordingly.
+
+### A Special Note Regarding Making Commits for PRs
+Shortly after the 2.5.1.0 ESAPI release in late November 2022, the ESAPI
+team decided to lock down the 'develop' amd 'main' branches. Merges from
+PRs are done to the 'develop' branch. That means that if you intend to
+contribute to ESAPI, you must be signing your commits. Please see the
+GitHub instructions at
+ https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits
+for details.
+
+### Git Branching Model
+We are following the branching model described in
+ https://nvie.com/posts/a-successful-git-branching-model
+If you are unfamiliar with it, you would be advised to give it a quick
+perusal. The major point is that the 'main' (formerly 'master') branch is
+reserved for official releases (which will be tagged), the 'develop' branch
+is used for ongoing development work and is the default branch, and we
+generally work off 'issue' branches named 'issue-#' where # is the GitHub
+issue number. (The last is not an absolute requirement, but rather a
+suggested approach.)
+
+Finally, we recommend setting the git property 'core.autocrlf' to 'input'
+in your $HOME/.gitconfig file; e.g., that file should contain something
+like this:
+
+ [core]
+ autocrlf = input
+
+
+### Required Software
+We use Maven for building. Maven 3.6.3 or later is required. You also need
+JDK 8 or later. [Note: If you use JDK 9 or later, there will be multiple
+failures when you try to run 'mvn test' as well as some general warnings.
+See [ESAPI GitHub issue #496](https://github.com/ESAPI/esapi-java-legacy/issues/496) for details. We welcome volunteers to address
+this.]
+## Finding Something Interesting to Work on
+
+See the section [Contributing to ESAPI Legacy](https://github.com/ESAPI/esapi-java-legacy/blob/develop/README.md#contributing-to-esapi-legacy)
+in the ESAPI README for suggestions. While you don't *have* to work on something labeled "good first issue"
+or "help wanted", those are good places to start for someone not yet familiar with the ESAPI code base.
+
+You will need a account on GitHub though. Once you create one, let us know
+what it is. Then if you want to work on a particular issue, we can assign
+it to you so someone else won't take it.
+
+If you have questions, email Kevin Wall (Kevin.W.Wall@gmail.com) or Matt
+Seil (xeno6696@gmail.com).
+
+
+## Building ESAPI
+See our local GitHub wiki page, [Building ESAPI](https://github.com/ESAPI/esapi-java-legacy/wiki/Building-ESAPI),
+which briefly discusses how to build ESAPI via Maven.
+
+You can also refer to [Using ESAPI for Java with Eclipse](https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-for-Java-with-Eclipse)
+if you prefer working from IDEs. There is also a much older ESAPI wiki page,
+[Building with Eclipse](https://www.owasp.org/index.php/ESAPI-BuildingWithEclipse)
+that might be useful.
+
+As always, any contributions to ESAPI's admittedly skimpy documentation in this area is welcome.
+In particular, contributing some hints about debugging applications using ESAPI
+would be very useful to our ESAPI clients.
+
+## Steps to work with ESAPI
+I usually do everything from the bash command prompt in Linux Mint,
+but other people use Windows. If you prefer an IDE, I can't help you
+much, but I can help with at least modest problems. If you have more
+difficult problems, I will probably refer you to my project co-leader,
+Matt who groks git a lot better than I.
+
+But the basic high level steps are:
+
+1. Fork https://github.com/ESAPI/esapi-java-legacy to your own GitHub repository using the GitHub web site.
+2. On your local laptop, clone your own GitHub ESAPI repo (i.e, the forked repo created in previous step)
+3. Create a new branch to work on an issue. I usually name the branch 'issue-#' where '#' is the GitHub issue # is will be working on, but you can call it whatever. E.g.,
+ ```bash
+ $ git checkout -b issue-#
+ ```
+4. Work on the GitHub issue on this newly created issue-# branch. Be sure that you also create new JUnit tests as required that confirm that the issue is corrected, or if you are introducing new functionality, ensure
+ that functionality is sufficiently covered.
+5. Make sure everything builds correctly and all the JUnit tests pass ('mvn test'). [Note: There are some known issues with test failures if your are running under Windows and your local ESAPI Git repo located anywhere other than the C: drive, where the test `ValidatorTest.testIsValidDirectoryPath()` fails.
+6. If you have added any dependencies, please also run OWASP Dependency-Check and look at the generated report left in 'target/dependency-check-report.html' to make sure there were not any CVEs introduced. (Alternately you can run 'mvn verify' which will first run the tests and then run Dependency-Check.) Note if this is the first time you have run Dependency-Check for ESAPI, expect it to take a while (often 30 minutes or so!). To execute Dependency Check from Maven, run:
+ ```bash
+ $ mvn org.owasp:dependency-check-maven:check
+ ```
+7. Commit your changes locally.
+8. Push your 'issue-#' branch to your personal, forked ESAPI GitHub repo. E.g.,
+ ```bash
+ $ git checkout issue-444
+ $ git remote -v | grep origin # Confirm 'origin' refers to YOUR PERSONAL GitHub repo
+ $ git push origin issue-444 # Push the committed changes on the 'issue-444' branch
+ ```
+9. Go to your personal, forked ESAPI GitHub repo (web interface) and create a 'Pull Request' (PR) from your 'issue-#' branch.
+10. Back on your local personal laptop / desktop, merge your issue branch with your local 'develop' branch. I.e.,
+ $ git checkout develop
+ $ git merge issue-444
+11. Do not remove your branch on your forked repository until your PR from your branch has been merged into the ESAPI/esapi-java/legacy 'develop' branch.
+ Note at least one the 3 main contributors on will review your commits before
+ merging them and they may do a formal code review and request further changes.
+ Once they are satisfied, they will merge your PR.
+
+In theory, you can do all this 'git' magic from Eclipse and presumably other
+IDEs like Oracle NetBeans or JetBrains IntelliJ IDEA. From Eclipse, it is right-click
+on the project and then select 'Team' to do the commits, etc. If you choose that
+route, you're pretty much on your own because none of us use that for Git
+interactions.
diff --git a/LICENSE b/LICENSE
index 5d0f11c51..20c1657fa 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,12 +1,12 @@
-The BSD License
-
-Copyright (c) 2007, The OWASP Foundation
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-Neither the name of the OWASP Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
+The BSD License
+
+Copyright (c) 2007, The OWASP Foundation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+Neither the name of the OWASP Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/LICENSE-CONTENT b/LICENSE-CONTENT
new file mode 100644
index 000000000..b5b0f5e05
--- /dev/null
+++ b/LICENSE-CONTENT
@@ -0,0 +1,78 @@
+Creative Commons
+Creative Commons Legal Code
+Attribution-ShareAlike 3.0 Unported
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
+
+License
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
+
+1. Definitions
+
+ 1. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
+ 2. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined below) for the purposes of this License.
+ 3. "Creative Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of adaptations of works made available under that license under this License or a Creative Commons jurisdiction license with the same License Elements as this License.
+ 4. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
+ 5. "License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike.
+ 6. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
+ 7. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
+ 8. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
+ 9. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
+ 10. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
+ 11. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
+
+2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
+
+3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
+
+ 1. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
+ 2. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
+ 3. to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
+ 4. to Distribute and Publicly Perform Adaptations.
+ 5.
+
+ For the avoidance of doubt:
+ 1. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
+ 2. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
+ 3. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
+
+The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
+
+4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
+
+ 1. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested.
+ 2. You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License.
+ 3. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
+ 4. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
+
+5. Representations, Warranties and Disclaimer
+
+UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+
+6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. Termination
+
+ 1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
+ 2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
+
+8. Miscellaneous
+
+ 1. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
+ 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
+ 3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+ 4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
+ 5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
+ 6. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
+
+ Creative Commons Notice
+
+ Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of Licensor.
+
+ Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of the License.
+
+ Creative Commons may be contacted at http://creativecommons.org/.
+
diff --git a/LICENSE-README b/LICENSE-README
new file mode 100644
index 000000000..6968b1478
--- /dev/null
+++ b/LICENSE-README
@@ -0,0 +1,7 @@
+Please note that:
+
+1) The LICENSE file only refers to the licensing of the source and binary code of ESAPI.
+ For example, the actual ESAPI JAR file is only licensed under "The BSD License".
+
+2) The LICENSE-CONTENT file only refers to the licensing of the content and documentation of ESAPI.
+ For example, the documentation directory is only licensed under the Creative Commons/ShareAlike 3.0 Unported license.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..0c31f1de1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,262 @@
+Enterprise Security API for Java (Legacy)
+=================
+
+[](https://travis-ci.org/bkimminich/esapi-java-legacy)
+[](https://coveralls.io/github/bkimminich/esapi-java-legacy?branch=develop)
+[](https://scan.coverity.com/projects/bkimminich-esapi-java-legacy)
+[](https://bestpractices.coreinfrastructure.org/projects/137)
+
+
+
+
+OWASP® ESAPI (The OWASP Enterprise Security API) is a free, open source, web application security control library that makes it easier for programmers to write lower-risk applications. The ESAPI for Java library is designed to make it easier for programmers to retrofit security into existing applications. ESAPI for Java also serves as a solid foundation for new development.
+
+
+
+
+# Jakarta EE Support
+**IMPORTANT:**
+ESAPI has supported the Jakarta Servlet API (i.e., **jakarta.servlet.api**) since release
+2.5.3.0. (Unfortunately, this information was previously missing in this **README** file.)
+
+Therefore, for release 2.5.3.0 and later versions of ESAPI, ESAPI ought to be able to support Spring Boot 3, Spring 6, Tomcat 10,
+and other applications or libraries requiring Jarkata EE. (If you find a case where it does
+not, please file a GitHub issue for it.)
+
+The ESAPI jar file supporting Jakarta will be named esapi-_version_-jakarta.jar. To use that
+specific Jakarta version of ESAPI, in Maven, you would specify your ESAPI dependency in your
+**pom.xml** as:
+```xml
+
+ org.owasp.esapi
+ esapi
+ 2.7.0.0
+ jakarta
+
+```
+(or any other version later than 2.5.3.0). Thanks to Jonathon Putney for creating a PR to
+fix this. There is a long discussion in GitHub Discussion [#768](https://github.com/ESAPI/esapi-java-legacy/discussions/768)
+where this was first announced, for those of you have insomnia or really long attention
+spans and are interested in the approaches that were tried.
+
+Of course, ESAPI also still continues to support the older Java EE Servlet API (i.e., **javax.servlet** namespace) as well. In
+fact, without the
+```xml
+jakarta
+```
+that's the version that will be used by default.
+
+
+# A word about ESAPI vulnerabilities
+A summary of all the vulnerabilities that we have written about in either the
+ESAPI Security Bulletins or in the GitHub Security Advisories may be found
+in this [Vulnerability Summary](https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md).
+It is too lengthy, and if you are using the latest available ESAPI version--generally not relevant--to
+place in this **README** file.
+
+# Where are the OWASP ESAPI wiki pages?
+You can find the official OWASP ESAPI Project wiki pages at
+[https://owasp.org/www-project-enterprise-security-api/](https://owasp.org/www-project-enterprise-security-api/).
+The ESAPI legacy GitHub repo also has several useful [wiki pages](https://github.com/ESAPI/esapi-java-legacy/wiki).
+
+# What does Legacy mean?
+This is the legacy branch of ESAPI which means it is an actively maintained branch of the project, however significant *new* **feature development** for this branch will *not* be done. Features that have already been scheduled for the 2.x branch will move forward.
+Development for the "next generation" of ESAPI (starting with ESAPI 3.0), will be done at the
+GitHub repository at [https://github.com/ESAPI/esapi-java](https://github.com/ESAPI/esapi-java).
+
+**IMPORTANT NOTES:**
+* The default branch for ESAPI legacy is the 'develop' branch (rather than the 'main' (formerly 'master') branch), where future development, bug fixes, etc. are now being done. The 'main' branch is now marked as "protected"; it reflects the latest stable ESAPI release (2.5.3.1 as of this date). Note that this change of making the 'develop' branch the default may affect any pull requests that you were intending to make.
+* Also, the *minimal* baseline Java version to use ESAPI is now Java 8. (This was changed from Java 7 during the 2.4.0.0 release.)
+* Support was dropped for Log4J 1 during ESAPI 2.5.0.0 release. If you need it, configure it via SLF4J. See the
+ [2.5.0.0 release notes](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.5.0.0-release-notes.txt)
+for details.
+
+# Where can I find ESAPI 3.x?
+As mentioned above, you can find it at [https://github.com/ESAPI/esapi-java](https://github.com/ESAPI/esapi-java).
+
+Note however that work on ESAPI 3 has not yet begun in earnest and is only
+in its earliest planning stages. Even the code that is presently there
+will likely change.
+
+# ESAPI Release Notes
+The ESAPI release notes may be found in ESAPI's "documentation" directory. They are generally named "esapi4java-core-*2.#.#.#*-release-notes.txt", where "*2.#.#.#*" refers to the ESAPI release number (which uses semantic versioning).
+
+See the GitHub [Releases](https://github.com/ESAPI/esapi-java-legacy/releases) information for a list of releases which generally
+link to the specific release notes.
+
+### Really IMPORTANT information in release notes - Ignore at your peril
+* Starting with ESAPI 2.2.1.0, important details changed reading the ESAPI
+ Logger. If you have are getting things like ClassNotFoundException, you
+ probably have not read it. Please be sure to read this specific section
+ of the
+ [2.2.1.0 release notes](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.0-release-notes.txt#L128-L155)
+* Starting with ESAPI 2.2.3.0, ESAPI is using a version of AntiSamy that by default includes 'slf4j-simple' and
+ does XML schema validation on the AntiSamy policy files. Please **READ** this
+ section from the
+ [2.2.3.0 release notes](https://github.com/ESAPI/esapi-java-legacy/blob/1312102e79d4ed98d1396f5c56e12f437534d62b/documentation/esapi4java-core-2.2.3.0-release-notes.txt#L22-L34)
+ (at least the beginning portion) for some important notes that likely will affect your use of ESAPI! You have been warned!!!
+* ESAPI 2.3.0.0 is the last release to support Java 7 as the minimal JDK.
+ Starting with release 2.4.0.0, Java 8 or later is required.
+* Starting with ESAPI 2.5.4.0, if you were using ESAPI's default logger, JUL
+ (i.e., you had the property **ESAPI.Logger** set to "org.owasp.esapi.logging.java.JavaLogFactory"),
+ then you must remove (or rename) the old ESAPI configuration file **esapi-java-logger.properties**.
+ Failure to do so will cause ESAPI to throw a `ConfigurationException`, thereby
+ preventing your application from starting. For important additional details, please see
+ the ESAPI GitHub Discussion https://github.com/ESAPI/esapi-java-legacy/discussions/841.
+
+# Locating ESAPI Jar files
+The [latest ESAPI release](https://github.com/ESAPI/esapi-java-legacy/releases/latest) is 2.7.0.0.
+All the *regular* ESAPI jars, with the exception of the ESAPI configuration
+jar (i.e., esapi-2.#.#.#-configuration.jar) and its associated detached
+GPG signature, are available from Maven Central. The ESAPI configuration
+jars are linked under the 'Assets' section to each of the specific
+ESAPI releases under the
+GitHub [Releases page](https://github.com/ESAPI/esapi-java-legacy/releases).
+
+
+However, **before** you start a *new* project using ESAPI, but sure to read "[Should I use ESAPI?](https://owasp.org/www-project-enterprise-security-api/#div-shouldiuseesapi)".
+
+# ESAPI Deprecation Policy
+Unless we unintentionally screw-up, our intent is to keep classes, methods,
+and/or fields which have been annotated as "@deprecated" for a
+minimum of two (2) years or until the next major release number (e.g.,
+3.x as of now), which ever comes first, before we remove them. Note
+that this policy does not apply to classes under
+the **org.owasp.esapi.reference** package. You generally are not expected
+to be using such classes directly in your code. At the ESAPI team's discretion,
+it will also not apply for any known exploitable vulnerabilities for which
+no available workaround exists.
+
+## Exceptions to Deprecation Policy
+We will make some exceptions to the normal 2 year period. In particular, in the
+cases were we believe that keeping a specific deprecated class or method around
+can introduce security issues (generally because many of you have a habit of
+completely ignoring deprecation warnings), we sometimes will shorten that 2 year
+period. When we decide to do that, we will announce that as part of the
+deprecation message.
+
+## Log4J 1.x Removal
+**IMPORTANT NOTES:** As of ESAPI 2.5.0.0, all the Log4J 1.x related code
+has been removed from the ESAPI code base (with the exception of some
+references in documentation). If you must, you still should be able to
+use Log4J 1.x logging via ESAPI SLF4J support. See the ESAPI 2.5.0.0 release
+notes for further details.
+
+# Quickstart - Maven Example
+### Step 1: Add the required dependencies.
+See https://mvnrepository.com/artifact/org.owasp.esapi/esapi/latest, the tab for
+whatever build tool you are using. If you need the Jakarta version, make sure to
+add
+```xml
+ jakarta
+```
+and include whatever jakara.servlet:jakarta.servlet-api version you are using with
+```xml
+ provided
+```
+### Step 2: Obtain the 2 properties files ESAPI.properties and validation.properties
+1. Download these 2 files from the ESAPI release that you are using from https://github.com/ESAPI/esapi-java-legacy/releases
+ and download the esapi--configuration.jar file (and the .asc file if you wish to confirm the GPG signature).
+2. Unjar that configuration file that you just downloaded and find the 2
+ properties files under the "configuration/esapi" subdirectory where you
+ unjarred the config jar.
+3. Read through Javadoc for [DefaultSecurityConfiguration](https://javadoc.io/static/org.owasp.esapi/esapi/2.5.4.0/org/owasp/esapi/reference/DefaultSecurityConfiguration.html)
+ to understand the ways that ESAPI locates these files and then use the mechanism that works best for you. Copy the 2 properties
+ files from the 'configuration/esapi' directory to the directory where you
+ choose to have them reside. Note that you may also edit them to customize
+ them according to your needs.
+
+# Contributing to ESAPI legacy
+### How can I contribute or help with fix bugs?
+Fork and submit a pull request! Easy as pi! (How's that for an irrational
+statement, you math nerds? :) We generally only accept bug fixes, not
+new features because as a legacy project, we don't intend on adding new
+features that we will have to maintain long term (although we may make
+exceptions; see the 'New Features' section in this **README**). If
+you are interesting in doing bug fixes though, the best place to start is the
+[CONTRIBUTING-TO-ESAPI.txt](https://github.com/ESAPI/esapi-java-legacy/blob/develop/CONTRIBUTING-TO-ESAPI.txt)
+
+If you are new to ESAPI, a good place to start is to look for GitHub issues labled as 'good first issue'. (E.g., to find all open issues with that label, use [https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22](https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).)
+
+Again, please find additional important details in the file
+'[CONTRIBUTING-TO-ESAPI.txt](https://github.com/ESAPI/esapi-java-legacy/blob/develop/CONTRIBUTING-TO-ESAPI.txt)',
+which will also describe the tool requirements.
+
+#### Want to report an issue?
+If you have found a bug, then create an issue on the esapi-legacy-java repo at [https://github.com/ESAPI/esapi-java-legacy/issues](https://github.com/ESAPI/esapi-java-legacy/issues)
+As of May 11, 2022, we switched back to using (GitHub) issue templates. (We previously used issue templates when our source code repository was still on Google Code.) You can read more about our issue templates in this brief
+[announcement](https://github.com/ESAPI/esapi-java-legacy/discussions/700).
+
+NOTE: Please do **NOT** use GitHub issues to ask questions about ESAPI.
+If you wish to ask questions, instead, post to either of the 2 mailing
+lists (now on Google Groups) found the References section at the bottom
+of this page. If we find questions posted as GitHub issues, we simply will
+close them and direct you to do this anyhow. Alternately you may use the new
+[Q&A](https://github.com/ESAPI/esapi-java-legacy/discussions/categories/q-a) section of our GitHub
+[Discussions](https://github.com/ESAPI/esapi-java-legacy/discussions) page to ask questions.
+
+When reporting an issue or just asking a question, please be clear and try
+to ensure that the ESAPI development team has sufficient information to be
+able to reproduce your results or to understand your question. If you have
+not already done so, this might be a good time to read Eric S. Raymond's classic
+"[How to Ask Questions the Smart Way](http://www.catb.org/esr/faqs/smart-questions.html)"
+before posting your issue.
+
+#### Find a Vulnerability?
+If believe you have found a vulnerability in ESAPI legacy, for the sake of the
+ESAPI community, please practice Responsible Disclosure. (Note: We will be sure
+you get credit and will work with you to create a GitHub Security Advisory, and
+if you so choose, to pursue filing a CVE via the GitHub CNA.)
+
+You are of course encouraged to first search our GitHub issues list (see above)
+to see if it has already been reported. If it has not, then please contact
+both Kevin W. Wall (kevin.w.wall at gmail.com) and
+Matt Seil (matt.seil at owasp.org) directly. Please do not report
+vulnerabilities via GitHub issues or via the ESAPI mailing lists as
+we wish to keep our users secure while a patch is implemented and
+deployed. If you wish to be acknowledged for finding the vulnerability,
+then please follow this process. Also, when you post the email describing
+the vulnerability, please do so from an email address that you usually
+monitor.
+
+More detail is available in the file
+'[SECURITY.md](https://github.com/ESAPI/esapi-java-legacy/blob/develop/SECURITY.md)'.
+https://raw.githubusercontent.com/ESAPI/esapi-java-legacy/blob/develop/SECURITY.md)'.
+
+### New Features
+If you wish to propose a new feature, the best place to discuss it is via
+new 'Discussions' board, probably under
+'[Ideas](https://github.com/ESAPI/esapi-java-legacy/discussions/categories/ideas)',
+or on the ESAPI-DEV mailing list mentioned below under the References section.
+As mentioned previously, we generally are not considering new features
+for ESAPI 2.x. This is because:
+- ESAPI is already too monolithic and has too many dependencies for its size.
+- We are trying to wind down support of ESAPI 2.x and get ESAPI 3.0 going so any
+ resources we throw at ESAPI 2.x will slow down that goal.
+
+That said, if you believe you have an idea for an additional simple feature that
+does not pull in any additional 3rd party libraries, toss it out there for
+discussion or even show us how it works with a PR. (Note that we vet all pull
+requests, including coding style of any contributions, so please use the same
+coding style found in the files you are already editing.)
+
+# References: Where to Find More Information on ESAPI
+**OWASP Wiki:** https://owasp.org/www-project-enterprise-security-api/
+
+**GitHub ESAPI Wiki:** https://github.com/ESAPI/esapi-java-legacy/wiki
+
+**General Documentation:** Under the '[documentation](https://github.com/ESAPI/esapi-java-legacy/tree/develop/documentation)' folder.
+
+**OWASP Slack Channel:** [#owasp-esapi](https://owasp.slack.com/archives/CQ2ET27AN)
+
+**GitHub Discussions:** [Discussions](https://github.com/ESAPI/esapi-java-legacy/discussions) - Not a lot there yet, but we only started this on May 11, 2022.
+
+**Mailing lists:**
+* As of 2019-03-25, ESAPI's 2 mailing lists were officially moved OFF of their Mailman mailing lists to a new home on Google Groups.
+* The names of the 2 Google Groups are "[esapi-project-users](mailto:esapi-project-users@owasp.org)" and "[esapi-project-dev](mailto:esapi-project-dev@owasp.org)", which you may POST to *after* you subscribe to them via "[Subscribe to ESAPI Users list](https://groups.google.com/a/owasp.org/forum/#!forum/esapi-project-users/join)" and "[Subscribe to ESAPI Developers list](https://groups.google.com/a/owasp.org/forum/#!forum/esapi-project-dev/join)" respectively.
+* Old archives for the old Mailman mailing lists for ESAPI-Users and ESAPI-Dev are still available at https://lists.owasp.org/pipermail/esapi-users/ and https://lists.owasp.org/pipermail/esapi-dev/ respectively.
+* For a general overview of Google Groups and its web interface, see [https://groups.google.com/forum/#!overview](https://groups.google.com/forum/#!overview)
+* For assistance subscribing and unsubscribing to Google Groups, see [https://webapps.stackexchange.com/questions/13508/how-can-i-subscribe-to-a-google-mailing-list-with-a-non-google-e-mail-address/15593#15593](https://webapps.stackexchange.com/questions/13508/how-can-i-subscribe-to-a-google-mailing-list-with-a-non-google-e-mail-address/15593#15593).
+
+----------
+OWASP is a registered trademark of the OWASP Foundation, Inc.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..c551662fc
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,57 @@
+# Security Policy
+
+In general, because the ESAPI core development is so small (3 people, all
+working full time jobs), we can only support the latest version of ESAPI.
+If you are locked in to some previous version and are unable to upgrade
+to the latest version, perhaps one or more of us might consider back-porting
+a patch (especially if it is the only way to address an ESAPI vulnerability),
+but if it is anything but trivial, we would charge a TBD consulting fee.
+
+## Supported Versions
+
+
+| Version | Supported |
+| ------- | ------------------ |
+| 2.7.0.0 (latest) | :white_check_mark: |
+| 2.1.0.1-2.6.2.0 | :x:, upgrade to latest release |
+| <= 1.4.x | :x:, no longer supported AT ALL |
+
+## Reporting a Vulnerability
+
+If you believe that you have found a vulnerability in ESAPI, first please search the
+GitHut issues list (for both open and closed issues) to see if it has already been reported.
+
+If it has not, then please contact **both** of the project leaders, Kevin W. Wall
+(kevin.w.wall at gmail.com) and Matt Seil (matt.seil at owasp.org) _directly_.
+Please do **not** report any suspected vulnerabilities via GitHub issues
+or via the ESAPI mailing lists as we wish to keep our users secure while a patch
+is implemented and deployed. This is because if this is reported as a GitHub
+issue or posted to either ESAPI mailing list, it more or less is equivalent to
+dropping a 0-day on all applications using ESAPI. Instead, we encourage
+responsible disclosure.
+
+If you wish to be acknowledged for finding the vulnerability, then please follow
+this process. One of the 2 ESAPI project leaders will try to contact you within
+at least 5 business days, so when you post the email describing the
+vulnerability, please do so from an email address that you usually monitor.
+If you eventually wish to have it published as a CVE, we will also work with you
+to ensure that you are given proper credit with MITRE and NIST. Even if you do
+not wish to report the vulnerability as a CVE, we will acknowledge you when we
+create a GitHub issue (once the issue is patched) as well as acknowledging you
+in any security bulletin that we may write up and use to notify our users. (If you wish
+to have your identity remain unknown, or perhaps you email address, we can work
+with you on that as well.)
+
+If possible, provide a working proof-of-concept or at least minimally describe
+how it can be exploited in sufficient details that the ESAPI development team
+can understand what needs to be done to fix it. Unfortunately at this time, we
+are not in a position to pay out bug bounties for vulnerabilities.
+
+Eventually, we would like to have BugCrowd handle this, but that's still a ways off.
+
+## ESAPI Security Bulletins and GitHub Security Advisories
+
+There are some ESAPI security bulletins published in the "documentation" directory on GitHub.
+GitHub also has published some Security Advisories for ESAPI.
+For details, see [Vulnerability Summary](https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md).
+
diff --git a/Vulnerability-Summary.md b/Vulnerability-Summary.md
new file mode 100644
index 000000000..e7eacb6d0
--- /dev/null
+++ b/Vulnerability-Summary.md
@@ -0,0 +1,30 @@
+# Summary of ESAPI Security Bulletins and GitHub Security Advisories
+This page attempts to summarize all the ESAPI Security Bulletins and GitHub Security Advisories in a table format. This started out as a lengthy email to the ESAPI User's Google group which you can find at
+"[A word about Log4J vulnerabilities in ESAPI - the TL;DR version](https://groups.google.com/a/owasp.org/g/esapi-project-users/c/_CR8d-dpvMU)",
+but then morphed into this current format as more and more Log4J 1.x vulnerabilities were discovered as well as one in ESAPI itself that we felt compelled to detail.
+
+Note that not all CVEs for ESAPI are reflected here as we only wrote ESAPI
+Security Bulletins for CVEs that we believed were either not exploitable via
+standard ESAPI configurations or that required special explanation above and beyond
+was provided in the description of the CVE.
+
+---
+
+
+|||||||
+|--- |--- |--- |--- |--- |--- |
+|**Relevant ESAPI Security Bulletin / GitHub Security Advisory**|**Summary**|**Relevant CWEs**|**Relevant Vuln ID**|**Notes regarding potential impact**|**ESAPI versions where default configuration is impacted**|
+|[1](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin1.pdf)|MAC bypass in ESAPI symmetric encryption|[CWE-310](https://cwe.mitre.org/data/definitions/310.html)|[CVE-2013-5679](https://nvd.nist.gov/vuln/detail/CVE-2013-5679)|MAC check may be bypassed thus not assuring the authenticity of the received ciphertext.|ESAPI 2.x versions before 2.1.0|
+|[2](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin2.pdf)|Java deserialization vulnerability in Log4J 1 (via SocketServer) for ESAPI logging may lead to code injection|[CWE-502](https://cwe.mitre.org/data/definitions/502.html)|[CVE-2019-17571](https://nvd.nist.gov/vuln/detail/CVE-2019-17571)|SocketServer is a class presumably intended for aggregating Log4J log events. It is a server-side class. ESAPI does not use it, nor any Log4J 1 classes that use it.|None.ESAPI 2.x versions 2.2.1.0 and later default to use JUL (java.util.logging)|
+|[3](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin3.pdf)|This flaw allows a specially-crafted XML file to manipulate the validation process in processed by Xerces’ XMLSchemaValidation class in certain cases.|[CWE-20](https://cwe.mitre.org/data/definitions/20.html)|[SNYK-JAVA-XERCES-608891](https://security.snyk.io/vuln/SNYK-JAVA-XERCES-608891) (related to [CVE-2020-14621](https://nvd.nist.gov/vuln/detail/CVE-2020-14621))|An analysis of the ESAPI and Xerces code shows that ESAPI does not use the vulnerable Xerces class either directly or indirectly.|None, but fixed even with respect to SCA tools for ESAPI 2.2.3.0 and later which AntiSamy 1.6.2, which uses Xerces 2.12.1, where this vulnerability is fixed.|
+|[4](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin4.pdf)|SMTPS (SMTP over SSL/TLS) can allow MITM attack if SMTPAppender is used with Log4J 1 ESAPI logging.|[CWE-295](https://cwe.mitre.org/data/definitions/295.html)|[CVE-2020-9488](https://nvd.nist.gov/vuln/detail/CVE-2020-9488)|If you are using Log4J 1’s SMTPAppender in your code, you already have a direct dependency that makes it exploitable. ESAPI does nothing to cause or prevent that.|None. ESAPI uses ConsoleAppender as the default appender even if ESAPI logging is configured to use Log4J 1.|
+|[5](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin5.pdf)|Invoking the method Commons IO method, FileNameUtils.normalize() with an improper input string could allow a limited path traversal.|[CWE-22](https://cwe.mitre.org/data/definitions/22.html)|[CVE-2021-29425](https://nvd.nist.gov/vuln/detail/CVE-2021-29425)|Commons IO is being pulled in via AntiSamy, which pulls in Apache Batik-CSS. Batik-CSS is part of a larger Apache Xmlgraphics Batik family.Nothing in the Batik family of libraries uses org.apache.commons.io.FileNameUtils and neither ESAPI nor AntiSamy use Commons IO directly. Thus ESAPI is not affected by this CVE.|None. However may still show up in SCA output as AntiSamy using latest Apache Commons IO library version (2.6) that still support Java 7. AntiSamy 1.7 and later will require Java 8 as will ESAPI versions after 2.3.|
+|[6](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin6.pdf)|Flaw in Log4J 1’s JSMAppender could cause insecure deserialization potentially leading to remote code execution.|[CWE-502](https://cwe.mitre.org/data/definitions/502.html)|[CVE-2021-4104](https://nvd.nist.gov/vuln/detail/CVE-2021-4104)|All versions of ESAPI are vulnerable and impacted if your application is doing all 3 of the following:1) Using the deprecated ESAPI Log4J logging.2) You have changed your default log4j.xml (or log4j.properties) file to use JMSAppender.3) An attacker is able to overwrite the contents of your Log4J 1 configuration file.|None. ESAPI uses ConsoleAppender as the default appender even if ESAPI logging is configured to use Log4J 1.|
+|[7](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin7.pdf)|Improper validation (or, specifically, not using parameterized SQL queries) of a SQL statement makes Apache Log4j JDBCAppender vulnerable to SQL Injection. This potentially could allow attackers to execute unintended SQL statements by entering data that is logged via Log4J 1.|[CWE-89](https://cwe.mitre.org/data/definitions/89.html)|[CVE-2022-23305](https://nvd.nist.gov/vuln/detail/CVE-2022-23305)|All versions of ESAPI are vulnerable and impacted if your application is doing both of the following:1) Using the deprecated ESAPI Log4J logging.2) You have changed your default log4j.xml (or log4j.properties) file to use JDBCAppender.|None. ESAPI uses ConsoleAppender as the default appender even if ESAPI logging is configured to use Log4J 1.|
+|[8](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin8.pdf) [GHSA-q77q-vx4q-xx6q](https://github.com/ESAPI/esapi-java-legacy/security/advisories/GHSA-q77q-vx4q-xx6q)|Improper sanitization of user-controlled input permitted by an incorrect regular expression in an ESAPI configuration file can result in that input being unintentionally executing javascript: URLs, resulting in Cross-Site Scripting (XSS).|[CWE-79](https://cwe.mitre.org/data/definitions/79.html)|[CVE-2022-24891](https://nvd.nist.gov/vuln/detail/CVE-2022-24891)|A malformed regular expression in ESAPI’s default AntiSamy policy file, “antisamy-esapi.xml”, accidentally allowed the “:” character to match as a part of the “onsiteURL” regular expression. This allowed 'javascript:' pseudo-URIs to slip past ESAPI which could result in XSS vulnerabilities. Note that this vulnerability dates back at least to the ESAPI 1.4 release.|ESAPI 1.4 and all ESAPI 2.x versions before 2.3.0.0.|
+|[9](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin9.pdf)|Apache Log4j 1’s JMSSink is vulnerable to insecure deserialization of untrusted logged data when the attacker has write access to the Log4j configuration or if the configuration references an LDAP service that the attacker has access to. This may resulting in remote code execution.|[CWE-502](https://cwe.mitre.org/data/definitions/502.html)|[CVE-2022-23302](https://nvd.nist.gov/vuln/detail/CVE-2022-23302)|Remote Code Execution is possible.|None. ESAPI uses ConsoleAppender as the default appender even if ESAPI logging is configured to use Log4J 1.|
+|[10](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin10.pdf)|There is an RCE flaw caused by an insecure deserialization vulnerability in Apache Chainsaw, a Java-based GUI log viewer. CVE-2020-9493 identified a deserialization issue that was present in Apache Chainsaw 2.x prior to 2.1.0. However, prior to Chainsaw V2.0, Chainsaw was a component of Apache Log4j 1.2.x where the same issue exists and remains unfixed.|[CWE-502](https://cwe.mitre.org/data/definitions/502.html)|[CVE-2022-23307](https://nvd.nist.gov/vuln/detail/CVE-2022-23307)|Remote Code Execution is possible if you are running Apache Chainsaw 1.x from the Apache Log4J 1.2.x jar.|None. ESAPI uses ConsoleAppender as the default appender even if ESAPI logging is configured to use Log4J 1.|
+|[GHSA-8m5h-hrqm-pxm2](https://github.com/ESAPI/esapi-java-legacy/security/advisories/GHSA-8m5h-hrqm-pxm2)|The default implementation of `Validator.getValidDirectoryPath(String, String, File, boolean)` may incorrectly treat the tested input string as a child of the specified parent directory. This potentially could allow control-flow bypass checks to be defeated if an attack can specify the entire string representing the 'input' path.|[CWE-22](https://cwe.mitre.org/data/definitions/22.html)|[CVE-2022-23457](https://nvd.nist.gov/vuln/detail/CVE-2022-23457)|Control-flow bypass may be possible.|ESAPI 2.x, prior to the ESAPI 2.3.0.0 release. Version 2.3.0.0 and later are patched.|
+|[11](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin11.pdf)|There is a DoS vulerablity in the FileUploadBase class of Apache Commons FileUpload for releases prior to 1.5. That DoS vulnerability is caused by not limiting the number of files that could be uploaded per single request.|[CWE-770](https://cwe.mitre.org/data/definitions/770.html)|[CVE-2023-24998](https://nvd.nist.gov/vuln/detail/CVE-2023-24998)|None. ESAPI uses a subclass of the affected FileUpladBase abstract class from Apache Commons FileUpload to which a new setFileCountMax() method was added.|Addressed in ESAPI 2.5.2.0 and later.|
+|[12](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin12.pdf) [GHSA-r68h-jhhj-9jvm](https://github.com/ESAPI/esapi-java-legacy/security/advisories/GHSA-r68h-jhhj-9jvm)|Decribes why ESAPI's Validator.isValidSafeHTML is being deprecated and will be removed one year after the ESAPI 2.5.3.0 release date.|[CWE-80](https://cwe.mitre.org/data/definitions/80.html)|N/A (no CVE)|XSS may be possible depending on how the method is used.|All ESAPI versions (all 1.x and 2.x versions). No patch is available until the methods are deleted one year after the ESAPI 2.5.3.0 release date.|
+|[13](https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin13.pdf)|There is a bypass around ESAPI's Encoder.encodeForSQL interface (a method that always carried a strong warning) that be result in SQL injection vulnerabilities in code that use it.|[CWE-138](https://cwe.mitre.org/data/definitions/138.html)|[CVE-2025-5878](https://www.cve.org/CVERecord?id=CVE-2025-5878)|May leave applications that use Encoder.encodeForSQL vulnerable to SQL injection.|ESAPI 2.x versions before 2.7.0|
diff --git a/build.number b/build.number
deleted file mode 100644
index a1184af7d..000000000
--- a/build.number
+++ /dev/null
@@ -1,3 +0,0 @@
-#Build Number for ANT. Do not edit!
-#Wed Jul 09 21:13:02 HST 2008
-build.number=68
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 3bfdc271b..000000000
--- a/build.xml
+++ /dev/null
@@ -1,130 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/dist/owasp-esapi-java-1.2.1.jar b/dist/owasp-esapi-java-1.2.1.jar
deleted file mode 100644
index e2298821a..000000000
Binary files a/dist/owasp-esapi-java-1.2.1.jar and /dev/null differ
diff --git a/dist/owasp-esapi-java-src-1.2.1.zip b/dist/owasp-esapi-java-src-1.2.1.zip
deleted file mode 100644
index 99f149c07..000000000
Binary files a/dist/owasp-esapi-java-src-1.2.1.zip and /dev/null differ
diff --git a/documentation/Analysis-of-ESAPI-2.0-KDF.odt b/documentation/Analysis-of-ESAPI-2.0-KDF.odt
new file mode 100644
index 000000000..7301bc628
Binary files /dev/null and b/documentation/Analysis-of-ESAPI-2.0-KDF.odt differ
diff --git a/documentation/Analysis-of-ESAPI-2.0-KDF.pdf b/documentation/Analysis-of-ESAPI-2.0-KDF.pdf
new file mode 100644
index 000000000..7bc07b17f
Binary files /dev/null and b/documentation/Analysis-of-ESAPI-2.0-KDF.pdf differ
diff --git a/documentation/ESAPI-configuration-user-guide.md b/documentation/ESAPI-configuration-user-guide.md
new file mode 100644
index 000000000..420a4fb27
--- /dev/null
+++ b/documentation/ESAPI-configuration-user-guide.md
@@ -0,0 +1,138 @@
+# ESAPI security configuration API enhancements - user guide
+
+## Motivation
+High number of open Google Issues against security configuration component
+highlighted problem with ESAPI configuration. Moreover, the rules for how and
+where the ESAPI.properties file is found are overly complicated making questions
+about it one of the most frequently asked questions.
+
+The ESAPI interface for its configuration (SecurityConfiguration) is overly
+complicated; it has a 'getter' method specific to almost every ESAPI
+configuration property. This complication leads to a unduly intricate,
+non-modular reference implementation (DefaultSecurityConfiguration) that makes
+it difficult to extend in terms of new functionality; e.g., when desiring to
+introduce a new ESAPI property name in ESAPI.properties.
+
+A new, simpler security configuration interface and implementation is needed.
+Such an implementation would not only be useful for ESAPI 2.x, but could very
+well be used to build the configurator needed by ESAPI 3.
+
+This document describes following changes to ESAPI security API:
+
+1. API simplification
+2. XML configuration support.
+3. Multiple configuration files support.
+
+## API simplification
+
+New interface is introduced: EsapiPropertyLoader, which contains four general
+methods for extraction of configuration properties:
+
+```
+public int getIntProp(String propertyName) throws ConfigurationException;
+public byte[] getByteArrayProp(String propertyName) throws ConfigurationException;
+public Boolean getBooleanProp(String propertyName) throws ConfigurationException;
+public String getStringProp(String propertyName) throws ConfigurationException;
+```
+
+SecurityConfiguration interface is extended with this new contract. Old methods
+have been deprecated as a result, in favor of these new methods. (TBD how long
+until these deprecated methods are removed, but it will be a minumum of 2 years
+or 1 major release [e.g., 3.x], whichever comes first. Also, we may not
+necessarily remove all of them at once, depending on community feedback.)
+
+DefaultSecurityConfiguration implements the new contract. New contract methods implementations work as described in
+'Multiple configuration files support' paragraph.
+
+## Multiple configuration files support
+
+EsapiPropertyManager is the new implementation for getting properties, which uses prioritized property loaders (each one associated with a specific configuration file). This allows to have multiple configuration files existing with priority connected to each one. At this moment, there
+are two configuration files possible to use, the path to them is set through following Java
+system properties:
+
+* org.owasp.esapi.opsteam = (higher priority config)
+* org.owasp.esapi.devteam = (lower priority config)
+
+The first is intended for deployment by an operations team responsible for
+enforcing security for configuration management enterprise-wide. The intent here
+is to allow this operations team to enforce global / company-wide policies such
+as the minimum encryption key size or permitted cryptographic algorithms.
+
+The second is intended for deployment by development teams and is more likely to
+be useful and be tailored for each individual project based on project needs.
+
+If an ESAPI property is set via the configuration file identified by
+org.owasp.esapi.opsteam then that property takes precedence over any property
+set by the configuration file identified by org.owasp.esapi.devteam system
+property. (A warning message will be logged if a property defined in the higher
+priority configuration file is also defined in the configuration file of lower
+priority.)
+
+The DefaultSecurityConfiguration class now uses this mechanism through the new
+API for retrieving properties.
+
+It is not mandatory to have both files configured or even any of them for
+DefaultSecurityConfiguration to work property. It can still use the single
+ESAPI.properties to search for a property. In case of any of the configurations
+or both of the existing, ESAPI.properties has LOWEST priority, so it will be
+searched as last.
+
+### Example properties extraction through DefaultSecurityConfiguration
+
+```java
+ESAPI.securityConfiguration().getBooleanProp("propertyXXX");
+```
+
+where "propertyXXX" is some property name relevant to ESAPI (and
+in this case, one that would hold a boolean value). See ESAPI.properties
+for a list of current property names known to ESAPI.
+
+In above example, following happens:
+
+1. org.owasp.esapi.opsteam configuration is used to get propertyXXX and return it as boolean.
+2. If (1) fails to find property, org.owasp.esapi.devteam is used to get propertyXXX and return it as boolean.
+3. If (2) fails to find property, ESAPI.properties is used to get propertyXXX and return it as boolean.
+4. If (3) fails to find property, unchecked ConfigurationException will be thrown.
+
+A ConfigurationException will be also thrown if propertyXXX was found in one
+of the configurations, but it is impossible to convert it to boolean value.
+
+## XML configuration support
+
+XML configuration storage is supported. Both org.owasp.esapi.opsteam and
+org.owasp.esapi.devteam can be XML files, but they must comply to the
+following XSD schema:
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### XML configuration example:
+```
+
+
+ test_string_property
+ 5
+ invalid int
+ true
+ yes
+ no
+ invalid boolean
+
+```
diff --git a/documentation/ESAPI-release-steps.odt b/documentation/ESAPI-release-steps.odt
new file mode 100644
index 000000000..455863aba
Binary files /dev/null and b/documentation/ESAPI-release-steps.odt differ
diff --git a/documentation/ESAPI-release-steps.pdf b/documentation/ESAPI-release-steps.pdf
new file mode 100644
index 000000000..96db0481d
Binary files /dev/null and b/documentation/ESAPI-release-steps.pdf differ
diff --git a/documentation/ESAPI-security-bulletin1.docx b/documentation/ESAPI-security-bulletin1.docx
new file mode 100644
index 000000000..55cc3ba39
Binary files /dev/null and b/documentation/ESAPI-security-bulletin1.docx differ
diff --git a/documentation/ESAPI-security-bulletin1.pdf b/documentation/ESAPI-security-bulletin1.pdf
new file mode 100644
index 000000000..ba2f68a83
Binary files /dev/null and b/documentation/ESAPI-security-bulletin1.pdf differ
diff --git a/documentation/ESAPI-security-bulletin10.odt b/documentation/ESAPI-security-bulletin10.odt
new file mode 100644
index 000000000..87db70d4d
Binary files /dev/null and b/documentation/ESAPI-security-bulletin10.odt differ
diff --git a/documentation/ESAPI-security-bulletin10.pdf b/documentation/ESAPI-security-bulletin10.pdf
new file mode 100644
index 000000000..90b84b442
Binary files /dev/null and b/documentation/ESAPI-security-bulletin10.pdf differ
diff --git a/documentation/ESAPI-security-bulletin11.odt b/documentation/ESAPI-security-bulletin11.odt
new file mode 100644
index 000000000..b1386c80d
Binary files /dev/null and b/documentation/ESAPI-security-bulletin11.odt differ
diff --git a/documentation/ESAPI-security-bulletin11.pdf b/documentation/ESAPI-security-bulletin11.pdf
new file mode 100644
index 000000000..b553f69b9
Binary files /dev/null and b/documentation/ESAPI-security-bulletin11.pdf differ
diff --git a/documentation/ESAPI-security-bulletin12.odt b/documentation/ESAPI-security-bulletin12.odt
new file mode 100644
index 000000000..d1abf5d82
Binary files /dev/null and b/documentation/ESAPI-security-bulletin12.odt differ
diff --git a/documentation/ESAPI-security-bulletin12.pdf b/documentation/ESAPI-security-bulletin12.pdf
new file mode 100644
index 000000000..126f06751
Binary files /dev/null and b/documentation/ESAPI-security-bulletin12.pdf differ
diff --git a/documentation/ESAPI-security-bulletin13.odt b/documentation/ESAPI-security-bulletin13.odt
new file mode 100644
index 000000000..ee9cb8ef8
Binary files /dev/null and b/documentation/ESAPI-security-bulletin13.odt differ
diff --git a/documentation/ESAPI-security-bulletin13.pdf b/documentation/ESAPI-security-bulletin13.pdf
new file mode 100644
index 000000000..8d272b042
Binary files /dev/null and b/documentation/ESAPI-security-bulletin13.pdf differ
diff --git a/documentation/ESAPI-security-bulletin2.odt b/documentation/ESAPI-security-bulletin2.odt
new file mode 100644
index 000000000..793f0ffbf
Binary files /dev/null and b/documentation/ESAPI-security-bulletin2.odt differ
diff --git a/documentation/ESAPI-security-bulletin2.pdf b/documentation/ESAPI-security-bulletin2.pdf
new file mode 100644
index 000000000..6925ad568
Binary files /dev/null and b/documentation/ESAPI-security-bulletin2.pdf differ
diff --git a/documentation/ESAPI-security-bulletin3.odt b/documentation/ESAPI-security-bulletin3.odt
new file mode 100644
index 000000000..8026a3936
Binary files /dev/null and b/documentation/ESAPI-security-bulletin3.odt differ
diff --git a/documentation/ESAPI-security-bulletin3.pdf b/documentation/ESAPI-security-bulletin3.pdf
new file mode 100644
index 000000000..98af7cfd3
Binary files /dev/null and b/documentation/ESAPI-security-bulletin3.pdf differ
diff --git a/documentation/ESAPI-security-bulletin4.odt b/documentation/ESAPI-security-bulletin4.odt
new file mode 100644
index 000000000..59c930f27
Binary files /dev/null and b/documentation/ESAPI-security-bulletin4.odt differ
diff --git a/documentation/ESAPI-security-bulletin4.pdf b/documentation/ESAPI-security-bulletin4.pdf
new file mode 100644
index 000000000..7a125584d
Binary files /dev/null and b/documentation/ESAPI-security-bulletin4.pdf differ
diff --git a/documentation/ESAPI-security-bulletin5.odt b/documentation/ESAPI-security-bulletin5.odt
new file mode 100644
index 000000000..9edbd72d1
Binary files /dev/null and b/documentation/ESAPI-security-bulletin5.odt differ
diff --git a/documentation/ESAPI-security-bulletin5.pdf b/documentation/ESAPI-security-bulletin5.pdf
new file mode 100644
index 000000000..b3a215f05
Binary files /dev/null and b/documentation/ESAPI-security-bulletin5.pdf differ
diff --git a/documentation/ESAPI-security-bulletin6.odt b/documentation/ESAPI-security-bulletin6.odt
new file mode 100644
index 000000000..88d0c98a5
Binary files /dev/null and b/documentation/ESAPI-security-bulletin6.odt differ
diff --git a/documentation/ESAPI-security-bulletin6.pdf b/documentation/ESAPI-security-bulletin6.pdf
new file mode 100644
index 000000000..970d79d96
Binary files /dev/null and b/documentation/ESAPI-security-bulletin6.pdf differ
diff --git a/documentation/ESAPI-security-bulletin7.odt b/documentation/ESAPI-security-bulletin7.odt
new file mode 100644
index 000000000..6688b3b87
Binary files /dev/null and b/documentation/ESAPI-security-bulletin7.odt differ
diff --git a/documentation/ESAPI-security-bulletin7.pdf b/documentation/ESAPI-security-bulletin7.pdf
new file mode 100644
index 000000000..38d60ebda
Binary files /dev/null and b/documentation/ESAPI-security-bulletin7.pdf differ
diff --git a/documentation/ESAPI-security-bulletin8.odt b/documentation/ESAPI-security-bulletin8.odt
new file mode 100644
index 000000000..2b73a5e2b
Binary files /dev/null and b/documentation/ESAPI-security-bulletin8.odt differ
diff --git a/documentation/ESAPI-security-bulletin8.pdf b/documentation/ESAPI-security-bulletin8.pdf
new file mode 100644
index 000000000..646050e51
Binary files /dev/null and b/documentation/ESAPI-security-bulletin8.pdf differ
diff --git a/documentation/ESAPI-security-bulletin9.odt b/documentation/ESAPI-security-bulletin9.odt
new file mode 100644
index 000000000..68b1ba79a
Binary files /dev/null and b/documentation/ESAPI-security-bulletin9.odt differ
diff --git a/documentation/ESAPI-security-bulletin9.pdf b/documentation/ESAPI-security-bulletin9.pdf
new file mode 100644
index 000000000..ed46ea87a
Binary files /dev/null and b/documentation/ESAPI-security-bulletin9.pdf differ
diff --git a/documentation/GHSL-2022-008_The_OWASP_Enterprise_Security_API.md b/documentation/GHSL-2022-008_The_OWASP_Enterprise_Security_API.md
new file mode 100644
index 000000000..bc4956ab0
--- /dev/null
+++ b/documentation/GHSL-2022-008_The_OWASP_Enterprise_Security_API.md
@@ -0,0 +1,108 @@
+# GitHub Security Lab (GHSL) Vulnerability Report: `GHSL-2022-008`
+
+The [GitHub Security Lab](https://securitylab.github.com) team has identified a potential security vulnerability in [The OWASP Enterprise Security API](https://github.com/ESAPI/esapi-java-legacy).
+
+We are committed to working with you to help resolve this issue. In this report you will find everything you need to effectively coordinate a resolution of this issue with the GHSL team.
+
+If at any point you have concerns or questions about this process, please do not hesitate to reach out to us at `securitylab@github.com` (please include `GHSL-2022-008` as a reference).
+
+If you are _NOT_ the correct point of contact for this report, please let us know!
+
+## Summary
+
+`getValidDirectoryPath` incorrectly treats sibling of a root directory as a child.
+
+## Product
+
+The OWASP Enterprise Security API
+
+## Tested Version
+
+v2.2.3.1 (The latest version of ["Legacy" 2.x branch](https://github.com/ESAPI/esapi-java-legacy#what-does-legacy-mean) as [ESAPI 3.x](https://github.com/ESAPI/esapi-java) is in early development and has no releases yet.)
+
+## Details
+
+### Issue: `getValidDirectoryPath` bypass (`GHSL-2022-008`)
+
+`parent` [1] - the third parameter in [`getValidDirectoryPath`](https://github.com/ESAPI/esapi-java-legacy/blob/07dd60a8cc9edf0c872d68ae8ae84c70f008d3d8/src/main/java/org/owasp/esapi/reference/DefaultValidator.java#L447-L483) is used to validate that the `input` [2] path is "inside specified parent" directory [3].
+
+```java
+public String getValidDirectoryPath(String context, String input /* [2] */, File parent /* [1] */, boolean allowNull) throws ValidationException, IntrusionException {
+ try {
+ if (isEmpty(input)) {
+ if (allowNull) return null;
+ throw new ValidationException( context + ": Input directory path required", "Input directory path required: context=" + context + ", input=" + input, context );
+ }
+
+ File dir = new File( input );
+
+ // check dir exists and parent exists and dir is inside parent
+ if ( !dir.exists() ) {
+ throw new ValidationException( context + ": Invalid directory name", "Invalid directory, does not exist: context=" + context + ", input=" + input );
+ }
+ if ( !dir.isDirectory() ) {
+ throw new ValidationException( context + ": Invalid directory name", "Invalid directory, not a directory: context=" + context + ", input=" + input );
+ }
+ if ( !parent.exists() ) {
+ throw new ValidationException( context + ": Invalid directory name", "Invalid directory, specified parent does not exist: context=" + context + ", input=" + input + ", parent=" + parent );
+ }
+ if ( !parent.isDirectory() ) {
+ throw new ValidationException( context + ": Invalid directory name", "Invalid directory, specified parent is not a directory: context=" + context + ", input=" + input + ", parent=" + parent );
+ }
+ if ( !dir.getCanonicalPath().startsWith(parent.getCanonicalPath() ) ) { // <---------- [3]
+ throw new ValidationException( context + ": Invalid directory name", "Invalid directory, not inside specified parent: context=" + context + ", input=" + input + ", parent=" + parent );
+ }
+
+ // check canonical form matches input
+ String canonicalPath = dir.getCanonicalPath();
+ String canonical = fileValidator.getValidInput( context, canonicalPath, "DirectoryName", 255, false);
+ if ( !canonical.equals( input ) ) {
+ throw new ValidationException( context + ": Invalid directory name", "Invalid directory name does not match the canonical path: context=" + context + ", input=" + input + ", canonical=" + canonical, context );
+ }
+ return canonical;
+ } catch (Exception e) {
+ throw new ValidationException( context + ": Invalid directory name", "Failure to validate directory path: context=" + context + ", input=" + input, e, context );
+ }
+}
+```
+
+If the result of `parent.getCanonicalPath()` is not slash terminated it allows for partial path traversal.
+
+Consider `"/usr/outnot".startsWith("/usr/out")`. The check is bypassed although `outnot` is not under the `out` directory.
+The terminating slash may be removed in various places. On Linux `println(new File("/var/"))` returns `/var`, but `println(new File("/var", "/"))` - `/var/`, however `println(new File("/var", "/").getCanonicalPath())` - `/var`.
+
+PoC (based on a unittest):
+```java
+Validator instance = ESAPI.validator();
+ValidationErrorList errors = new ValidationErrorList();
+assertTrue(instance.isValidDirectoryPath("poc", "/tmp/test2", new File("/tmp/test/"), false, errors));
+assertEquals(0, errors.size());
+```
+
+#### Impact
+
+This issue allows to break out of expected directory.
+
+#### Remediation
+
+Consider using `getCanonicalFile().toPath().startsWith` to compare `Path`:
+
+```java
+if ( !dir.getCanonicalFile().toPath().startsWith(parent.getCanonicalFile().toPath() ) )
+```
+
+## GitHub Security Advisories
+
+We recommend you create a private [GitHub Security Advisory](https://help.github.com/en/github/managing-security-vulnerabilities/creating-a-security-advisory) for this finding. This also allows you to invite the GHSL team to collaborate and further discuss this finding in private before it is [published](https://help.github.com/en/github/managing-security-vulnerabilities/publishing-a-security-advisory).
+
+## Credit
+
+This issue was discovered and reported by GHSL team member [@JarLob (Jaroslav LobaÄŤevski)](https://github.com/JarLob).
+
+## Contact
+
+You can contact the GHSL team at `securitylab@github.com`, please include a reference to `GHSL-2022-008` in any communication regarding this issue.
+
+## Disclosure Policy
+
+This report is subject to our [coordinated disclosure policy](https://securitylab.github.com/advisories#policy).
diff --git a/documentation/GHSL-2022-008_The_OWASP_Enterprise_Security_API.pdf b/documentation/GHSL-2022-008_The_OWASP_Enterprise_Security_API.pdf
new file mode 100644
index 000000000..c77efef05
Binary files /dev/null and b/documentation/GHSL-2022-008_The_OWASP_Enterprise_Security_API.pdf differ
diff --git a/documentation/Installation.html b/documentation/Installation.html
deleted file mode 100644
index 4012017cf..000000000
--- a/documentation/Installation.html
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-
-ESAPI Installation Notes
-
-
-
-
-
The OWASP Enterprise Security API Project may be found at http://www.owasp.org/index.php/ESAPI. This software
-is available under the LGPL, and we encourage your participation in the project.
-
-
ESAPI consists of two key parts, an API defined in a set of interfaces, and a reference implementation of those
-interfaces. Within your enterprise, you may want to customize the ESAPI to suit the way you do business. The important
-thing is that you work towards creating your ESAPI and getting all of your projects to use it. This will dramatically
-increase the likelihood that your developers are producing secure code.
-
-
Your ESAPI can be viewed as a unified facade to all of your organization's security functionality. Have a clear, easy
-to understand API make it easy to find security mechanisms and use them properly. Many of the existing security libraries,
-while providing excellent security functions, are much too complex for most developers to use without mistakes. Establishing
-your ESAPI will help to prevent this kind of problem.
-
-
Having an ESAPI has other benefits as well, including:
-
-
Simplifed requirements
-
Easier developer security training
-
Faster and more reliable security scanning and penetration testing
-
Better results from static analysis and code review
-
Ability to change security mechanisms across applications
-
Higher assurance in your security mechanisms
-
Solid coverage of most of the OWASP Top Ten
-
-
-
Installation
-
To install the ESAPI in your environment, you should include the following jar files on your classpath:
-
-
owasp-esapi-1.0.jar
-
commons-fileupload-1.2.jar
-
commons-io-1.3.2.jar
-
-
Newer versions of the Apache Commons projects may also work.
-
-
Invoking
-
-
The ESAPI needs to know where to find the ESAPI.properties and other configuration files. This is done by way of a Java system property.
-The property should point to the resources directory where the ESAPI files reside. You can specify the system property where you invoke the JVM as follows:
You can then add calls to the ESAPI methods from your code. For example, to use the ESAPI Validator, you should
-get an instance from the singleton with
-
-
Validator validator = Validator.getInstance()
-
-Then you can use validation calls directly. For example, to validate an email address, you can use:
-
-
-try {
- String validEmail = validation.getValidDataFromBrowser( "Email", input );
-} catch( ValidationException e ) {
- // handle bad data
-}
-
-
-
The regular expressions that define validators such as "Email" above are defined in the ESAPI properties file. Note
-that the Validator class performs a significant amount of canonicalization work before validating and prevents
-many common forms of attack.
-
-
Configuring
-
All of the configuration options for ESAPI are in ESAPI.properties. Generally the values specified there are
-good options for a web application that needs to be secure.
-
-
Building
-
ESAPI is set up as an Eclipse project. If you download the full zip archive, you should be able to import it into
-Eclipse and get it to compile. You should be able to run the test cases, provided that you remember that your launch
-configuration for the test suite will have to have the org.owasp.esapi.resources property defined as described above.
-
-
-
-
-
-
diff --git a/documentation/LoggerDesignAndTesting.md b/documentation/LoggerDesignAndTesting.md
new file mode 100644
index 000000000..d3542a48a
--- /dev/null
+++ b/documentation/LoggerDesignAndTesting.md
@@ -0,0 +1,27 @@
+(Gleaned from an email from Jeremiah J. Stacey to Kevin W. Wall on 2021-03-21. Some minor alterations were made for contextual understanding by Kevin Wall because the original email thread was not included.)
+
+The testing (for SLF4J logging at least) is tested with Mockito and Powermock. For the SLF4J logging, the tests are in Slf4JLoggerTest. It uses mocks to assert that the slf4j logging implementation gets the data we expect in the calls we support.
+
+I was very deliberate in the breakout of the classes to isolate specific functionality to enable this type of testing. At a high level, there are four classes that make up the logging structure.
+I tried to encapsulate a subset of functionality into each one:
+
+**LogFactory** - Constructs Loggers to be used by clients. Responsible for building the LogBridge and the LevelHandler.
+
+**Logger** - The ESAPI interface implementation which uses the LogBridge and a delegate Logger to forward events to the underlying log implementation.
+
+**LogBridge** - Logical handler for determining the delegate handler for a known ESAPI log event, and forwarding the Log event to that handler. Also responsible for prefixing the client/server info content and applying the newline replacement behavior.
+
+**LogLevelHander** - This is actually where the log event gets sent to SLF4J! The Handler enumeration is assembled as part of a map in the static block of the LogFactory, and is used by the LogBridge to route a log event at a defined ESAPI log level to the correct API of the delegate Logger.
+
+
+The general workflow is:
+
+ LogFactory static block creates the LogPrefixAppender, LogScrubber, and LogBridge.
+
+ LogFactory.getLogger(...) Creates Logger with the delegate slf4j logger implementation and the LogBridge.
+
+ Logger.info/warn/etc(message) -> forwards to LogBridgelog(logger, esapiLevel, type, message) -> forwards to LogHandler.log(...) -> forwards to slf4j Logger implementation with appropriate level and composed message.
+
+So each of the tests for each of the classes verifies data in -> data out based on the Logging API. The structure for JUL and SLF4J are almost identical. There are a few differences in the interaction with the underlying Logger interactions and expectations. As a result, the tests are also almost full duplications (again accounting for differences in the underlying logging API).
+
+-J
diff --git a/documentation/OWASP ESAPI Overview.html b/documentation/OWASP ESAPI Overview.html
deleted file mode 100644
index fdc53babf..000000000
--- a/documentation/OWASP ESAPI Overview.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
The OWASP Enterprise Security API (ESAPI) is both a set of
-interfaces and a reference implementation of a library that provides
-enterprise web application developers the most important security
-functions they need in order to build web applications and web services
-that protect themselves against attacks.
-
-
The The Open Web Application
-Security Project (OWASP) is a worldwide free and open community focused
-on improving the security of application software. Our mission is to
-make application security "visible," so that people and organizations
-can make informed decisions about application security risks. Everyone
-is free to participate in OWASP and all of our materials are available
-under an open source license. The OWASP Foundation is a 501c3
-not-for-profit charitable organization that ensures the ongoing
-availability and support for our work.
-
-
The OWASP ESAPI Project is led by Jeff Williams, Aspect Security
-
-
You can find more information about the ESAPI project, or join
-the mailing list and help us make it better from the OWASP project page
-at http://www.owasp.org/index.php/ESAPI.
-
-
-
-
The library builds on the excellent security libraries available,
-such as Java Logging, JCE, and Adobe Commons FileUpload. It uses the
-concepts from many of the security packages out there, such as ACEGI,
-Apache Commons Validator, Microsoft's AntiXSS library, and many many
-more. This library provides a single consistent interface to security
-functions that is intuitive for enterprise developers.
-
-
-
-
Used properly, the ESAPI provides enough functions to protect
-against most of the OWASP Top Ten. The only real exception is the
-Insecure Communications category, which is generally outside the control
-of the software developer.
-
-
This project and all associated code is Copyright (c) 2007 - The OWASP Foundation
-
-
The ESAPI is published by OWASP under the BSD license. You should read and accept the LICENSE
-before you use, modify, and/or redistribute this software.
-
-
-
-
-
-
diff --git a/documentation/OWASP ESAPI Overview.pptx b/documentation/OWASP ESAPI Overview.pptx
deleted file mode 100644
index 70765374c..000000000
Binary files a/documentation/OWASP ESAPI Overview.pptx and /dev/null differ
diff --git a/documentation/OWASP ESAPI Requirements.docx b/documentation/OWASP ESAPI Requirements.docx
deleted file mode 100644
index f86bd7b54..000000000
Binary files a/documentation/OWASP ESAPI Requirements.docx and /dev/null differ
diff --git a/documentation/cc.JPG b/documentation/cc.JPG
new file mode 100644
index 000000000..8ca55b722
Binary files /dev/null and b/documentation/cc.JPG differ
diff --git a/documentation/esapi4java-2.0-javadoc-pictures.pptx b/documentation/esapi4java-2.0-javadoc-pictures.pptx
new file mode 100644
index 000000000..388fbd906
Binary files /dev/null and b/documentation/esapi4java-2.0-javadoc-pictures.pptx differ
diff --git a/documentation/esapi4java-2.0-readme.txt b/documentation/esapi4java-2.0-readme.txt
new file mode 100644
index 000000000..7fd25e068
--- /dev/null
+++ b/documentation/esapi4java-2.0-readme.txt
@@ -0,0 +1,61 @@
+
+ Welcome to ESAPI for Java!
+
+(This file best viewed full screen.)
+
+Here are the most significant directories and files included the zip file for this release:
+
+File / Directory Description
+=========================================================================================
+/
+|
++---configuration/ Directory of ESAPI configuration files
+| |
+| |---esapi/
+| | |---waf-policies/ Directory containing Web Application Firewall policies
+| | |---ESAPI.properties The main ESAPI configuration file
+| | `---validation.properties Regular expressions used by the ESAPI validator
+| |
+| `---properties/ Examples of how to internationalize error messages???
+| |---ESAPI_en_US.properties in US/English
+| |---ESAPI_fr_FR.properties in French
+| `---ESAPI_zhs_CN.properties in Chinese
+|
+|---documentation/ ESAPI documentation
+| |
+| |---esapi4java-2.0-readme.txt The file you are now reading
+| |---esapi4java-core-2.0-release-notes.pdf ESAPI 2.0 release notes (draft)
+| |---esapi4java-core-2.0-install-guide.doc ESAPI 2.0 installation guide (draft)
+| |---esapi4java-2.0rc6-override-log4jloggingfactory.txt How to use log4j to override User logging
+| |---esapi4java-core-2.0-ciphertext-serialization.pdf Describes serialization layout of ESAPI 2.0 ciphertext representation
+| |---esapi4java-core-2.0-crypto-design-goals.doc (draft) Describes ESAPI 2.0 crypto design goals & design decisions
+| |---esapi4java-core-2.0-readme-crypto-changes.html Describes why crypto was changed from what was in ESAPI 1.4
+| |---esapi4java-core-2.0-symmetric-crypto-user-guide.html User guide for using symmetric encryption in ESAPI 2.0
+| |---esapi4java-core-2.1-release-notes.txt ESAPI 2.1 release notes
+| |---esapi4java-core-2.2.0.0-release-notes.txt ESAPI 2.2.0.0 release notes
+| `---esapi4java-waf-2.0-policy-file-spec.pdf Describes how to configure ESAPI 2.0's Web Application Firewall
+|
+|---libs/ ESAPI dependencies
+|
+|---site/
+| |---apidocs ESAPI Javadoc
+| |---cobertura
+| `---testapidocs ESAPI Javadoc for its JUnit test cases
+|
+|---src/ ESAPI source code
+|
+|---esapi-.jar The ESAPI jar for version (e.g., == 2.0_rc10)
+|
+|---LICENSE.txt ESAPI license for source code and documentation
+|
+`---pom.xml Maven's pom.xml for building ESAPI from source via mvn.
+
+===========================================================
+
+Where to go from here -- please see the installation guide and the release
+notes.
+
+Please address comments and questions concerning the API and this document to
+the ESAPI Users mailing list, .
+
+Copyright (C) 2009-2019 The OWASP Foundation.
diff --git a/documentation/esapi4java-2.0rc6-override-log4jloggingfactory.txt b/documentation/esapi4java-2.0rc6-override-log4jloggingfactory.txt
new file mode 100644
index 000000000..35290f5e6
--- /dev/null
+++ b/documentation/esapi4java-2.0rc6-override-log4jloggingfactory.txt
@@ -0,0 +1,71 @@
+This release includes critical changes to the ESAPI Log4JLogger that will now allow you to over-ride the user specific
+message using your own User or java.security.Principal implementation.
+
+There are a three critical steps that need to be taken to over-ride the ESAPI Log4JLogger:
+
+1) Please make a copy of http://owasp-esapi-java.googlecode.com/svn/trunk/src/main/java/org/owasp/esapi/reference/ExampleExtendedLog4JLogFactory.java and change the package and the class name (something like com.yourcompany.logging.ExtendedLog4JFactory). This class (not very big at all) gives you the exact “shell” that you will need to over-ride the user message of the ESAPI Log4JLogger.
+
+2) In your new class, please change the following function to use your user object:
+
+ public String getUserInfo() {
+ return "-EXTENDEDUSERINFO-";
+ }
+
+3) Change your copy of ESAPI.properties to use your new logging class
+
+The ESAPI.properties entry looks like this now:
+
+ESAPI.Logger=org.owasp.esapi.reference.Log4JLogFactory
+
+Please change it to the following, based on how you renamed your new logging class
+
+ESAPI.Logger=com.yourcompany.logging.ExtendedLog4JFactory
+
+And you should be all set!
+
+PS: The original ESAPI Log4JLogging class used a secure random number as a replacement to logging the session ID. This allowed
+us to tie log messages from the same session together, without exposing the actual session id in the log file. The code looks
+like this, and you may wish to use it in your over-ridden version of getUserInfo.
+
+HttpServletRequest request = ESAPI.httpUtilities().getCurrentRequest();
+if ( request != null ) {
+ HttpSession session = request.getSession( false );
+ if ( session != null ) {
+ sid = (String)session.getAttribute("ESAPI_SESSION");
+ // if there is no session ID for the user yet, we create one and store it in the user's session
+ if ( sid == null ) {
+ sid = ""+ ESAPI.randomizer().getRandomInteger(0, 1000000);
+ session.setAttribute("ESAPI_SESSION", sid);
+ }
+ }
+}
+
+In fact, here is the entire original getUserInfo() implementation (that was tied to the ESAPI request and user object) –
+you may wish to emulate some of this.
+
+public String getUserInfo() {
+ // create a random session number for the user to represent the user's 'session', if it doesn't exist already
+ String sid = null;
+ HttpServletRequest request = ESAPI.httpUtilities().getCurrentRequest();
+ if ( request != null ) {
+ HttpSession session = request.getSession( false );
+ if ( session != null ) {
+ sid = (String)session.getAttribute("ESAPI_SESSION");
+ // if there is no session ID for the user yet, we create one and store it in the user's session
+ if ( sid == null ) {
+ sid = ""+ ESAPI.randomizer().getRandomInteger(0, 1000000);
+ session.setAttribute("ESAPI_SESSION", sid);
+ }
+ }
+ }
+
+ // log user information - username:session@ipaddr
+ User user = ESAPI.authenticator().getCurrentUser();
+ String userInfo = "";
+ //TODO - make type logging configurable
+ if ( user != null) {
+ userInfo += user.getAccountName()+ ":" + sid + "@"+ user.getLastHostAddress();
+ }
+
+ return userInfo;
+}
diff --git a/documentation/esapi4java-big-duke.JPG b/documentation/esapi4java-big-duke.JPG
new file mode 100644
index 000000000..6f7007759
Binary files /dev/null and b/documentation/esapi4java-big-duke.JPG differ
diff --git a/documentation/esapi4java-core-2.0-ciphertext-serialization.pdf b/documentation/esapi4java-core-2.0-ciphertext-serialization.pdf
new file mode 100644
index 000000000..37d68a467
Binary files /dev/null and b/documentation/esapi4java-core-2.0-ciphertext-serialization.pdf differ
diff --git a/documentation/esapi4java-core-2.0-ciphertext-serialization.xls b/documentation/esapi4java-core-2.0-ciphertext-serialization.xls
new file mode 100644
index 000000000..86b7de7a0
Binary files /dev/null and b/documentation/esapi4java-core-2.0-ciphertext-serialization.xls differ
diff --git a/documentation/esapi4java-core-2.0-crypto-design-goals.doc b/documentation/esapi4java-core-2.0-crypto-design-goals.doc
new file mode 100644
index 000000000..836e8c776
Binary files /dev/null and b/documentation/esapi4java-core-2.0-crypto-design-goals.doc differ
diff --git a/documentation/esapi4java-core-2.0-install-guide.doc b/documentation/esapi4java-core-2.0-install-guide.doc
new file mode 100644
index 000000000..d185ecbdd
Binary files /dev/null and b/documentation/esapi4java-core-2.0-install-guide.doc differ
diff --git a/documentation/esapi4java-core-2.0-install-guide.pdf b/documentation/esapi4java-core-2.0-install-guide.pdf
new file mode 100644
index 000000000..012c49753
Binary files /dev/null and b/documentation/esapi4java-core-2.0-install-guide.pdf differ
diff --git a/documentation/esapi4java-core-2.0-readme-crypto-changes.html b/documentation/esapi4java-core-2.0-readme-crypto-changes.html
new file mode 100644
index 000000000..db403b9c9
--- /dev/null
+++ b/documentation/esapi4java-core-2.0-readme-crypto-changes.html
@@ -0,0 +1,440 @@
+
+
+
+
+ Why Is OWASP Changing ESAPI Encryption?
+
+
+
+
+
+
+
Why Is OWASP Changing ESAPI Encryption?
+
Reasons for Change
+
Symmetric Encryption in ESAPI 1.4
+
The as-delivered, default ESAPI 1.4
+encryption mechanism uses "PBEWithMD5AndDES", a "Password
+Based Encryption" algorithm. As implemented in ESAPI 1.4,
+password (or pass phrase), taken from the property MasterPassword, is
+concatenated with the salt as specified by the property MasterSalt,
+and then repeated hashed 20 times using the MD5 message digest
+algorithm. The intent of the salt and repetitive hashing is to slow
+down dictionary attacks on the password. The result after the 20
+iterations of hashing is used as the DES encryption key. The
+encryption uses Cipher Block Chaining (CBC) cipher mode.
+
Problems with Symmetric Encryption in ESAPI 1.4
+
The problems with symmetric encryption in ESAPI 1.4 are many. Here
+are some of the main issues:
+
+
The implementation only supported a single encryption key.
+ While this may be sufficient for some uses, clearly there are cases
+ where multiple recipients are involved when you would like to use
+ unique encryption keys for each recipient.
+
ESAPI 1.4 came with a default setting for MasterPassword and
+ MasterSalt, thus not requiring that it be changed. How many of you
+ forgot to change these?
+
Password based encryption is likely to be much weaker
+ randomly choosing a secret key. For instance, if you restrict
+ yourself to printable ASCII characters (which most people will), it
+ would require a pass phrase of roughly 45 characters to be the
+ equivalent of a randomly chosen 128-bit secret key.
+
The default algorithm, DES, only has an effective key length
+ of 56-bits. This key size is too short and is in the realm of brute
+ forcing within a short amount of time for most medium to large
+ companies. (Fortunately, this could be addressed in part by changing
+ the EncryptionAlgorithm property from "PBEWithMD5AndDES"
+ to either "PBEWithHmacSHA1AndDESede" [if you are using JDK
+ 1.5 or later] or to "PBEWithMD5AndTripleDES" [if you are
+ still using JDK 1.4]. Unfortunately, because of the implementation
+ of JavaEncryptor, only "password based encryption"
+ algorithms can be used in ESAPI 1.4.)
+
The symmetric encryption does not provide for any means of
+ confirming message authenticity. Cryptographers consider ensuring
+ message authenticity an important feature of modern cryptosystems.
+
+
Symmetric Encryption in ESAPI 2.0rc1 and 2.0rc2
+
By default, release candidates ESAPI
+2.0-rc1 and 2.0-rc2 used the 256-bit AES cipher with the cipher mode
+Electronic Code Book (ECB) for encryption with Encryptor
+via the ESAPI reference implementation, JavaEncryptor.
+ECB cipher mode is the simplest cipher mode to use, but it is also
+cryptographically very weak. If more than one block of plaintext is
+encrypted with the same key, those identical blocks of ciphertext
+always encrypt to the same ciphertext block, thus revealing patterns
+in the plaintext input. For example, these images from Wikipedia's
+Block
+cipher modes of operation illustrate this point well:
+
In both ESAPI 2.0-rc1 and 2.0-rc2, one can choose other block
+ciphers (e.g. Blowfish) or other key sizes (e.g., 512-bit AES), but
+encryption in ESAPI 2.0-rc1 and 2.0-rc2 only support ECB
+cipher mode with no padding; it cannot be used to decrypt data
+encrypted with anything other than an algorithm using ECB cipher mode
+and no padding. Most encryption (outside of ESAPI) uses some other
+cipher mode (e.g., Cipher Block Chaining (CBC) mode) and some sort of
+padding scheme, such as PKCS#5 padding, meaning that they are many
+situations where ESAPI encryption would not be suitable.
+
Problems with Symmetric Encryption in ESAPI 2.0-rc1 and 2.0-rc2
+
The problems with symmetric encryption in ESAPI 2.0-rc1 and 2.0rc2
+are many. Here are some of the main issues:
+
+
The implementation only supported a single encryption
+ key. While this may be sufficient for some uses, clearly there are
+ cases where multiple recipients are involved when you would like to
+ use unique encryption keys for each recipient.
+
ESAPI 2.0-rc1 and 2.0-rc2 came with a default settings for
+ Encryptor.MasterKey and Encryptor.MasterSalt, thus not requiring
+ that these be changed. How many of you forgot to change these?
+
Because the reference implementation in JavaEncryptor
+ allows no means to specify an Initialization Vector (IV), only the
+ weak ECB cipher mode can be used.
+
The symmetric encryption does not provide for any means of
+ confirming message authenticity. Cryptographers consider ensuring
+ message authenticity an important feature of modern cryptosystems.
+
+
The Encryption Changes in ESAPI 2.0-rc3 and Later
+
Briefly speaking, the changes being implemented for ESAPI Java 2.0
+are:
+
+
+
Starting in ESAPI Java 2.0-rc3,
+ the default cipher transformation is changing to
+ "AES-128/CBC/PKCS5Padding" (i.e., 128-bit AES in CBC
+ cipher mode and PKCS#5 padding) with a random IV. The main reason
+ that 128-bit AES was chosen over 256-bit AES for the default is that
+ 128-bit AES is slightly faster than 256-bit AES, and it does not
+ require you downloading the Unlimited Strength Jurisdiction Policy
+ files from Sun Microsystems. For those believing that 128-bit AES is
+ not sufficiently strong--bruting forcing it (except perhaps with a
+ reasonable quantum computer) is still not feasible--and certain key
+ related attacks (see Biryukov, Dunkelman, Keller, Khovratovich, and
+ Shamir's Cryptology ePrint
+ Archive: Report 2009/374 -- Key Recovery Attacks of Practical
+ Complexity on AES Variants With Up To 10 Rounds for further
+ details) show that longer key sizes in AES may not always be the
+ best.
+
Because cipher modes other than
+ ECB require an Initialization Vector (IV), a mechanism to handle
+ both fixed and random IVs has been added. The use of the “fixed”
+ IV should only be considered if there is a need to be compatible
+ with some legacy software or third party software package. Those
+ cases should be rare.
+
The original attempt to preserve
+ backward compatibility with ESAPI Java 1.4 (via
+ org.owasp.esapi.reference.crypto.LegacyJavaEncryptor)
+ has been removed. This was put to a vote on Jan 31, 2010 before both
+ the ESAPI Users and ESAPI Developers mailing lists and the lack of
+ response was deafening. There literally was but a single response
+ and that was to kill off LegacyJavaEncryptor.
+ (By this time, the two symmetric encryption interfaces in Encryptor
+ had already been deprecated.)
+
+
The byte-encoding has been changed from native byte encoding
+ to UTF-8 byte-encoding throughout ESAPI 2.0 and not just for
+ encryption. This was needed so that one could (say) encrypt on a
+ Sparc running Solaris and then move the encrypted data to an Intel
+ host running Windows and still be able to decrypt the data. Without
+ this change to use uniform encoding throughout, this could not be
+ guaranteed.
+
+
The Good, the Bad, and the Ugly
+
Or put another way, there are always trade-offs to be made...
+
+
The Good
+
We get improved security by encouraging the use of stronger cipher
+modes (and ESAPI is all about "enterprise security",
+right?). Furthermore, it is possible to choose a preferred JCE
+provider for ESAPI and ESAPI will attempt to use that provider. For
+example, if you wish to use Bouncy Castle rather than the SunJCE, you
+can do so. One place where this might be a significant advantage is
+if you need to use a FIPS 140-2 compliant JCE implementation. Whereas
+in production environments, you ultimately will want to ensure this
+by editing your $JAVA_HOME/jre/lib/security/java.security
+file, this is often inconvenient for developers who simply wish to
+test because this file often requires super-user access to alter. In
+such cases, setting the new ESAPI property
+Encryptor.PreferredJCEProvider
+to the fully qualified class name of your FIPS 140-2 JCE provider in
+your ESAPI.properties
+file and you can test without any other changes to your code or you
+environment.
+
We also get message authenticity as long as we don't use any of
+the deprecated encryption methods or intentionally disable it. (The
+only sane reason for intentionally disabling the MAC
+calculation is for FIPS 140-2 compliance. This MAC calculation
+requires deriving two new SecretKeys
+from the original key—one to use for message authenticity and a
+second one to use for message confidentiality. While we believe that
+this mechanism is secure [it was originally suggested by professional
+cryptographers], this key derivation would not be using FIPS 140-2
+approved code. Therefore if you require FIPS 140-2 compliance, you
+should set “Encryptor.CipherText.useMAC=false”
+in your ESAPI.properties
+file.)
+
The Bad
+
With cipher modes that require an IV, the same IV must be used
+both to encrypt and decrypt. While it is not required that the IV be
+kept secret from adversaries, there are some attacks that are
+possible if the adversary is permitted to alter the IV at will and
+observe the results of the ensuing decryption attempt.
+
+
So that leaves two choices for the IV:
+
+
+
Using a fixed IV:
+ The IV can be agreed upon out-of-band by the parties exchanging
+ encrypted messages. In this way, the encrypted data that is stored
+ and/or transmitted can be limited to only the raw ciphertext.
+ (WARNING:
+ This case should be reserved for situations requiring compatibility
+ with legacy or third party software packages.)
+
Using a random IV: Most cryptographers prefer
+ to use a random IV, typically a different one with each message to
+ be encrypted. However, doing so on encrypted data that will be
+ persisted (e.g., to a database) or transmitted to the recipient this
+ random IV must be stored / made known. Therefore, the raw ciphertext
+ can no longer suffice; whatever random IV that was chosen must be
+ communicated.
+
+
+
Likewise, the use of padding is going to add some overhead to the
+length of the ciphertext.
+
For example, a short plaintext of 0-15
+bytes, this overhead can be around 200% of the total plaintext size.
+This overhead diminishes (as a percent of the total plaintext size)
+as the plaintext size increases. Here is a table that illustrates
+this:
Base64-encoded length of ciphertext (with IV
+ and padding) encrypted with 128-bit AES in CBC mode, but no MAC1
+
+
+
Length of raw portable serialized CipherText
+ byte array, containing IV, padding, and MAC, and encrypted with
+ 128-bit AES in CBC mode
+
+
+
Length of raw portable serialized CipherText,
+ containing IV, padding, and MAC, and encrypted with 128-bit AES in
+ CBC mode as a Base64-encoded string
+
+
+
+
+
0-15
+
+
+
44
+
+
+
102
+
+
+
137
+
+
+
+
+
16-31
+
+
+
64
+
+
+
118
+
+
+
162
+
+
+
+
+
32-47
+
+
+
88
+
+
+
134
+
+
+
182
+
+
+
+
+
48-63
+
+
+
108
+
+
+
150
+
+
+
202
+
+
+
+
+
64-79
+
+
+
128
+
+
+
166
+
+
+
222
+
+
+
+
+
… etc. Each additional 16 bytes of plaintext...
+
+
+
...adds ~20 additional bytes
+
+
+
...adds 16 additional bytes
+
+
+
...adds 20 additional bytes
+
+
+
+
__________________________________
+
1. That is, the String
+that is returned by the deprecated Encryptor.decrypt(String)
+method.
+
As you can see, since the size of the IV and the amount of padding
+bytes are fixed at a maximum, this overhead goes down as the length
+of the plaintext message increases. The IV is always a fixed length
+for a given cipher; it is always the same as the cipher block size.
+The padding can vary, but for PKCS5 padding, the padding will be
+between 1 to the cipher block size (in bits) / 8 bytes. For AES, the
+cipher block size is 128-bits, but more typically, a cipher's block
+size is 64-bits so the padding would be between 1 to 16 bytes for AES
+and 1 to 8 bytes for a 64-bit block size cipher and the IV would be
+IV would be 16 bytes for AES and 8 bytes for most other ciphers.
+
+
The Ugly
+
Well, so far, this "bad" news may be bad for you but
+good for your database and/or storage vendor, but you probably can
+live with it, especially if you are willing to do a little bit of
+recoding of your database table sizes.
+
But wait Skippy, don't go running off just quite yet. As Robert
+Heinlein wrote in his 1966 novel The Moon is a Harsh Mistress
+"There ain't no such thing as a free lunch". (Some of us
+more hardened cynics know it more commonly as TANSTAAFL.)
+
+
As mentioned earlier, backward compatibility with ESAPI 1.4
+(originally planned via LegacyJavaEncryptor) has been
+removed because of apparent lack of interest. What this means is if
+you are one of the unlucky stuckeys who are using ESAPI 1.4 symmetric
+encryption to encrypt data and you have persisted this data (and this
+would include the use of the
+org.owasp.esapi.EncryptedProperties
+class in ESAPI 1.4), you will
+first have to decrypt this
+encrypted data using ESAPI 1.4 before using encryption with ESAPI
+2.0. As they say, “we are sorry for the inconvenience”, but there
+was an opportunity to make your voice heard so we refuse to take all
+the blame.
+
In addition, all this backward compatibility and flexibility comes
+at the extra cost of complexity, and not merely additional
+complexity in the reference implementation. There is also some
+additional complexity in the ESAPI Encryptor interfaces
+as well.
+
In particular, there new classes for plaintext (PlainText)
+and ciphertext (CipherText) class to coalesce all this
+complexity of handling the ciphertext result from encryption
+operations. And then there are new encryption and decryption methods
+for the Encryptor interface. Specifically, the encrypt
+and decrypt methods have been generalized as:
+
+(There are also two corresponding encrypt / decrypt methods that omit
+the initial SecretKey
+argument and instead use the SecretKey
+based on Encryptor.MasterKey.)
+
The two existing interfaces from ESAPI 1.4 and earlier:
+are still supported but have been deprecated, mainly because
+they do not support integrity / authenticity checks which most
+cryptographers consider essential. Also these older String-based
+encrypt() / decrypt() interfaces have slightly different semantics
+than do their ESAPI 1.4 counterparts in that these methods default to
+CBC cipher mode, PKCS5Padding, and a random IV. This means that at a
+minimum, the IV must be included as the resulting base64-encoded
+“ciphertext”.
+
However, this difference in cipher mode means that if you have
+data that was previously encrypted using ESAPI 1.4 or earlier, you
+will not be able to decrypt it using the ESAPI 2.0
+method. If you require such compatibility, you may contact the
+author, Kevin W. Wall,
+for assistance.
+
+
Note that while the new String-based encrypt() / decrypt() methods
+use the stronger CBC cipher mode with a random IV, they still do not
+ensure authenticity and integrity so the more general encrypt() /
+decrypt() methods should be preferred over the String-based ones.
+(See below for examples of how to use these new methods.)
+
Further Details
+
Further details are provided in the Encryptor Javadoc
+and the “Symmetric Encryption” section of the ESAPI User Guide.
+
+
diff --git a/documentation/esapi4java-core-2.0-release-notes.doc b/documentation/esapi4java-core-2.0-release-notes.doc
new file mode 100644
index 000000000..9853e0d2a
Binary files /dev/null and b/documentation/esapi4java-core-2.0-release-notes.doc differ
diff --git a/documentation/esapi4java-core-2.0-release-notes.pdf b/documentation/esapi4java-core-2.0-release-notes.pdf
new file mode 100644
index 000000000..351f055cc
Binary files /dev/null and b/documentation/esapi4java-core-2.0-release-notes.pdf differ
diff --git a/documentation/esapi4java-core-2.0-symmetric-crypto-user-guide.html b/documentation/esapi4java-core-2.0-symmetric-crypto-user-guide.html
new file mode 100644
index 000000000..19298d4c2
--- /dev/null
+++ b/documentation/esapi4java-core-2.0-symmetric-crypto-user-guide.html
@@ -0,0 +1,810 @@
+
+
+
+
+ ESAPI 2.x Symmetric Encryption User Guide
+
+
+
+
+
+
+
+
+
+
+ Crypto song: Take a listen and enjoy! Harry Belafonte never sounded this good. ;-)
+
+
+
+
ESAPI 2.0 Symmetric Encryption User Guide
+
ESAPI.properties Properties Relevant to Symmetric Encryption
+
Those properties that are new since ESAPI 2.0-rc2 are shown in
+red. Values shown in blue
+are ones that you would replace.
+
+
+
+
+
+
+
Property Name
+
+
+
Default Value
+
+
+
Comment
+
+
+
+
+
ESAPI.Encryptor
+
+
+
org.owasp.esapi.reference.crypto.JavaEncryptor
+
+
+
The class implementing the Encryptor interface and
+ returned by ESAPI.encryptor().
+
+
+
+
+
Encryptor.MasterKey
+
+
+
<initially unset>
+
+
+
The base64-encoded SecretKey. The key must be
+ appropriate to the specified key size and cipher algorithm.
+
Set as per the instructions in the ESAPI
+ Installation Guide.
+
+
+
+
+
Encryptor.MasterSalt
+
+
+
<initially unset>
+
+
+
A base64-encoded random “salt”. This should be
+ at least 20-bytes. It is used to generate a random (but
+ consistent) public/private key pair used in asymmetric encryption
+ and digital signatures.
+
Set as per the instructions in the ESAPI
+ Installation Guide.
+
+
+
+
+
Encryptor.EncryptionAlgorithm
+
+
+
AES
+
+
+
A deprecated property, superseded by
+ Encryptor.CipherTransformation.
+
+
+
+
+
Encryptor.CipherTransformation
+
+
+
AES/CBC/PKCS5Padding
+
+
+
Specifies the cipher transformation to use for
+ symmetric encryption. The format is
+ cipherAlgorithm/cipherMode/paddingScheme.
+
+
+
+
+
Encryptor.EncryptionKeyLength
+
+
+
128
+
+
+
Default key size, in bits. Required for cipher algorithms
+ that support multiple key sizes.
+
+
+
+
+
Encryptor.MinEncryptionKeyLength
+
+
+
128
+
+
+
Minimum key size, in bits, that ESAPI will support
+ for encryption. (Note that any legitimate size is
+ accepted for decryption.) So, for example, if you needed
+ to be able to do encryption for 2-key Triple DES (aka, 2TDEA),
+ then you would have to change this to '112'. Note that for a
+ minimum key size of larger than 128-bits, you will need
+ to have the JCE Unlimited Strength Jurisdiction Policy files
+ installed on your runtime system.
+
+
+
+
+
+
Encryptor.ChooseIVMethod
+
+
+
random
+
+
+
Legal values are “random” or “fixed”.
+ Random is recommended. Set to “fixed” only if required for
+ compatibility with legacy or third party software. If set to
+ “fixed”, then the property Encryptor.fixedIV must also be
+ set to hex-encoded specific IV that you need to use.
+ NOTE: "fixed" had been deprecated since 2.2.0.0 and finally
+ was removed for release 2.3.0.0. Using it in versions 2.3.0.0 or
+ later will result in a ConfigurationException being thrown.
+
+ CAUTION: While it is not required that the IV be kept
+ secret, encryption relying on fixed IVs can lead to a known
+ plaintext attack called a "Key Collision Attack". While this
+ attack is probably not practical (for those with modest
+ resources) for ciphers with 128-bit key size, this attack
+ makes it possible to capture the ciphertexts from only
+ 2(N/2) known plaintexts to discover the
+ encryption key. Loughran and Dowling explain a Java
+ implementation of Eli Biham's key collision attack on DES in
+ their easy to understand paper,
+
+ A Java Implemented Key Collision Attack on the
+ Data Encryption Standard (DES). Since attacks only get
+ better and the cost of storage is dropping rapidly, you are
+ urged to avoid using "fixed" IVs except when required for
+ backward compatibility. In particular, should never use
+ fixed IVs just to avoid the storage cost of storing a random
+ IV.
+
+
+
+
+
+
Encryptor.fixedIV
+
+
+
0x000102030405060708090a0b0c0d0e0f
+
+
+
A hex-encoded value to use as a fixed IV. Only
+ used if the property Encryptor.fixedIV is set to “fixed”. Intended
+ only for compatibility with legacy code. See the above
+ related above caution for Encryptor.ChooseIVMethod.
+
+
+
+
+
+
Encryptor.CipherText.useMAC
+
+
+
true
+
+
+
Whether or not CipherText
+ should use a message authentication code (MAC) with
+ it. This prevents an adversary from altering the IV
+ as well as allowing a more fool-proof way of
+ determining the decryption failed because of an incorrect key
+ being supplied. This refers to the "separate" MAC
+ calculated and stored in CipherText, not
+ part of any MAC that is calculated as a result
+ of a "combined mode" cipher mode.
+
Note: If the cipher mode used is one specified in
+ the comma-separated list of cipher modes given in the property
+ Encryptor.cipher_modes.combined_modes, then a separate MAC
+ is not calculated for CipherText regardless of
+ the setting of this property. (Doing so would be
+ superfluous.)
+
+
+
+
+
Encryptor.PreferredJCEProvider
+
+
+
<empty string>
+
+
+
Specifies the preferred JCE provider, that
+ is the JCE provider that is first looked at for JCE algorithms.
+ The Encryptor reference implementation,
+ JavaEncryptor, attempts to
+ load this JCE provider at position the first position when the
+ JavaEncryptor class is first loaded.
+
+ The value may either be a provider name (e.g., “BC” for
+ Bouncy Castle) or the fully qualified class name implementing
+ java.security.Provider for
+ the desired JCE provider. If left set to the empty string (the
+ default) or unset, the effect is to not change the preferred JCE
+ provider so that your application ends up using whatever your Java
+ VM is already using, which is generally determined by the settings
+ in your $JAVA_HOME/jre/lib/security/java.security
+ file.
+
+
+
+
+
Encryptor.cipher_modes.additional_allowed
+
+
+
CBC
+
+
+
Additional cipher modes allowed for ESAPI 2.0
+ symmetric encryption. These cipher modes are in addition to
+ those specified by the property
+ Encryptor.cipher_modes.combined_modes.
+
Note: We will add support for streaming modes like
+ CFB & OFB once we add support for 'specified' to the property
+ Encryptor.ChooseIVMethod (probably in ESAPI 2.1).
+
+
+
+
+
Encryptor.cipher_modes.combined_modes
+
+
+
GCM,CCM,IAPM,EAX,OCB,CWC
+
+
+
Comma-separated list of cipher modes that provide
+ both confidentiality and
+ message authenticity. (NIST refers to such cipher
+ modes as "combined modes" so that's what we
+ shall call them.) If any of these cipher modes are used then no
+ MAC is calculated and stored in the CipherText
+ upon encryption. Likewise, if one of these cipher
+ modes is used with decryption, no attempt will be
+ made to validate the MAC contained in the CipherText
+ object regardless of whether it contains one or not.
+ Since the expectation is that these cipher modes support support
+ message authenticity already, injecting a MAC in the
+ CipherText object would be at best redundant.
+
+
Note that as of JDK 1.5, the SunJCE provider does
+ not support any of these cipher modes. Of these listed,
+ only GCM and CCM are currently NIST approved.
+
+
+
+
+
Encryptor.PlainText.overwrite
+
+
+
TRUE
+
+
+
Whether or not the plaintext bytes for the
+ PlainText object may be overwritten with “*” characters and
+ then marked eligible for garbage collection. If not set, this is
+ still treated as 'true'. If this is set to 'true', you will not be
+ able to use any PlainText object after you have used it with one
+ of the Encryptor encrypt() methods.
+
+
+
+
+
Encryptor.KDF.PDF
+
+
+
HmacSHA256
+
+
+
+ This is the Pseudo Random Function (PRF) that ESAPI's Key
+ Derivation Function (KDF) normally uses. NSA wanted us to
+ support something stronger than HmacSHA1 (even though that
+ is considered fine for now--unless perhaps you are guarding
+ nuclear launch codes--and if so, your Java license probably
+ prohibits that ;-).
+
+ (Note this is *only* the PRF used for ESAPI's KDF and *not*
+ what is used for ESAPI's MAC. Currently, HMacSHA1 is always
+ used for the MAC.)
+
+ Currently supported choices for JDK 1.5 and 1.6 are:
+ HMacSHA1 (160 bits), HMacSHA256 (256 bits), HMacSHA384
+ (384 bits), and HMacSHA512 (512 bits).
+
+ Note that HMacMD5 is *not* supported for the PRF
+ used by the KDF even though these JDKs support it.
+ ESAPI 2.0 release candidates prior to 2.0_rc11
+ ALWAYS used HMacSHA1. It is somewhat faster than
+ the SHA2 HMAC variations, but not significantly so.
+
+ The only legitimate reason to tweak this would be to change it to
+ one of the new HMACs based on the future SHA-3 winner once it is
+ announced by NIST and supported in ESAPI and most JDKs. Until then,
+ don't meddle.
+
+
+
+
+
+
Encryptor.CharacterEncoding
+
+
+
UTF-8
+
+
+
The default encoding used for certain aspects such
+ as signing and sealing.
+
+
+
+
How the Old (Deprecated) Methods Were Used
+
To encrypt / decrypt using the String-based, deprecated methods
+carried over from ESAPI 1.4, code similar to the following would be
+used.
+
+This code will still work, however if you are using the standard
+(default) reference for ESAPI.Encryptor, which is
+org.owasp.esapi.reference.crypto.JavaEncryptor, the
+cipher transformation used with be that specified by the property
+Encryptor.CipherTransformation with a key size (when the
+algorithm supports a variable key size) of that specified by
+Encryptor.EncryptionKeyLength and the IV type specified
+by Encryptor.ChooseIVMethod. What is not provided by
+these methods (and why they are deprecated) is that they provide no
+mechanism to ensure message authenticity unless they are used with a
+so-called “combined” cipher mode such as CCM or GCM. (Note
+that as of JDK 1.6, the default JCE provider, “SunJCE”, does not
+support any combined cipher modes.)
+
Requirements for using ESAPI Symmetric Encryption
+
+The parties participating in using ESAPI's symmetric encryption
+capabilities must agree on the following:
+
+
+All parties must share the same encryption key(s). If multiple keys are
+used, each party must know which key to use for encryption / decryption.
+Parties must ensure that exchanging, storing, and all management
+of these encryption keys is done securely. How this is done is
+presently outside the scope of ESAPI encryptions, but developers may
+find the advice in
+
+OWASP's Cryptographic Storage Cheat Sheet helpful in this regard.
+
+
+If parties are only exchanging raw ciphertext (plus IV, when appropriate),
+then they must also agree on the cipher transformation to use.
+
+
+If the involved parties participating in encryption are not using a
+"combined" cipher mode that provides both confidentiality and authenticity
+(for example, something like GCM or CCM), then they must whether or
+not there will be an additional MAC sent allow with the raw ciphertext and
+other cipher spec information in order to provide evidence of authenticity /
+data integrity. (See the property Encryptor.CipherText.useMAC
+for further details.) Failure to agree on this may allow an adversary to
+carry out certain chosen ciphertext attacks against their encrypted data
+resulting in (possibly complete) leakage of the corresponding plaintext.
+
+
+
Encrypting / Decrypting with the New Methods -- The Simple Usage
+
Using the new encryption / decryption methods is somewhat more
+complicated, but this is in part because they are more flexible and
+that flexibility means that more information needs to be communicated
+as to the details of the encryption.
+
+
A code snippet using the new methods that use the master
+encryption key would look something like this:
+
+Yes, this is a bit more complicated, but it will 1) work across
+different hardware platforms and operating systems whereas the older
+methods may not, and 2) it provides for authenticityand
+confidentiality of the ciphertext regardless of which cipher
+mode is chosen.
+
Also, these new methods allow a general byte array to be
+encrypted, not just a Java String. If one needed to encrypt a byte
+array with the old deprecated method, one would first have to use
+
+
byte[] plaintextByteArray = { /* byte array to be encrypted */ };
+ String plaintext = new String(plaintextByteArray, "UTF-8");
+all the while catching the required UnsupportedEncodingException.
+For example, to handle this in ESAPI 1.4, one would have to write
+something like:
+
+ try {
+ byte[] plaintextByteArray = { /* byte array to be encrypted */ };
+ String myplaintext = new String(plaintextByteArray, "UTF-8");
+ String ciphertext = ESAPI.encryptor().encrypt(myplaintext);
+ String decrypted = ESAPI.encryptor().decrypt(ciphertext);
+ byte[] recoveredBytes = decrypted.getBytes(“UFT-8”);
+ assert java.util.Arrays.equals( plaintextByteArray, recoveredBytes );
+ } catch( UnsupportedEncodingException ex) {
+ // Should not happen but need to catch and deal with it anyhow.
+ // Log error then return error designation however appropriate.
+ } catch(EncryptionException ex) {
+ // Log error then return error designation however appropriate.
+ }
+
+However, dealing with this in ESAPI 2.0 is not any more cumbersome
+than dealing with Strings:
+Ideally when you are encrypting sensitive data you do not want the
+plaintext sensitive data to be left lying around after it is
+encrypted. Instead, you should overwrite them after their value as
+been used. However, when you are using immutable Strings, this is not
+possible using native Java methods. But if you are able to pass in
+byte arrays that are passed directly to PlainText
+objects (as shown above), the default is to overwrite this
+after they are encrypted.
+
+(Note: Verify!) If the default for
+Encryptor.PlainText.overwrite
+of true
+had been used, then the array plaintextByteArray
+would have been overwritten with ASCII “*” characters.
+
Encrypting / Decrypting with the New Methods – Storing Encrypted Data
+
If you use one of the new
+Encryptor encrypt() / decrypt() methods, how do you persist the
+CipherText object returned by the encrypt() methods and how do
+you restore it to pass to the decrypt() method?
+
The following example code
+snippet will illustrate this. In the following example we will simply
+write out the serialized CipherText object to a local file, but
+obviously you could hex- or base64-encode the serialized byte array
+and store it in a database or sent it in a SOAP XML message to a web
+service, etc.
+
public class PersistedEncryptedData
+ {
+ public static int persistEncryptedData(PlainText plaintext,
+ String filename)
+ throws EncryptionException, IOException
+ {
+ File serializedFile = new File(filename);
+ serializedFile.delete(); // Delete any old serialized file.
+
+ CipherText ct = ESAPI.encryptor().encrypt(plaintext);
+ byte[] serializedCiphertext = ct.asPortableSerializedByteArray();
+
+ FileOutputStream fos = new FileOutputStream(serializedFile);
+ fos.write(serializedCiphertext);
+ fos.close();
+ return serializedCiphertext.length;
+ }
+
+ public static PlainText restorePlaintext(String encryptedDataFilename)
+ throws EncryptionException, IOException
+ {
+ File serializedFile = new File(encryptedDataFilename);
+ FileInputStream fis = new FileInputStream(serializedFile);
+ int avail = fis.available();
+ byte[] bytes = new byte[avail];
+ fis.read(bytes, 0, avail);
+
+ CipherText restoredCipherText =
+ CipherText.fromPortableSerializedBytes(bytes);
+ fis.close();
+ PlainText plaintext = ESAPI.encryptor().decrypt(restoredCipherText);
+ return plaintext;
+ }
+ }
+
+
Advanced Usage
+
Encrypting / Decrypting with the New Methods
+
ESAPI 1.4 and earlier only allowed you to use the master key
+(MasterPassword in
+ESAPI 1.4; Encryptor.MasterKey in ESAPI 2.0) to encrypt
+and decrypt with. But encryption with a single key seldom is
+sufficient. For instance, lets say that your application has a need
+to encrypt both bank account numbers and credit card numbers. The
+encrypted bank account numbers are to be sent to one recipient and
+the encrypted credit card numbers are to be sent to a different
+recipient. Obviously in such cases, you do not want to share the same
+key for both recipients.
+
+
In ESAPI 1.4 there was not much you can do, but in ESAPI 2.0 and
+later, there are new encryption / decryption methods that allow you
+to specify a specific SecretKey. There is also a static
+helper method in CryptoHelper to allow you to generate a
+SecretKey of a specific type. (Distribution of this key
+is out of scope for this particular example, but for the moment, we
+will assume that secret keys are first generated, and then
+distributed to the recipients out-of-band. On you could distribute
+them dynamically via asymmetric encryption assuming that you've
+previously exchanged public keys with the recipients.)
+
The following illustrates how these new methods might be used.
+
+
First, we would generate some appropriate secret keys and
+distribute them securely (e.g., perhaps over SSL/TLS) or exchange
+them earlier out-of-band to the intended recipients. (E.g., one could
+put them on two separate thumb drives and use a trusted courier to
+distribute them to the recipients or one could use PGP-mail or S/MIME
+to securely email them, etc.)
+
+Second, these keys would be printed out and stored somewhere secure
+by our application, perhaps using something like ESAPI's
+EncryptedProperties class, where they could later be
+retrieved and used.
+
+
In the following code, we assume that the SecretKey
+values have already been initialized elsewhere.
+
+
SecretKey bankAcctKey = ...; // These might be read from EncryptedProperties
+ SecretKey credCardKey = ...; // or from a restricted database, etc.
+ ...
+ String bankAccountNumber = ...; // Assume obtained elsewhere
+ String creditCardNumber = ...; // Ditto
+ ...
+ try {
+ // Encrypt each with their appropriate secret key
+ CipherText encryptedBankAcct =
+ ESAPI.encryptor().encrypt( bankAcctKey, new PlainText(bankAccountNumber) );
+ CipherText encryptedCreditCard =
+ ESAPI.encryptor().encrypt( credCardKey, new PlainText(creditCardNumber) );
+ ...
+ // Decrypt using appropriate secret key
+ PlainText recoveredBankAcct = ESAPI.encryptor().decrypt( bankAcctKey, encryptedBankAcct ) );
+ assert bankAccountNumber.equals( recoveredBankAcct );
+ ... etc. ...
+ } catch(EncryptionException ex) {
+ // Log error then return error designation however appropriate.
+ }
+
Using ESAPI with Multiple Cipher Transformations
+For the most part, the architecture of ESAPI assumes that you will
+stick to using the defaults in the ESAPI.properties configuration
+file or implment your own classes--possibly by extending the ESAPI
+reference classes--and use these classes instead of the reference
+classes.
+
+For most things, this works well. Most applications likely can
+standardize on a single cipher transformation such as AES/CBC/PKCS5Padding
+with a 128-bit AES key and use that 100% of the time. However, on
+occassion, an application may need to use two separate cipher
+transformations (or even two different cipher algorithms) to
+handle legacy applications or deal with multiple partners.
+
+This section discusses how to do this without implementing your own
+classes or extending the ESAPI reference class, JavaEncryptor.
+Note that it is recognized that this approach is somewhat of a kludge.
+A simpler approach is planned for ESAPI 2.1, but the approach shown
+here is workable even though it's not pretty.
+
+If you find yourself in need of encrypting with a different cipher
+transformation, the first thing that you should count on is not
+using the same encryption key for each. While in some cases this
+likely would work (e.g., you are only using a different cipher mode
+or you have 256-bit AES key for "Encryptor.MasterKey" but also have
+a need to do encryption with a 128-bit AES key), it is not guaranteed
+to do so. Instead, you should count on generating a separate encryption
+key and using the encrypt / decrypt methods taking an additional
+SecretKey parameter as show in the previous section.
+
+
+Rather than repeating all the details of how to do this in this
+user guide, we encourage you to investigate how this was done in
+the Junit testing for the JavaEncryptor class. Please
+look at the source code for the private method
+runNewEncryptDecryptTestCase(String, int, byte[]) in
+the EncryptorTest JUnit test in the source code
+"src/test/java/org/owasp/esapi/reference/crypto/EncryptorTest.java".
+This code calls:
+
+which sets ESAPI to use the specified cipher transformation,
+cipherXform. As a convenience (for later restoral),
+it returns the previous cipher transformation.
+
+There are also a few non-obvious key size adjustments that are also
+going on with DES and DESede (aka, triple DES) keys that are made there
+as well. This has to do with the fact that for DES keys (which
+includes DESede), the "true" key size differs from the "effective"
+key size. (E.g., in DES, the "true" key size--from the DES algorithms's
+perspective is 64-bits, however the effective key size for DES
+is only 56-bits because of the 8-bits of parity "imposed" by the NSA in
+the early 1970s.) This inconsistency manifests itself in the JCE by
+the fact that KeyGenerator.init() wants the effective
+key size to be specified (so 56-bits for DES, 112- or 168-bits for
+DESede), but SecretKey.getEncoding().length stores the
+"true" key size (e.g., 64-bits or 192-bits for DES and DESede respectively).
+Other cipher algorithms do not have this discrepancy between true and
+effective key sizes. Since a SecretKey is returned by the
+KeyGenerator, this is only all too confusing. The
+reference JavaEncryptor and its JUnit test,
+EncryptorTest attempt to deal with this discrepency.
+See the adjustments made to key size in
+EncryptorTest.runNewEncryptDecryptTestCase()
+for further details.
+
+
Using ESAPI Symmetric Encryption with FIPS 140-2 Cryptographic Modules
+If you wish to use ESAPI with a FIPS 140-2 validated, JCE-compliant
+cryptographic module such as the
+
+IBM Java JCE FIPS 140-2 Cryptographic Module
+(hereafter referred to as IBMJCEFIPS) or the
+
+RSA Security BSafe Crypto-J
+(hereafter referred to as Crypto-J), or other similar products, you
+must follow these instructions. Failure to do so will mean that
+you will fail to meet FISMA compliance. (Note: The mention of these
+two specific vendor products does not constitute an endorsement from
+either OWASP or this author.)
+
+
+
Follow the vendor's regular instructions to configure your application
+to use the vendor product in a FIPS 140-2 compliant manner. Generally this
+will include some special configuration and/or initialization requirements
+that must be followed to restrict the vendor software to use FIPS 140-2
+approved algorithms.
+
+If the vendor's instructions do not already include a recommendation to edit
+the $JAVA_HOME/jre/lib/security/java.security file, the OWASP
+team recommends that you do so to prevent you from accidentally using any
+other cryptographic module (such as SunJCE). To do this, you will need
+to change the property "security.provider.1" (which represents the default)
+provider so that it refers to the fully-qualified classname of
+your vendor's JCE Provider class. (By default, this is set to
+"sun.security.provider.Sun".) In fact, you may wish to go as far as to
+either comment out or remove the other providers to reduce the possibility
+that they will accidentally be used by your application.
+
+
Edit the ESAPI.properties that your application is going to
+be using and set the property "Encryptor.PreferredJCEProvider" to
+the fully qualified classname of your vendor's FIPS 140-2 compliant
+JCE provider class. (If you are using a Java SecurityManager
+you may also need to grant
+org.owasp.esapi.reference.crypto.JavaEncryptor permissions
+to change the JCE provider.)
+
+
Edit the ESAPI.properties that your application is going to
+be using and set the property Encryptor.CipherText.useMAC to
+false. This is critical as having this property
+set to true causes ESAPI to use derived keys
+for the actual encryption and MAC calculation, which is against FIPS 140-2
+compliance. (Note: This
+does not mean that OWASP believes that this key derivation is weak--its
+design has been suggested some cryptographers--but it would be creating and
+using a related key for encryption in a manner not reviewed by NIST
+and thus it is not acceptable to FIPS 140-2 approval.)
+
+
Edit the ESAPI.properties that your application is going to
+be using and set the property "Encryptor.CipherTransformation" to
+a cipher transformation that is FIPS 140-2 certified for you vendor's
+software. OWASP recommends using a NIST "combined" cipher mode, that is
+one that provides for both message confidentiality and message
+authenticity if such a cipher mode is available from your vendor
+and FIPS 140-2 certified. (Cipher modes "GCM" and "CCM" are the only
+FIPS 140-2 approved as of this writing.)
+If such a "combined" cipher mode is not available, then use a cipher
+transformation like "AES/CBC/PKCS5Padding" with a random IV.
+This is almost always available as one of the FIPS 140-2 certified cipher
+transformations, however it will not provide you with message authenticity
+because to remain FIPS 140-2 compliant you will have had to disable the
+MAC calculation (via setting Encryptor.CipherText.useMAC to
+false) causing ESAPI to skip calculating an
+explicit MAC for you and hence providing no assurance of data integrity
+to the party attempting to decrypt your data. Without authenticity
+however, your encryption may still be vulnerable to the "padded oracle"
+chose ciphertext attack. Consult with your local cryptographic expert in
+such cases as this depends greatly on the circumstances of how you are
+using encryption.
+
+
+If your vendor softare requires you to explicitly to initialize their
+software for FIPS-mode (e.g., to cause the required FIPS 140-2 "power-on
+self tests" to run) by calling some software method, then this must be
+done by your application code before calling any of the ESAPI
+crypto-related code. Specifically, it must be called before
+your application calls ESAPI.encryptor().
+
+
+
+We believe that following these steps will still allow for your application
+to be FIPS 140-2 / FISMA compliant, however, as always, you should check
+with your FIPS auditor before using ESAPI in this manner. Should your
+auditors ask, feel free to point them to the ESAPI source code, which
+we believe will convince them that ESAPI is not a cryptographic module.
+(Rather, it only provides a wrapper to call other cryptographic modules
+through the standard JCE APIs.)
+
Acknowledgments
+The OWASP ESAPI development team would like to acknowledge the contributions
+of cryptographers David A. Wagner and Ian Grigg. David provided the
+outline of how to securely compute derived keys for confidentiality
+and authenticity from a single master key and Ian convinced us
+to take a packetizing approach to laying out the portable, serialized
+CipherText object.
+
+In addition, Kevin Kenan has agreed to review all the crypto code
+from ESAPI 2.0-rc5 or 2.0-rc6 candidate release. Others are invited
+to participate as well, especially those with a background in cryptography.
+(See
+"Request to review ESAPI 2.0 crypto" for details.)
+
+I would also like to thank Jessica Fitzgerald-McKay and Andy Sampson of
+the Systems and Network Analysis Center of the NSA for their excellent feedback in
+response to the review request made in Google Issue #81. Working with bureaucracy
+is not something that I do particularly well, but Jessica and Andy made it as
+painless as it possibly could be. Their feedback, which at this point,
+unfortunately we are unable to quote, was generally favorable, but in the
+places where they had recommendations, these were very precise and
+helpful.
+
+Lastly, I would like to thank Jeffrey Walton of Software Integrity, LLC.
+Jeff provided an extremely thorough analysis of ESAPI 2.0's (as of 2.0_rc10)
+Key Derivation Function (KDF). Jeff's analysis convinced me to bring ESAPI's
+KDF more in line with NIST's recommendations for KDFs as described in
+NIST Special Publication 800-108 (and specifically section 5.1). You can
+read about Jeff's review at
+
+Analysis of ESAPI 2.0's Key Derivation Function
+
+
+
+
diff --git a/documentation/esapi4java-core-2.1-release-notes.txt b/documentation/esapi4java-core-2.1-release-notes.txt
new file mode 100644
index 000000000..e97e56c93
--- /dev/null
+++ b/documentation/esapi4java-core-2.1-release-notes.txt
@@ -0,0 +1,68 @@
+ESAPI for Java - 2.1.0 Release Notes
+
+1) Fixed security issue #306, a vulnerability discovered by Phillipe Arteau.
+ This fix necessitated removing the deprecated encrypt() and decrupt() methods
+ that were intended to provide backward compatibility with ESAPI 1.4.
+ As it turns out, there was no way to fix this bug without a major rewrite
+ unless these methods were removed. However, as these two methods have been
+ deprecated more than 2 years ago and they are known to be insecure
+ (they are vulnerable to padding oracle attacks), the ESAPI team has
+ decided to remove them in accordance to their support policy.
+
+ See comments for issue #306 for further details, as well as additional
+ safety precautions that you may wish to take in the unlikely, but possible
+ event that this vulnerability resulted in an actual security breach.
+
+ Finally, since the removal of these methods constitute an interface change
+ (to the Encryptor interface), this is considered a minor release (2.1)
+ rather than simply a patch release (2.0.2).
+
+ Please note that there are further updates planned to further strengthen
+ the MAC that ESAPI crypt uses. However, because they will require some
+ design changes, they may not be out for another month. Note that these
+ fixes do not correct any *known* vulnerabilities, but will address
+ some potential weaknesses in what is not included in the MAC (such as
+ the crypto version).
+
+2) Other Google Issues fixed: 257, 271, and 292 are all fixed in this release.
+
+3) Fixed Javadoc for Encoder.encryptForJavaScript(). [Revision r1879]
+
+4) DefaultEncryptedProperties - made minor Javadoc changes.
+
+5) The ESAPI 2.0 Encryptor.encrypt() methods now all throw an appropriate
+ IllegalArgumentException if any of the arguments are null. Previously,
+ if any of the arguments were null you would either get an AssertionError
+ (if you had assertions enabled) or a default NullPointerException when
+ assertions were disabled. While IllegalArgumentException is still an
+ unchecked RuntimeException, note that if you were previously catching
+ NullPointerExceptions for these cases, you may need to change your code.
+
+6) The public constructor, CiphertextSerializer(CipherText ct), was changed
+ to explicitly check that the parameter is not null. Previously it had
+ checked with assertions which might later result in a NullPointerException
+ being thrown if assertions were disabled. Now if the parameter is null,
+ an appropriate IllegalArgumentException is thrown. This should not really
+ affect existing code (unless you are experimenting implementing your own
+ crypto) since user code should not really be using CiperTextSerializer
+ directly.
+
+7) Some of the setter methods in KeyDerivationFunction were changed to explicitly
+ check for invalid arguments and throw an IllegalArgumentException rather than
+ checking these parameters via assertions. This should not affect general
+ user code as most would not be calling the KeyDerivationFunction class
+ directly.
+
+8) Other miscellaneous minor code clean-up, mostly to remove compiler warnings.
+
+NOTE: A follow-up patch release is scheduled within the next few months to
+ address some questionable design decisions regarding what data in
+ the serialized ciphertext should be authenticated via the MAC. For
+ instance, presently only the IV+ciphertext is MAC'd (as would be the
+ equivalent case of when you would use an authenticated combined cipher
+ mode such as GCM or CCM). A deeper analysis of the design is required
+ based on findings in Google Issue # 306. I will periodically try
+ to keep the ESAPI mailing lists updated with the progress so watch
+ there for emerging details and anticipated schedule.
+
+-Kevin W. Wall , 2013-08-30
diff --git a/documentation/esapi4java-core-2.1.0.1-release-notes.txt b/documentation/esapi4java-core-2.1.0.1-release-notes.txt
new file mode 100644
index 000000000..4c599ff59
--- /dev/null
+++ b/documentation/esapi4java-core-2.1.0.1-release-notes.txt
@@ -0,0 +1,129 @@
+Release notes for ESAPI 2.1.0.1
+ Release date: 2016-Feb-05
+ -Kevin W. Wall
+ -Chris Schmidt
+
+Previous release: ESAPI 2.1.0, Sept 2013
+
+
+-----------------------------------------------------------------------------
+ GitHub Issues fixed in this release:
+ 36 issues closed
+
+32 - URLs in doc for HTTPUtilities.setNoCacheHeaders are wrong
+58 - Separate Crypto Related Properties into Separate File
+ Fixed as part of issue #350. Can be addressed by placing sensitive
+ ESAPI crypto properties into a separate properties file controlled by
+ the operations team and not checked into your SCM. For further details,
+ see documentation/ESAPI-configuration-user-guide.md and use system property
+ org.owasp.esapi.opsteam.
+96 - Need validation configuration enhancements
+103 - Make ESAPI configuration XML
+200 - DefaultHttpUtilities.sendRedirect should throw AccessControlException, not IOException
+205 - BaseValidationRule.assertValid(String context, String input) causes NPE if input is not valid.
+221 - IntrusionException should extend EnterpriseRuntimeException
+229 - printStackTrace when loading configuration file
+237 - how can we use esapi in java for validation,please see files attached containing java code and for errors
+254 - Patch for /trunk/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java
+261 - Could not set multiple cookies one by one at single request
+275 - Log4JLogger.java doesn't output correct file & line number because FQCN isn't forwarded to Log4J
+276 - Patch for /branches/2.1/src/main/java/org/owasp/esapi/reference/DefaultExecutor.java
+287 - Patch for /branches/2.1/src/main/java/org/owasp/esapi/reference/FileBasedAuthenticator.java
+288 - Patch for /trunk/src/test/java/org/owasp/esapi/reference/UserTest.java
+289 - ClickjackFilter after doFilter
+306 - Canonicalizing "%Device% changes the meaning of the input string
+313 - Insecure default configuation for Executor.ApprovedExecutables in ESAPI.properties file
+315 - ValidatorTest.testIsValidDate fails if default locale is not US
+318 - Incorrect Equality test on floating point values
+319 - Resource leak: FileInputStream is not closed on method exit
+321 - Unsynchronized get method, synchronized set method
+322 - RequestRateThrottleFilter may not work as expected with hits=1 or hits=2
+323 - PolicyFactory Sanitize method weird output
+328 - StringUtils.union broken which has minor impact on CSRF Protection and random file name generation
+330 - setHeader blocks legitimate headers due to header name size limit being too low
+331 - Log4j configuration with no root level causes NPE in Log4jLogger.java
+334 - Regex in ESAPI.properties is not considering few of the french characters
+336 - Log4JLogger.java doesn't output correct file & line number-Similar issue as reported in Issue 268
+344 - JUnit test failure in ValidatorTest.testGetValidSafeHTML()
+345 - JUnit test failure in ValidatorTest.testIsValidDate()
+347 - Fixes #345 - JUnit test failure in ValidatorTest.testIsValidDate()
+349 - Package correctly the esapi.tld into ESAPI jar
+350 - [ESAPI Spring Code Sprint – May / June 2015] Implementation of requirements
+351 - getHeader length limit error
+354 - Add stern javadoc warning about Base64.decodeToObject() being unsafe and mark method as deprecated.
+ Note: This method no longer functions unless the system property org.owasp.esapi.enableUnsafeSerialization
+ is set to "true". This breaks backward compatibility in favor of taking a more secure posture.
+355 - Temp files created by org.owasp.esapi.waf.internal.InterceptingServletOutputStream not removed by WAF JUnit tests
+356 - Make end-of-line terminators consistent for .java, .xml, and other ESAPI source files.
+359 - CodecTest unit tests never test with a populated char array.
+
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release not tracked via GitHub issues
+
+* Miscellaneous minor javadoc fixes and updates.
+* Fixed grammatical error in CipherTextSerializer class error message.
+* Upgraded versions of several ESAPI dependencies (i.e., 3rd party jars), including several that had unpatched CVEs.
+* Added the Maven plug-in for OWASP Dependency Check so 3rd party dependencies can be kept up-to-date.
+* Added .gitignore file so that certain files won't get accidentally commited such as IDE files.
+* Added .gitattributes file so to help resolve end-of-line issues. (Part of issue 356.)
+* Added new documentation (documentation/ESAPI-configuration-user-guide.md) describing new ESAPI configuration feature.
+* Changed many assertions in ESAPI crypto to explicit runtime checks that
+ throw IllegalArgumentException instead.
+
+-----------------------------------------------------------------------------
+ ATTENTION: Other Important Notes
+
+The JUnit test AuthenticatorTest.setCurrentUser() is periodically failing
+due to an apparent race condition either in the test itself or in
+FileBasedAuthenticator. See GitHub issue #360 for details, including
+why we don't think it is worth holding up the release for.
+
+-----------------------------------------------------------------------------
+
+ Contributors for ESAPI 2.1.0.1 release
+
+Notice: My appologies if I've missed anyone, but you did have an opportunity
+ to send me your names. (I solicited for contributors names to emails
+ to the ESAPI-Dev and ESAPI-User mailing lists sent on 1/23/2016.)
+ If I missed you and you contributed to THIS release, please send
+ me an email with your first and last name and what your SPECIFIC
+ contribution was and I will see you name is added to this list.
+ - Kevin W. Wall
+
+Project co-leaders
+ Kevin W. Wall (kwwall)
+ Chris Schmidt (chrisisbeef)
+
+Special shout-outs to:
+ Matt Seil (xeno6696)
+ Jeremiah Stacey (jeremiahjstacey)
+
+Special contributions:
+ ESAPI Hackathon participants - November 18, 2014 - January 20, 2014
+ Daniel Amodio
+ Eric Kobrin
+ Eric Citaire
+ Eamonn Washington
+ John Melton
+ Special thanks to Samantha Groves for assisting with the ESAPI hackathon
+
+ Professor and students involved in ESAPI Spring Code Sprint (May - June, 2015):
+ Marek Zachara - instructor
+ Patryk Bak - student
+ Marcin Siedlarz - student
+ Szymon Bobowiec - student
+ Karol Kapcia - student
+ Fabio Cerullo - OWASP board coordination for code sprint
+
+Other Contributors:
+ Karan Sanwal
+ Arpit Gupta
+ Constantino Cronemberger
+ Tà rin Gamberìni
+ Kad Dembele
+ Anthony Musyoki
+ Andrew VanLoo
+ Ashish Tripathy
+ Brad Schoening
diff --git a/documentation/esapi4java-core-2.2.0.0-release-notes.txt b/documentation/esapi4java-core-2.2.0.0-release-notes.txt
new file mode 100644
index 000000000..b43efc743
--- /dev/null
+++ b/documentation/esapi4java-core-2.2.0.0-release-notes.txt
@@ -0,0 +1,421 @@
+Release notes for ESAPI 2.2.0.0
+ Release date: 2019-June-24
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.1.0.1, February 5, 2016
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+* Upgrade to require JDK 7 or later. JDK 6 is no longer supported by ESAPI.
+* Upgrade to require Java Servlet API 3.0.1 or later. See "Appendix: Dependency Updates (as reflected in pom.xml)" below for additional details.
+* 100+ GitHub issues closed. (Note: Includes previously incorrectly closed issues that were reopened, fixed, and then closed again.)
+* Upgraded versions of several ESAPI dependencies (i.e., 3rd party jars), including several that had unpatched CVEs. See "Appendix: Dependency Updates (as reflected in pom.xml)" below for full details.
+* Known vulnerabilities still not addressed:
+ - There is this critical CVE in log4j 2.x before 2.8.2: CVE-2017-5645. It is a Java deserialization vulnerability that can lead to arbitrary remote code execution. Some private vulnerability databases claim that this same vulnerability is present in log4j 1.x even though the CVE itself does not claim that. However, examination of this CVE shows that the vulnerability is associated with implementations of TcpSocketServer and UdpSocketServer, which implement fully functional socket servers that can be used to listen on network connections and record log events sent to server from various client applications. For ESAPI to be vulnerable to that, first someone would have to have an implementation of wone of those servers running and secondly, they would have to change ESAPI's log4j.xml configuration file so that it uses log4j's SocketAppender rather than the default ConsoleAppender that ESAPI's default deployment uses. Thus even if this vulnerability were present in log4j 1.x, ESAPI's use of ConsoleAppender makes it a non-issue.
+ - There is a known and unpatched vulnerability in the SLF4J Extensions that some vulnerability scanners may pick up and associate with ESAPI's use of slf4j-api-1.7.25.jar. (Note that OWASP Dependency Check does NOT flag this vulnerability [CVE-2018-8088], but others may.) According to NVD, this vulnerability is associated with "org.slf4j.ext.EventData in the slf4j-ext module in QOS.CH SLF4J before 1.8.0-beta2". Fortunately, I have confirmed that this Java deserialization does not impact ESAPI. First off, the default configuration of ESAPI.properties does not use SLF4J, but even if an application should choose to use it, ESAPI does not include the slf4j-ext jar and it has been confirmed that the vulnerable class (org.slf4j.ext.EventData) is not included in the slf4j-api jar that ESAPI does. Unfortunately, this CVE is not patched in the latest SLF4J packages, so even if we were to update it to latest version (currently 1.80-beta2, as of 12/31/2018), any scanners that associate ESAPI with CVE-2018-8088 would still have this false positive. But the important thing to ESAPI users is to know that if this CVE is identified for ESAPI, that it is a false positive.
+ - There is a recently discovered issue (see https://app.snyk.io/vuln/SNYK-JAVA-COMMONSBEANUTILS-30077) that is related to CVE-2014-0114 that is a Java deserialization issue in Apache Commons BeanUtils 1.9.3 that can lead to remote command execution attacks. This had been fixed in 1.9.2, but apparently they missed a place where the fix was needed. A GitHub commit (https://github.com/apache/commons-beanutils/pull/7/commits/2780a77600e6428b730e3a5197b7c5baf1c4cca0) has been made to mster branch of the BeanUtils repo, but thus far, no official patch has been released. ESAPI only uses BeanUtils in its AccessController (specifically, DynaBeanACRParameter class), where it has a dependency on org.apache.commons.beanutils.LazyDynaMap. Based on the BeanUtils commit, the fix was in org.apache.commons.beanutils2.PropertyUtilsBean. Based on a cursory examination, the ESAPI team does not believe that this vulnerability reported by Snyk is exploitable given that manner that it is used within ESAPI, or if it is, it is not externally exploitable based on the default access control rules that are provided with ESAPI. However, the ESAPI team will be watching for an official patch to Apache Commons BeanUtils and we will release a patched version of ESAPI as patch point release once a patch is officially available in Maven Central.
+ - Otherwise, ESAPI 2.2.0.0 addresses all know CVEs except for CVE-2013-5960 (which I have fixed in a private BitBucket repo, but getting it to be backward compatible is proving to be more difficult than anticipated.) Besides, if you want to use encryption in Java, I'd highly recommend using Google Tink, which is much more fully featured than ESAPI. (Tink allows key rotation, storing keys in various cloud HSMs, etc.)
+
+
+It was mainly because of these first two bullet items above that we bumped the release to 2.2.0.0 rather than to 2.1.0.2. (See GitHub Issue #471 for details.)
+=================================================================================================================
+
+ Basic ESAPI facts
+
+ESAPI 2.1.0.1 release:
+ 177 Java source files
+ 1547 Junit tests in 88 Java source files
+
+ESAPI 2.2.0.0 release:
+ 194 Java source files
+ 4150 JUnit tests in 118 Java source files
+
+That's 2603 NEW tests since the 2.1.0.1 release!!!
+
+ GitHub Issues fixed in this release
+ [i.e., since 2.1.0.1 release on 2016-Feb-05]
+ More than 100 issues closed
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+30 ESAPIFilter in RI should allow login page destination to be configured
+31 MySQL CODEC : "_" character not handled properly ?
+37 RandomAccessReferenceMap.update() can randomly corrupt the map
+71 java.lang.ExceptionInInitializerError in 2.0 version
+129 Add Logging support for SLF4J
+157 minimum-config deployment fails
+188 SecurityWrapperRequest seems to mishandle/swallow allowNull argument
+209 Build an encoding function specific to HTTP/Response Splitting (tactical remediation)
+213 Provide a taglib descriptor (.tld file)
+223 DecodeFromURL fails when the input is "%" (without quotes)
+228 EncodeForHTML or other Encoding methods fail if there is a windows style path being encoded.
+234 Canonicalization might not be performed
+244 Unable to use the esapi taglib as esapi.tld file is missing in the ESAPI 2.0 GA release
+246 CryptoHelper::arrayCompare - leaks info about arrays
+247 XSS Cheat sheet on safe vs unsafe CSS property value syntax is inaccurate
+253 tag library will not function without ESAPI configuration
+255 Patch for /trunk/src/main/java/org/owasp/esapi/reference/crypto/JavaEncryptor.java
+258 isValidDate fails to identify injection attack [[Note: closed as duplicate of 299]]
+259 JavascriptCodec is removing all backslashes
+265 Canonicalize function for the DefaultEncoder class does not handle URLs properly
+267 java.lang.ClassNotFoundException: org.owasp.validator.html.PolicyException
+273 Could not initialize class org.owasp.esapi.reference.crypto.JavaEncryptor
+274 Logger.log is is slow
+277 NPE in SafeFile.doDirCheck() on empty file path, needs null check.
+278 ValidatorTest fails with German default Locale
+280 HTMLEntityCodec.getNamedEntity not case sensitive
+281 missing assertions in SafeFileTest.java
+282 Difference between encodeForHTMLAttribute and encodeForHTML
+283 nekohtml fails ESAPI.validator().getValidSafeHTML();
+284 ESAPI.validator().getValidInput() returns misleading Exception
+285 Incorrect treatement of named html entities
+286 JavaLogFactory not thread safe
+289 ClickjackFilter after doFilter
+291 DefaultEncoder.canonicalize() Bug
+292 jsessionid validator regex in esapi.properties not applicable to ids generated by tomcat
+293 Canoniclizing out of EncodeforLdap or EncodeForDN if contains specific characters like "(, ) #" etc. messes up the input.
+294 Config Error
+295 ESAPI validator isValidRedirectLocation does not work
+296 CSS and images not working with ESAPIWebApplicationFirewallFilter
+297 ClassNotFoundException: org.owasp.esapi.reference.accesscontrol.DefaultAccessController AccessController class
+299 isValidDate fails with patterns ending with "yyyy"
+300 non-BMP characters incorrectly encoded
+301 encodeForHTMLAttribute escapes the forward slash
+302 HTMLEntityCodec#decode incorrectly decodes upper-case accented letters as their lower-case counterparts
+303 HTMLEntityCodec destroys 32-bit CJK (Chinese, Japanese and Korean) characters
+304 encodeForCSS breaks color values
+305 ClassCastException when using ESAPI logger
+307 Issue with decodeFromURL method in the DefaultEncoder
+308 AuthenticatedUser isCredentialsNonExpired() have todo comment, but default return false;
+309 Eliminate eclipse code warnings to improve quality
+316 Deprecate current HttpUtilities.setRememberToken() and replace with one not requiring user password
+317 Resource leak: This FileReader is not closed on method exit
+325 ClassCastException on SecurityWrapperResponse
+327 Construct "&" in Validator.URL is simple character class, not reference to ampersand
+329 AbstractAccessReferenceMap.addDirectReference not invariant
+333 logger is gettin class cast exception
+352 Possible threading issue in EnterpriseSecurityExceptionTest
+360 AuthenticatorTest.setCurrentUser() periodically fails.
+361 Update pom.xml to use latest Maven plugins
+364 Possible null deference found by Coverity (id # 1352406) in CipherTextSerializer class
+365 TLD not in Jar
+366 Need instructions for building and developing ESAPI in IntelliJ
+371 Synchronize instance with GitHub issues
+372 Use of vulnerable commons-httpclient:commons-httpclient:3.1 dependency
+373 Create File Validator that checks Magic Bytes as Opposed to Extensions
+374 Email Validator does not accept + and longed domain names while it is allowed in ICANN
+375 java.lang.NoClassDefFoundError - .StrTokenizer
+376 Infinite or very long loop in URL validation URL
+379 WAF: GeneralAttackSignatureRule fails to process request with single parameter.
+381 Update ESAPI's pom.xml to address vulnerable 3rd party components
+383 SecurityWrapperResponse is overwriting http status codes that conflicts with RESTful Web Service protocols
+385 Method logSpecial in DefaultSecurityConfiguration is private and cannot be overriden by subclasses
+386 Avoid using System.err in EsapiPropertyManager
+387 'mvn site' fails for FindBugs report, causing 'site' goal to fail
+389 Provide an option for the encodeForLDAP method to not encode wildcard characters
+394 Refactor Validator.getCanonicalizedUri into Encoder.
+395 Issues when I am passing htttp://localhost:8080/user=admin&prodversion=no
+396 Trust Boundary Violation - while triggering veracode
+397 Update Resource path search to maintain legacy behavior in DefaultSecurityConfiguration.java
+398 addHeader in SecurityWrapperResponse has an arbitrary limit of 20 for the length of the Header name
+399 Fix Build Error when using mvn site
+400 Create a unit test for SecurityWrapperResponse
+403 Refactor all "Magic Numbers" in the baseline to use ESAPI.properties configurations
+414 canonicalize falsely recognizes HTML named entities
+417 Add additional protection against CVE-2016-1000031
+422 Inconsistent dependency structure and vulnerable xml (xerces, xalan, xml-apis ...) dependencies
+424 issue with Filename encoding for executeSystemCommand
+425 Project build error: Non-resolvable parent POM for org.owasp.esapi:esapi:2.1.0.2-SNAPSHOT: Could not transfer artifact
+427 HTTP cookie validation rules too restrictive?
+429 Miscellaneous updates to pom.xml
+432 ESAPI.properties not found.
+433 Class Cast Exception when trying to run JUnit Tests
+435 DefaultEncoder exhibits "double checked locking" anti-pattern
+437 CVE-2016-2510
+438 EncryptorTest.testNewEncryptDecrypt() fails for 112-bit (2-key) DESede if Bouncy Castle provider is installed as preferred provider
+439 Tighten ESAPI defaults to disallow dubious file suffixes
+442 Remove deprecated fields in Encoder interface
+444 Delete deprecated method Base64.decodeToObject() and related methods
+445 A bunch of dependencies are out of date , I will list them below with the associated vulnerability
+447 can't generate MasterKey / MasterSalt
+448 Clean up pom.xml
+454 about code eclipse formatter template question
+455 New release for mitigation of CVEs
+457 when run jetty ,can not find esapi\ESAPI.properties
+461 Eclipse setup issues
+462 Allow configurable init parameter in ESAPIFilter for unauthorized requests
+463 Create release notes for next ESAPI release
+465 Update both ESAPI.properties files to show comment for ESAPI logger support for SLF4J
+471 Bump ESAPI release # to 2.2.0.0
+476 DefaultValidator.getValidInput implementation ignores 'canonicalize' method parameter
+478 Remove obsolete references to Google Code in pom.xml and any other release prep
+482 ESAPI 2.2.0.0 release date?
+483 More miscellaneous prep work for ESAPI 2.2.0.0 release
+485 Update Maven dependency check plugin to 5.0.0-M2
+488 Missed a legal input case in DefaultSecurityConfiguration.java
+492 Release candidates on maven central
+493 wrong regex validation
+499 ValidatorTest.isValidDirectoryPath() has tests that fail under Windows if ESAPI tests run from different drive where Windows installed
+500 Suppress noise from ESAPI searching for properties and stop ignoring important IOExceptions
+
+
+-----------------------------------------------------------------------------
+
+ Changes requiring special attention
+
+* Various deprecated methods were _actually_ deleted! This could break existing application code.
+
+ Issue 442 Remove deprecated fields in Encoder interface
+
+ Specifically, if you are using any of these previously deprecated fields from the Encoder interface, you need to update your application code to refer insteat to the constances from org.owasp.esapi.EncoderConstants:
+
+ public final static char[] CHAR_LOWERS = EncoderConstants.CHAR_LOWERS;
+ public final static char[] CHAR_UPPERS = EncoderConstants.CHAR_UPPERS;
+ public final static char[] CHAR_DIGITS = EncoderConstants.CHAR_DIGITS;
+ public final static char[] CHAR_SPECIALS = EncoderConstants.CHAR_SPECIALS;
+ public final static char[] CHAR_LETTERS = EncoderConstants.CHAR_LETTERS;
+ public final static char[] CHAR_ALPHANUMERICS = EncoderConstants.CHAR_ALPHANUMERICS;
+ public final static char[] CHAR_PASSWORD_LOWERS = EncoderConstants.CHAR_PASSWORD_LOWERS;
+ public final static char[] CHAR_PASSWORD_UPPERS = EncoderConstants.CHAR_PASSWORD_UPPERS;
+ public final static char[] CHAR_PASSWORD_DIGITS = EncoderConstants.CHAR_PASSWORD_DIGITS;
+ public final static char[] CHAR_PASSWORD_SPECIALS = EncoderConstants.CHAR_PASSWORD_SPECIALS;
+ public final static char[] CHAR_PASSWORD_LETTERS = EncoderConstants.CHAR_PASSWORD_LETTERS;
+
+ Issue 444 Delete deprecated method Base64.decodeToObject() and related methods
+
+ Specifically, the following methods were removed from the org.owasp.esapi.codecs.Base64 class. If you will using any of these methods, you likely already had vulnerabilities in your application code. If any of these methods were being used, you will need to rewrite your application code:
+
+ public static String encodeObject( java.io.Serializable serializableObject )
+ public static String encodeObject( java.io.Serializable serializableObject, int options )
+ public static Object decodeToObject( String encodedObject )
+
+ Issue 483 More miscellaneous prep work for ESAPI 2.2.0.0 release
+ Specifically, CipherText.getSerialVersionUID() and DefaultSecurityConfiguration.MAX_FILE_NAME_LENGTH have actually been deleted from the ESAPI code base. For the former, use CipherText.cipherTextVersion() instead. For the latter, there is no replacement. (This wasn't being used, but it was set to 1000 in case you're wondering.)
+
+* Various properties in ESAPI.properties were changed in a way that might affect your application:
+ Issue 439 Tighten ESAPI defaults to disallow dubious file suffixes
+
+ Specifically, the property HttpUtilities.ApprovedUploadExtensions changed from
+ HttpUtilities.ApprovedUploadExtensions=.zip,.pdf,.doc,.docx,.ppt,.pptx,.tar,.gz,.tgz,.rar,.war,.jar,.ear,.xls,.rtf,.properties,.java,.class,.txt,.xml,.jsp,.jsf,.exe,.dll
+ to:
+ HttpUtilities.ApprovedUploadExtensions=.pdf,.doc,.docx,.ppt,.pptx,.xls,.xlsx,.rtf,.txt,.jpg,.png
+ so if you were relying on your application to legimately accept an of the dangerous file types that were removed, you will need to update this property in your application's ESAPI.properties file accordingly.
+
+ - Several other properties related to the ESAPI Validator interface (typically through one of the isValid() methods) have had their default values which it uses modified. This mostly affects the use ESAPI.validator().isValid() calls, use of the class org.owasp.esapi.filters.SecurityWrapperRequest (which extends HttpServletRequestWrapper and is often used separately), as well as the ESAPI servlet filter, org.owasp.esapi.filters.SecurityWrapper, that uses it SecurityWrapperRequest. The following ESAPI properties are affected. If you are relying on any of these properties, you should review your application to see if / how it might be impacted.
+
+ Validator.HTTPContextPath: Changed so that '/' is no longer a valid character.
+ Validator.HTTPHeaderName: Changed so that the max size of a valid HTTP header name increased from 50 to 256.
+ Validator.HTTPJSESSIONID: Changed so that valid HTTP JSESSIONID length increased from 30 to 32 characters.
+ Validator.HTTPParameterName: Changed so that '-' is now considered a valid character for an HTTP parameter name.
+ Validator.HTTPParameterValue: Changed so that some additional characters are allowed and length is limited to 1000 characters; i.e., changed from:
+ Validator.HTTPParameterValue=^[a-zA-Z0-9.\\-\\/+=@_ ]*$
+ to:
+ Validator.HTTPParameterValue=^[\\p{L}\\p{N}.\\-/+=_ !$*?@]{0,1000}$
+ Validator.HTTPQueryString: Changed lots of things. Specifically, changed from:
+ Validator.HTTPQueryString=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ %]*$
+ to:
+ Validator.HTTPQueryString=^([a-zA-Z0-9_\\-]{1,32}=[\\p{L}\\p{N}.\\-/+=_ !$*?@%]*&?)*$
+ (Left as an exercise for the reader to figure out what exactly this means. ;-)
+ Validator.HTTPURI: Changed to be much more restrictive; i.e., changed from:
+ Validator.HTTPURI=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$
+ to:
+ Validator.HTTPURI=^/([a-zA-Z0-9.\\-_]*/?)*$
+
+* Other changes:
+ Issue 500 Suppress noise from ESAPI searching for properties and stop ignoring important IOExceptions
+
+ Fixing this required changes to the CTORs of the following classes:
+
+ org.owasp.esapi.configuration.EsapiPropertyManager
+ org.owasp.esapi.configuration.AbstractPrioritizedPropertyLoader
+ org.owasp.esapi.configuration.EsapiPropertyLoaderFactory
+ org.owasp.esapi.configuration.StandardEsapiPropertyLoader
+ org.owasp.esapi.configuration.XmlEsapiPropertyLoader
+
+ These CTORs now explicitly throw IOException if the specified ESAPI property file is not found or not readable. Note that this should not affect most people as most use DefaultSecurityCOnfigurator and it still only throws ConfigurationException. (IOExceptions from these other classes are caught and rethrow as ConfigurationException.) Use of these classes directly should be very rare.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+* Updated minimal version of Maven from 3.0 to 3.1 required to build ESAPI.
+* Miscellaneous minor javadoc fixes and updates.
+* Added the Maven plug-in for OWASP Dependency Check so 3rd party dependencies can be kept up-to-date.
+* Updated .gitignore file with additional files to be ignored.
+* Changed many additional assertions in ESAPI crypto to explicit runtime checks that throw IllegalArgumentException instead. If you were using ESAPI crypto correctly, it shouldn't affect you, but if you were calling it incorrectly, you may now immediately get an IllegalArgumentException rather than something like a mysterious MullPointerException much later on.
+
+-----------------------------------------------------------------------------
+
+ Contributors for ESAPI 2.2.0.0 release
+
+Notice:
+ My appologies if I've missed anyone, but I have went solely by GitHub's record or *merged* PRs closed since 2.1.0.1 (i.e., > 2016-02-05). If you submitted a patch file that was included with some other PR or worked with someone else that contributed a merged PR, drop me an email. It is not my intention to slight anyone's contribution. If you can provide evidence of this, we will add your GitHub ID to this list.
+
+ Note that some of you may have submitted PRs that were rejected or closed for other reasons (such as being a duplicate, etc.) If you feel that you should still be mentioned here, shoot me an email and make your case and I will discuss it with my project co-lead, and you might be added to these release notes retroactively.
+ - Kevin W. Wall
+
+Project co-leaders
+ Kevin W. Wall (kwwall)
+ Matt Seil (xeno6696)
+
+Special shout-outs to:
+ Jeremiah Stacey (jeremiahjstacey) -- All around ESAPI support and JUnit test case developer extraordinaire
+ Dave Wichers (davewichers) - for Maven Central / Sonatype help
+
+List of all PRs closed since 2.1.0.1 (2016-Feb-05) -
+ List includes merged AND rejected PRs
+
+ 53 Closed PRs since 2.1.0.1 release
+ ===================================
+#362 by artfullyContrived was merged on Feb 9, 2016 -- Update pom.xml to use latest Maven plugins
+#367 by drm2 was merged on Apr 9, 2016 -- Adding IntelliJ Tests setup documentation
+#368 by bkimminich was closed on May 7, 2016 -- Enable Travis CI build
+#369 by artfullyContrived was merged on Apr 22, 2016 -- Packages the esapi.tld into the jar file.
+#370 by kravietz was closed on Sep 23, 2018 • Changes requested -- Integer overflow in for loop
+#378 by sunnypav was merged on Jul 21, 2017 • Changes requested -- #302 HTMLEntityCodec Now decodes cased accented letters properly
+#380 by mickilous was merged on Jul 16, 2017 • Approved -- Support of Cookie without maxAge set
+#384 by matthiaslarisch was closed on Oct 5, 2018 -- this commit fixes #385 changed visibility of method 'logSpecial(...)' from private to protected and #386 to avoid System.err output
+#388 by augustd was merged on May 13, 2017 -- Suppress CVE-2016-1000031 in dependency check Build-Maven
+#390 by JoelRabinovitch was merged on Jul 3, 2017 -- Issue 389
+#391 by xeno6696 was merged on Jun 18, 2017 • Approved -- Issue #376 -- Addressed Kevin Wall's CR comments.
+#392 by xeno6696 was merged on Jun 18, 2017 -- Issue 376 -- Added missed null check on regex pattern.
+#393 by xeno6696 was merged on Jul 16, 2017 -- Issue 316 -- updated code to account for httpOnly and Secure cookie …
+#401 by xeno6696 was merged on Jul 16, 2017 -- Updated pom.xml so the base compile version is 1.7 instead of 1.6. T…
+#402 by xeno6696 was merged on Jul 16, 2017 -- Issue #398 -- Fixed hardcoded instance of HTTP header and made it con…
+#404 by xeno6696 was merged on Jul 21, 2017 -- Added simple unit test to validate changes that made HTML entities al…
+#405 by xeno6696 was merged on Jul 24, 2017 -- Multiple issues, #403, #400, #383, #405
+#406 by xeno6696 was merged on Jul 24, 2017 -- Issue #317 -- Fixed resource leak. Special thanks to eamonn.
+#407 by augustd was merged on Jul 27, 2017 -- Update antisamy xom
+#409 by xeno6696 was merged on Jul 27, 2017 -- Issue #327 got rid of misleading HTML entity in URL regex.
+#410 by xeno6696 was merged on Jul 28, 2017 -- Issue #292 && Issue #403 -- Updated default regex size for jsessionid…
+#411 by xeno6696 was merged on Jul 30, 2017 -- Merging commits related to #403.
+#413 by xeno6696 was merged on Aug 11, 2017 • Approved -- Issue #300 -- Fixing ESAPI's inability to handle non-BMP codepoints.
+#415 by xeno6696 was merged on Aug 11, 2017 -- Issue #281 -- Updated unit tests with missing assertions.
+#416 by xeno6696 was merged on Aug 11, 2017 -- Issue #278 -- Added default local to date test to avoid non-us unit t…
+#418 by xeno6696 was merged on Aug 11, 2017 -- Issue #281 -- added windows escape char to blacklist in SafeFile to a…
+#419 by xeno6696 was merged on Aug 21, 2017 -- Catching up ESAPI.properties prod and test version.
+#420 by xeno6696 was merged on Aug 26, 2017 -- Issue #284 -- Restored original canonicalization behavior due to issu…
+#421 by xeno6696 was merged on Aug 26, 2017 -- Adding mocking frameworks for testing. Also added joda-time in preparation for date fixes.
+ [Note: A later PR removed joda-time, as it was not really needed.]
+#426 by NiklasMehner was merged on Nov 6, 2017 -- Fix configuration loading: Use value instead of constants also update vulnerable dependencies
+#428 by JoelRabinovitch was merged on Nov 26, 2017 -- Fixed the encoderForLDAP method to use a "switch" statement as was suggested by the maintainer.
+#430 by kwwall was merged on Feb 22, 2018 -- Close issue #429.
+#431 by jeremiahjstacey was merged on Feb 22, 2018 • Approved -- Jstacey 135
+#434 by xeno6696 was merged on May 13, 2018 -- Moved esapi.tld into the correct resources location. Fixes issues #2…
+#436 by tom-leahy was closed on Aug 27, 2018 -- Add unicode letter/number support for fileName validation enhancement
+#440 by kwwall was merged on Sep 23, 2018 -- Close #439 by racheting down default allowed file suffixes used with file uploads
+#441 by kwwall was merged on Sep 23, 2018 -- Close #438 by loosening JUnit test case assertion
+#443 by kwwall was merged on Sep 23, 2018 -- Issue 442
+#446 by jeremiahjstacey was merged on Sep 26, 2018 -- Issue #129 SLF4J Logging Structures
+#449 by kwwall was merged on Oct 8, 2018 -- Close issue #448
+#450 by kwwall was merged on Oct 8, 2018 -- Issue 444
+#451 by kwwall was merged on Oct 8, 2018 -- Log special
+#453 by jackycct was merged on Nov 2, 2018 -- #304 encodeForCSS breaks color values
+#456 by JasperXgwang was closed on Nov 8, 2018 -- fix bug not found in classpath when run with jetty or tomcat
+#459 by simon0117 was merged on Dec 20, 2018 -- Eclipse setup updates
+#460 by simon0117 was closed on Dec 20, 2018 -- ESAPIFilter in RI should allow login page destination to be configured #30
+#464 by kwwall was merged on MMM DD, 2019 -- Misc release cleanup
+#467 by jeremiahjstacey was merged on Jan 06, 2019 -- AuthenticatorTest Stability #360
+#468 by jeremiahjstacey was merged on Jan 22, 2019 -- Date validation rule 299
+#469 by jeremiahjstacey was merged on Jan 15, 2019 -- AbstractAccessReferenceMap Issues #37 #329
+#470 by jeremiahjstacey was merged on Jan 15, 2019 -- JavaLogFactory Thread Safety #286
+#472 by jeremiahjstacey was merged on Jan 21, 2019 -- Issue #31 MySQLCodec Updates
+#475 by jeremiahjstacey was merged on Jan 27, 2019 -- Issue #188 resolution proof: Test updates
+#477 by jeremiajjstacey was merged on Feb 02, 2019 -- $476 DefaultValidator.getValidInput uses canonicalize method argument
+#487 by kwwall was merged on Apr 29, 2019 -- Master branch updates for ESAPI-2.2.0.0-RC2
+#490 by hellyguo was closed on May 12, 2019 -- enhance: cache class and method to avoid reading each time
+#491 by hellyguo was merged on May 27, 2019 -- enhance: improve the performance of ObjFactory
+
+
+List of contributors of *merged* PRs, listed (rather naively) by # of merged PRs:
+ # merged PRs GitHub ID
+ -------------------------
+ 19 xeno6696
+ 10 jeremiahjstacey
+ 9 kwwall
+ 2 artfullyContrived
+ 2 augustd
+ 2 JoelRabinovitch
+ 1 drm2
+ 1 hellyguo
+ 1 jackycct
+ 1 mickilous
+ 1 NiklasMehner
+ 1 simon0117
+ 1 sunnypav
+
+Developer Activity Report (Changes between release 2.1.0.1 and 2.2.0.0, i.e., between 2015-02-05 and 2019-06-09 )
+As created by 'mvn site', however this data was slighty edited to remove email ids replace them with GitHub ids when those were known, or with the developer name.
+Sorted first by # of commits and then by developer id / name..
+
+Developer Total commits Total Number
+ of Files Changed
+=====================================================
+kwwall 362 351
+xeno6696 64 82
+jeremiahjstacey 55 68
+davewichers 7 49
+Anthony Musyoki 4 2
+Kad DEMBELE 4 2
+augustd 3 7
+drmyersii 2 2
+JoelRabinovitch 2 4
+Ben Sleek 1 1
+chrisisbeef 1 5
+hellyguo 1 3
+Jackycct 1 2
+mickilous 1 2
+NiklasMehner 1 2
+Pavan Kumar 1 1
+simon0117 1 3
+taringamberini 1 1
+=====================================================
+Totals: 512 399 (unique files changed)
+
+
+Thanks you all for your time and effort to ESAPI and making it a better project. And if I've missed any, my apologies; let me know and I will correct it.
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+Appendix: Dependency Updates (as reflected in pom.xml)
+
+
+Many 3rd party dependencies had known vulnerabilities (e.g., CVEs reported to NIST's NVD, those reported via VulnDB, BlackDuck, SourceClear, etc.). We have tried to address all those of which we were aware and have updated the dependent 3rd party libraries to (where possible) the latest patched version.
+
+Note that in many places, these 3rd party dependencies were not *direct* dependencies, but rather *transitive* and since we are not able to force a direct 3rd party dependency to update their dependencies, in several cases, we have used Maven's tag to exclude specific transitive dependencies andthen explictly included their latest patched versions that did not cause JUnit test failures.
+
+Because the landscape of known vulnerabilities in 3rd party components is constantly changing and the OWASP ESAPI contributors do not have access to all private vulnerability databases, we may have inevitably missed some. In other cases, we have examined reported vulnerabilities and confirmed that as ESAPI uses and deploys the code in its default configuration, the claimed vulnerabilities are not exploitable.
+
+The following lists all new and updated dependencies. If a dependency is not listed below, the version used since ESAPI release 2.1.0.1 has not changed.
+
+New compile-time / runtime direct dependencies:
+ org.slf4j:slf4j-api:1.7.25 - Not actually needed in your application's classpath unless ESAPI.Logger is configured to use org.owasp.esapi.logging.slf4j.Slf4JLogFactory.
+
+New JUnit dependencies
+ org.bouncycastle:bcprov-jdk15on:1.61
+ org.powermock:powermock-api-mockito2:2.0.0-beta.5
+ org.powermock:powermock-module-junit4:2.0.0-beta.5
+
+Updated direct dependencies, by Maven scope
+ provided:
+ javax.servlet:javax.servlet-api: 2.5 -> 3.0.1
+ javax.servlet.jsp:javax.servlet.jsp-api: 2.0 -> 2.3.3
+
+ compile:
+ commons-fileupload:commons-fileupload: 1.3.1 -> 1.3.3
+ org.apache.commons:commons-collections4: 3.2.2 -> 4.3
+ commons-beanutils:commons-beanutils-core: 1.8.3 -> 1.9.3
+ com.io7m.xom:xom: 1.2.5 -> 1.2.10
+ org.apache-extras.beanshell:bsh: 2.0b4 -> 2.0b6
+ org.owasp.antisamy:antisamy: 1.5.3 -> 1.5.8
+ org.apache.xmlgraphics:batik-css: 1.8 -> 1.11
+
+ Transitive runtime dependencies that ESAPI has now directly taken control off because of known vulnerabilities or other incompatibilities:
+ xalan:xalan: 2.7.0 -> 2.7.2
+ xml-apis:xml-apis: 1.3.03 -> 1.4.01
+ xerces:xercesImpl: 2.8.0 -> 2.12.0
+
+ test:
+ commons-io:commons-io: 2.4 -> 2.6
diff --git a/documentation/esapi4java-core-2.2.1.0-release-notes.txt b/documentation/esapi4java-core-2.2.1.0-release-notes.txt
new file mode 100644
index 000000000..e32e0ad8c
--- /dev/null
+++ b/documentation/esapi4java-core-2.2.1.0-release-notes.txt
@@ -0,0 +1,316 @@
+Release notes for ESAPI 2.2.1.0
+ Release date: 2020-July-12
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.2.0.0, 2019-June-24
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+
+This is a minor release. It's main purpose was to update dependencies to eliminate potential vulnerabilities arising from dependencies with known CVEs. See the section "Changes requiring special attention" below for additional details.
+
+Also special props to Bill Sempf for stepping up and volunteering to prepare the initial cut of these release notes. Had he not done so, this release either would not have release notes or it would have been delayed another 6 months while I procrastinated further with various distractions. (Squirrel!)
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.2.0.0 release:
+ 194 Java source files
+ 4150 JUnit tests in 118 Java source files
+
+ESAPI 2.2.1.0 release:
+ 211 Java source files
+ 4309 JUnit tests in 134 Java source files
+
+39 GitHub Issues closed in this release
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+
+143 - Enhance encodeForOS to auto-detect the underling OS
+173 - DOMConfigurator is being used inappropriately in the ESAPIWebApplicationFirewallFilter
+226 - Javadoc Inaccuracy in getRandomInteger() and getRandomReal()
+232 - SecurityWrapperResponse.createCookieHeader modification request (closed; marked 'wontfix')
+235 - exception is java.lang.NoClassDefFoundError: org.owasp.esapi.codecs.Codec
+245 - KeyDerivationFunction::computeDerivedKey - possible security level mismatch
+256 - Whitespace in JavaEncryptor
+263 - I am getting validation exception while validating a parameter coming from http request
+268 - SecurityWrapperResponse setStatus should not always set SC_OK
+269 - org.owasp.esapi.reference.DefaultValidator reports ValidationException with IE 9
+271 - Add Constructor to DefaultSecurityConfiguration to accept a properties file (1.4)
+276 - Patch for /branches/2.1/src/main/java/org/owasp/esapi/reference/DefaultExecutor.java
+310 - Make HTMLValidationRule to look for antisamy-esapi.xml in classpaths enhancement
+382 - Build Fails on path with space
+465 - Update both ESAPI.properties files to show comment for ESAPI logger support for SLF4J
+488 - Missed a legal input case in DefaultSecurityConfiguration.java
+494 - Encoder's encodeForCSS doesn't handle RGB Triplets
+495 - Maven Install Requires GPG Key
+499 - ValidatorTest.isValidDirectoryPath() has tests that fail under Windows if ESAPI tests run from different drive where Windows installed
+500 - Suppress noise from ESAPI searching for properties and stop ignoring important IOExceptions
+503 - Bug on on referrer header when value contains `§ion` like `www.asdf.com?a=1§ion=2`
+509 - HTMLValidationRule.getValid(String,String) does not follow documented specifications
+511 - Add missing documentation to Validator.addRule() and Validator.getRule()
+512 - Update Apache Commons Bean Utils to 1.9.4
+515 - NullPointerException can result from line 163 of SecurityWrapperRequest.java:
+521 - JUnit test ValidatorTest.testIsValidSafeHTML() now failing
+522 - javadoc corrections for Encoder.canonicalize()
+523 - Links in README to users list and dev list are reversed
+527 - Configuration flag for disabling Logger User and App Information
+530 - Apply default logging content to SLF4J messages
+532 - Update JUL and Log4J code structure and workflow to match SLF4J
+536 - SecurityWrapperResponse setHeader error message is unclear
+538 - Addressing log4j 1.x CVE-2019-17571
+542 - Write up ESAPI release notes for planned 2.2.1.0 release
+552 - Rewrite implementation of some ESAPI classes to remove Java 8 dependencies
+554 - CryptoHelper.arrayCompare() fails with NPE under Java 7 when one of the arguments is null
+555 - JUnit test org.owasp.esapi.reference.AccessControllerTest.testIsAuthorizedForData fails when run against Java 7 on Linux
+556 - Major overhaul to ESAPI Encoder Javadoc based on ESAPI Encoder Usability Study
+558 - ValidatorTest.testIsValidDirectoryPath() JUnit test fails under MacOS
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+The new default ESAPI logger is JUL (java.util.logging packages) and we have deprecated the use of Log4J 1.x because we now support SLF4J and Log4J 1.x is way past its end-of-life. We did not want to make SLF4J the default logger (at least not yet) as we did not want to have the default ESAPI use require additional dependencies. However, SLF4J is likely to be the future choice, at least once we start on ESAPI 3.0. A special shout-out to Jeremiah Stacey for making this possible by re-factoring much of the ESAPI logger code. Note, the straw that broke the proverbial camel's back was the announcement of CVE-2019-17571 (rated Critical), for which there is no fix available and likely will never be.
+
+Related to that CVE and how it affects ESAPI, be sure to read
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin2.pdf
+which describes CVE-2019-17571, a deserialization vulnerability in Log4J 1.2.17. ESAPI is not affected by this (even if you chose to use Log4J 1 as you default ESAPI logger). This security bulletin describes why this CVE is not exploitable as used by ESAPI.
+
+Notable dependency updates (excludes those only used with JUnit tests):
+ antiSamy 1.5.8 -> 1.5.10
+ batik-css 1.11 -> 1.13
+ commons-beansutil 1.9.3 -> 1.9.4
+ slf4j-api 1.7.26 -> 1.7.30
+
+Finally, while ESAPI still supports JDK 7 (even though that too is way past end-of-life), the next ESAPI release will move to JDK 8 as the minimal baseline. (We already use Java 8 for development but still to Java 7 source and runtime compatibility.)
+
+-----------------------------------------------------------------------------
+
+ Known Issues / Problems
+
+-----------------------------------------------------------------------------
+If you use Java 7 (the minimal Java baseline supported by ESAPI) and try to run 'mvn test' there is one test that fails. This test passes with Java 8. The failing test is:
+
+ [ERROR] Tests run: 5, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.203 s
+ <<< FAILURE! - in org.owasp.esapi.crypto.SecurityProviderLoaderTest
+ [ERROR] org.owasp.esapi.crypto.SecurityProviderLoaderTest.testWithBouncyCastle
+ Time elapsed: 0.116 s <<< FAILURE!
+ java.lang.AssertionError: Encryption w/ Bouncy Castle failed with
+ EncryptionException for preferred cipher transformation; exception was:
+ org.owasp.esapi.errors.EncryptionException: Encryption failure (unavailable
+ cipher requested)
+ at
+ org.owasp.esapi.crypto.SecurityProviderLoaderTest.testWithBouncyCastle(Security
+ ProviderLoaderTest.java:133)
+
+I will spare you all the details and tell you that this has to do with Java 7 not being able to correctly parse the signed Bouncy Castle JCE provider jar. More details are available at:
+ https://www.bouncycastle.org/latest_releases.html
+and
+ https://github.com/bcgit/bc-java/issues/477
+I am sure that there are ways of making Bouncy Castle work with Java 7, but since ESAPI does not rely on Bouncy Castle (it can use any compliant JCE provider), this should not be a problem. (It works fine with the default SunJCE provider.) If it is important to get the BC provider working with the ESAPI Encryptor and Java 7, then open a GitHub issue and we will take a deeper look at it and see if we can suggest something.
+
+
+
+Another problem is if you run 'mvn test' from the 'cmd' prompt (and possibly PowerShell as well), you will get intermittent failures (generally between 10-25% of the time) at arbitrary spots. If you run it again without any changes it will work fine without any failures. We have discovered that it doesn't seem to fail if you run the tests from an IDE like Eclipse or if you redirect both stdout and stderr to a file; e.g.,
+
+ C:\code\esapi-java-legacy> mvn test >testoutput.txt 2>&1
+
+We do not know the reason for these failures, but only that we have observed them on Windows 10. If you see this error, please do NOT report it as a GitHub issue unless you know a fix for it.
+
+
+ *** IMPORTANT WORKAROUND for 2.2.1.0 ESAPI Logging ***
+
+Lastly, if you try to use the new ESAPI 2.2.1.0 logging, you will notice that you need to change ESAPI.Logger and also possibly provide some other logging properties as well. This is because the logger packages were reorganized to improve maintainability, but we failed to mention it. To use ESAPI logging in ESAPI 2.2.1.0 (and later), you MUST set the ESAPI.Logger property to one of:
+
+ org.owasp.esapi.logging.java.JavaLogFactory - To use the new default, java.util.logging (JUL)
+ org.owasp.esapi.logging.log4j.Log4JLogFactory - To use the end-of-life Log4J 1.x logger
+ org.owasp.esapi.logging.slf4j.Slf4JLogFactory - To use the new (to release 2.2.0.0) SLF4J logger
+
+In addition, if you wish to use JUL for logging, you *must* supply an "esapi-java-logging.properties" file in your classpath. Unfortunately, we failed to drop add that to the ESAPI configuration jar under the GitHub 'Releases', so this file has been added explicitly to the 2.2.1.0 release 'Assets' for this release (for details, see https://github.com/ESAPI/esapi-java-legacy/releases/esapi-2.2.1.0). Even worse, there was a logic error in the static initializer of JavaLogFactory (now fixed in the 2.2.1.1 patch release) that causes a NullPointerException to be thrown so that the message about the missing "esapi-java-logging.properties" file was never seen.
+
+If you are using JavaLogFactory or Slf4JLogFactory, you will also want to ensure that you have the following ESAPI logging properties set to get the logs to appear what you are used to with Log4J 1.x logging:
+ # Set the application name if these logs are combined with other applications
+ Logger.ApplicationName=ExampleApplication
+ # If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true
+ Logger.LogEncodingRequired=false
+ # Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments.
+ Logger.LogApplicationName=true
+ # Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments.
+ Logger.LogServerIP=true
+ # LogFileName, the name of the logging file. Provide a full directory path (e.g., C:\\ESAPI\\ESAPI_logging_file) if you
+ # want to place it in a specific directory.
+ Logger.LogFileName=ESAPI_logging_file
+ # MaxLogFileSize, the max size (in bytes) of a single log file before it cuts over to a new one (default is 10,000,000)
+ Logger.MaxLogFileSize=10000000
+ # Determines whether ESAPI should log the user info.
+ Logger.UserInfo=true
+ # Determines whether ESAPI should log the session id and client IP.
+ Logger.ClientInfo=true
+
+See GitHub issue #560 for additional details.
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+Documentation updates for locating Jar files
+Unneeded code removed from ExtensiveEncoderURI test
+Inline reader added to ExtensiveEncoder
+Additional time for windows to always sleep more than given seconds in CryptoTokenTest
+Change required by tweak to CipherText.toString() method
+Removed call to deprecated CryptoHelper.computeDerivedKey() method
+New JUnit tests for org.owasp.esapi.crypto.KeyDerivationFunction class
+Miscellaneous documentation and tests
+JavaLogger moved to new package
+Log4J 1.x no longer ESAPI's default logger
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.2.0.0 and 2.2.1.0, i.e., between 2019-06-25 and 2020-07-11)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+========================================================
+davewichers 2 1 0
+HJW8472 11 8 1
+jeremiahjstacey 78 70 6
+kwwall 67 64 8
+Michael-Ziluck 3 2 2
+sempf 1 1 1
+wiitek 6 4 2
+xeno6696 3 5 1
+========================================================
+ Total: 21
+
+
+-----------------------------------------------------------------------------
+
+
+21 Closed PRs merged since 2.2.0.0 release (those rejected not listed)
+======================================================================
+PR# GitHub ID Description
+----------------------------------------------------------------------
+504 -- kwwall -- New scripts to suppress noise for 'mvn test'
+505 -- kwwall -- Close issue #256. White-space clean up.
+506 -- kwwall -- Closes Issue 245
+508 -- Michael-Ziluck -- Resolves #226 - Corrected docs for the bounded, numeric, random methods
+510 -- Michael-Ziluck -- Resolve #509 - Properly throw exception when HTML fails
+513 -- kwwall -- Close issue #512 by updating to 1.9.4 of Commons Beans Util.
+514 -- xeno6696 -- Fixed issues #503 by writing a new addReferer method, also temporarily…
+516 -- jeremiahjstacey -- Issue 515
+518 -- jeremiahjstacey -- Issue #511 Copying Docs from DefaultValidator
+519 -- jeremiahjstacey -- Issue 494 CSSCodec RGB Triplets
+520 -- jeremiahjstacey -- OS Name DefaultExecutorTests #143
+533 -- jeremiahjstacey -- #532 JUL and Log4J match SLF4J class structure and Workflow
+535 -- kwwall -- Issue 521
+537 -- jeremiahjstacey -- Issue 536
+539 -- wiiitek -- upgrade for convergence
+540 -- wiiitek -- Issue 382: Build Fails on path with space
+541 -- HJW8472 -- Fixed issue #310
+543 -- sempf -- Release notes for 2.2.1.0
+551 -- kwwall -- Misc cleanup
+553 -- kwwall -- Fix for GitHub Issue 552
+557 -- kwwall -- Final prep for 2.2.1.0 release
+
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --since=2019-06-25 --reverse --pretty=medium
+
+ which will show all the commits since just after the last (2.2.0.0) release.
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn dependency:tree
+ [INFO] Scanning for projects...
+ [INFO]
+ [INFO] -----------------------< org.owasp.esapi:esapi >------------------------
+ [INFO] Building ESAPI 2.2.1.0
+ [INFO] --------------------------------[ jar ]---------------------------------
+ [INFO]
+ [INFO] --- maven-dependency-plugin:3.1.2:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.2.1.0
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.0.1:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- com.io7m.xom:xom:jar:1.2.10:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.3.3:compile
+ [INFO] +- log4j:log4j:jar:1.2.17:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.5.10:compile
+ [INFO] | +- net.sourceforge.nekohtml:nekohtml:jar:1.9.22:compile
+ [INFO] | +- org.apache.httpcomponents:httpclient:jar:4.5.12:compile
+ [INFO] | | \- org.apache.httpcomponents:httpcore:jar:4.4.13:compile
+ [INFO] | \- commons-codec:commons-codec:jar:1.14:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:1.7.30:compile
+ [INFO] +- commons-io:commons-io:jar:2.6:compile
+ [INFO] +- org.apache.xmlgraphics:batik-css:jar:1.13:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.13:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-util:jar:1.13:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-constants:jar:1.13:compile
+ [INFO] | | \- org.apache.xmlgraphics:batik-i18n:jar:1.13:compile
+ [INFO] | +- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.4:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- xalan:xalan:jar:2.7.2:compile
+ [INFO] | \- xalan:serializer:jar:2.7.2:compile
+ [INFO] +- xerces:xercesImpl:jar:2.12.0:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.0.4:compile (optional)
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile (optional)
+ [INFO] +- net.jcip:jcip-annotations:jar:1.0:compile (optional)
+ [INFO] +- junit:junit:jar:4.13:test
+ [INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.65.01:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-core:jar:2.0.7:test
+ [INFO] +- org.javassist:javassist:jar:3.25.0-GA:test
+ [INFO] +- org.mockito:mockito-core:jar:2.28.2:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.9.10:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.9.10:test
+ [INFO] | \- org.objenesis:objenesis:jar:2.6:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.7:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.7:test
+ [INFO] +- org.openjdk.jmh:jmh-core:jar:1.23:test
+ [INFO] | +- net.sf.jopt-simple:jopt-simple:jar:4.6:test
+ [INFO] | \- org.apache.commons:commons-math3:jar:3.2:test
+ [INFO] \- org.openjdk.jmh:jmh-generator-annprocess:jar:1.23:test
+ [INFO] ------------------------------------------------------------------------
+ [INFO] BUILD SUCCESS
+ [INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+
+ Release notes written by Bill Sempf (bill.sempf@owasp.org), but please direct any communication to the project leaders.
+
+Special shout-outs to:
+ Jeremiah Stacey (jeremiahjstacey) -- All around ESAPI support and JUnit test case developer extraordinaire and for refactoring ESAPI loggers.
+ Dave Wichers (davewichers) - for several extremely useful pom.xml improvements.
+ Bill Sempf (sempf) -- for these release notes. Awesome job, Bill. I owe you a brew.
+ Chamila Wijayarathna and Nalin A. G. Arachchilage for their authorship and subsequent extensive discussion of their paper "Fighting Against XSS Attacks: A Usability Evaluation of OWASP ESAPI Output Encoding" (https://scholarspace.manoa.hawaii.edu/bitstream/10125/60167/0727.pdf). Their paper and their willingness to engage with me to discuss it was what led to the (hopefully) improved Javadoc for the ESAPI Encoder interface.
+ And lastly a special thanks to first-time contributors Michael-Ziluck, wiiitek, and HJW8472.
+
+Thanks you all for your time and effort to ESAPI and making it a better project. And if I've missed any, my apologies; let me know and I will correct it.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.2.1.1-release-notes.txt b/documentation/esapi4java-core-2.2.1.1-release-notes.txt
new file mode 100644
index 000000000..4670706f7
--- /dev/null
+++ b/documentation/esapi4java-core-2.2.1.1-release-notes.txt
@@ -0,0 +1,237 @@
+Release notes for ESAPI 2.2.1.1
+ Release date: 2020-July-26
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.2.1.0, 2020-July-12
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+
+This is a patch release to address GitHub issue #560. See that GitHub issue and
+
+Also special props to Bill Sempf for stepping up and volunteering to prepare the initial cut of these release notes. Had he not done so, this release either would not have release notes or it would have been delayed another 6 months while I procrastinated further with various distractions. (Squirrel!)
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.2.1.0 release:
+ 211 Java source files
+ 4309 JUnit tests in 134 Java source files
+
+ESAPI 2.2.1.1 release:
+ 211 Java source files
+ 4312 JUnit tests in 134 Java source files
+
+39 GitHub Issues closed in this release
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+
+560 - Could not initialize class org.owasp.esapi.logging.java.JavaLogFactory (ESAPI 2.2.1.0)
+561 - Update ESAPI-release-steps.odt to note how to do 'Release' on GitHub
+564 - Create release notes for 2.2.1.1 patch release
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+As of ESAPI 2.2.1.0 (the previous release), the new default ESAPI logger is JUL (java.util.logging packages) and we have deprecated the use of Log4J 1.x because we now support SLF4J and Log4J 1.x is way past its end-of-life. We did not want to make SLF4J the default logger (at least not yet) as we did not want to have the default ESAPI use require additional dependencies. However, SLF4J is likely to be the future choice, at least once we start on ESAPI 3.0. A special shout-out to Jeremiah Stacey for making this possible by re-factoring much of the ESAPI logger code. Note, the straw that broke the proverbial camel's back was the announcement of CVE-2019-17571 (rated Critical), for which there is no fix available and likely will never be.
+
+However, if you try to juse the new ESAPI 2.2.1.0 logging you will notice that you need to change ESAPI.Logger and also possibly provide some other properties as well to get the logging behavior that you desire.
+
+To use ESAPI logging in ESAPI 2.2.1.0 (and later), you will need to set the ESAPI.Logger property to
+
+ org.owasp.esapi.logging.java.JavaLogFactory - To use the new default, java.util.logging (JUL)
+ org.owasp.esapi.logging.log4j.Log4JLogFactory - To use the end-of-life Log4J 1.x logger
+ org.owasp.esapi.logging.slf4j.Slf4JLogFactory - To use the new (to release 2.2.0.0) SLF4J logger
+
+In addition, if you wish to use JUL for logging, you *MUST* supply an "esapi-java-logging.properties" file in your classpath. This file is included in the 'esapi-2.2.1.1-configuration.jar' file provided under the 'Assets' section of the GitHub Release at
+ https://github.com/ESAPI/esapi-java-legacy/releases/esapi-2.2.1.1
+
+Unfortunately, there was a logic error in the static initializer of JavaLogFactory (now fixed in this release) that caused a NullPointerException to be thrown so that the message about the missing "esapi-java-logging.properties" file was never seen.
+
+If you are using JavaLogFactory, you will also want to ensure that you have the following ESAPI logging properties set:
+ # Set the application name if these logs are combined with other applications
+ Logger.ApplicationName=ExampleApplication
+ # If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true
+ Logger.LogEncodingRequired=false
+ # Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments.
+ Logger.LogApplicationName=true
+ # Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments.
+ Logger.LogServerIP=true
+ # LogFileName, the name of the logging file. Provide a full directory path (e.g., C:\\ESAPI\\ESAPI_logging_file) if you
+ # want to place it in a specific directory.
+ Logger.LogFileName=ESAPI_logging_file
+ # MaxLogFileSize, the max size (in bytes) of a single log file before it cuts over to a new one (default is 10,000,000)
+ Logger.MaxLogFileSize=10000000
+ # Determines whether ESAPI should log the user info.
+ Logger.UserInfo=true
+ # Determines whether ESAPI should log the session id and client IP.
+ Logger.ClientInfo=true
+
+See GitHub issue #560 for additional details.
+
+
+Related to that aforemented Log4J 1.x CVE and how it affects ESAPI, be sure to read
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin2.pdf
+which describes CVE-2019-17571, a deserialization vulnerability in Log4J 1.2.17. ESAPI is *NOT* affected by this (even if you chose to use Log4J 1 as you default ESAPI logger). This security bulletin describes why this CVE is not exploitable as used by ESAPI.
+
+
+Finally, while ESAPI still supports JDK 7 (even though that too is way past end-of-life), the next ESAPI release will move to JDK 8 as the minimal baseline. (We already use Java 8 for development but still to Java 7 source and runtime compatibility.)
+
+-----------------------------------------------------------------------------
+
+ Known Issues / Problems
+
+-----------------------------------------------------------------------------
+If you use Java 7 (the minimal Java baseline supported by ESAPI) and try to run 'mvn test' there is one test that fails. This test passes with Java 8. The failing test is:
+
+ [ERROR] Tests run: 5, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.203 s
+ <<< FAILURE! - in org.owasp.esapi.crypto.SecurityProviderLoaderTest
+ [ERROR] org.owasp.esapi.crypto.SecurityProviderLoaderTest.testWithBouncyCastle
+ Time elapsed: 0.116 s <<< FAILURE!
+ java.lang.AssertionError: Encryption w/ Bouncy Castle failed with
+ EncryptionException for preferred cipher transformation; exception was:
+ org.owasp.esapi.errors.EncryptionException: Encryption failure (unavailable
+ cipher requested)
+ at
+ org.owasp.esapi.crypto.SecurityProviderLoaderTest.testWithBouncyCastle(Security
+ ProviderLoaderTest.java:133)
+
+I will spare you all the details and tell you that this has to do with Java 7 not being able to correctly parse the signed Bouncy Castle JCE provider jar. More details are available at:
+ https://www.bouncycastle.org/latest_releases.html
+and
+ https://github.com/bcgit/bc-java/issues/477
+I am sure that there are ways of making Bouncy Castle work with Java 7, but since ESAPI does not rely on Bouncy Castle (it can use any compliant JCE provider), this should not be a problem. (It works fine with the default SunJCE provider.) If it is important to get the BC provider working with the ESAPI Encryptor and Java 7, then open a GitHub issue and we will take a deeper look at it and see if we can suggest something.
+
+
+
+Another problem is if you run 'mvn test' from the 'cmd' prompt (and possibly PowerShell as well), you will get intermittent failures (generally between 10-25% of the time) at arbitrary spots. If you run it again without any changes it will work fine without any failures. We have discovered that it doesn't seem to fail if you run the tests from an IDE like Eclipse or if you redirect both stdout and stderr to a file; e.g.,
+
+ C:\code\esapi-java-legacy> mvn test >testoutput.txt 2>&1
+
+We do not know the reason for these failures, but only that we have observed them on Windows 10. If you see this error, please do NOT report it as a GitHub issue unless you know a fix for it.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Updates to README.md fileg
+* Minor Javadoc fixes to org.owasp.esapi.Encoder
+* Fixes / cleanup to 2.2.1.0 release notes (documentation/esapi4java-core-2.2.1.0-release-notes.txt)
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.2.1.0 and 2.2.1.1, i.e., between 2020-07-12 and 2020-07-26)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+========================================================
+jeremiahjstacey 5 5 1
+kwwall 67 64 8
+========================================================
+ Total: 21
+
+
+-----------------------------------------------------------------------------
+
+
+2 Closed PRs merged since 2.2.1.0 release (those rejected not listed)
+======================================================================
+PR# GitHub ID Description
+----------------------------------------------------------------------
+559 -- synk-bot -- Upgrade com.github.spotbugs:spotbugs-annotations from 4.0.4 to 4.0.5
+562 -- jeremiahjstacey -- Issue #560 JUL fixes
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --since=2020-07-13 --reverse --pretty=medium
+
+ which will show all the commits since just after the last (2.2.1.0) release.
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn dependency:tree
+ [INFO] Scanning for projects...
+ [INFO]
+ [INFO] -----------------------< org.owasp.esapi:esapi >------------------------
+ [INFO] Building ESAPI 2.2.1.1
+ [INFO] --------------------------------[ jar ]---------------------------------
+ [INFO]
+ [INFO] --- maven-dependency-plugin:3.1.2:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.2.1.1
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.0.1:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- com.io7m.xom:xom:jar:1.2.10:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.3.3:compile
+ [INFO] +- log4j:log4j:jar:1.2.17:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.5.10:compile
+ [INFO] | +- net.sourceforge.nekohtml:nekohtml:jar:1.9.22:compile
+ [INFO] | +- org.apache.httpcomponents:httpclient:jar:4.5.12:compile
+ [INFO] | | \- org.apache.httpcomponents:httpcore:jar:4.4.13:compile
+ [INFO] | \- commons-codec:commons-codec:jar:1.14:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:1.7.30:compile
+ [INFO] +- commons-io:commons-io:jar:2.6:compile
+ [INFO] +- org.apache.xmlgraphics:batik-css:jar:1.13:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.13:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-util:jar:1.13:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-constants:jar:1.13:compile
+ [INFO] | | \- org.apache.xmlgraphics:batik-i18n:jar:1.13:compile
+ [INFO] | +- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.4:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- xalan:xalan:jar:2.7.2:compile
+ [INFO] | \- xalan:serializer:jar:2.7.2:compile
+ [INFO] +- xerces:xercesImpl:jar:2.12.0:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.0.5:compile (optional)
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile (optional)
+ [INFO] +- net.jcip:jcip-annotations:jar:1.0:compile (optional)
+ [INFO] +- junit:junit:jar:4.13:test
+ [INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.65.01:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-core:jar:2.0.7:test
+ [INFO] +- org.javassist:javassist:jar:3.25.0-GA:test
+ [INFO] +- org.mockito:mockito-core:jar:2.28.2:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.9.10:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.9.10:test
+ [INFO] | \- org.objenesis:objenesis:jar:2.6:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.7:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.7:test
+ [INFO] +- org.openjdk.jmh:jmh-core:jar:1.23:test
+ [INFO] | +- net.sf.jopt-simple:jopt-simple:jar:4.6:test
+ [INFO] | \- org.apache.commons:commons-math3:jar:3.2:test
+ [INFO] \- org.openjdk.jmh:jmh-generator-annprocess:jar:1.23:test
+ [INFO] ------------------------------------------------------------------------
+ [INFO] BUILD SUCCESS
+ [INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+
+elangoravi for bringing GitHub issue #560 to our attention. This is one where we thought the workaround instructions was harder than just trying to fix it and thus we were encouraged to release a patch.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.2.2.0-release-notes.txt b/documentation/esapi4java-core-2.2.2.0-release-notes.txt
new file mode 100644
index 000000000..833d1b94e
--- /dev/null
+++ b/documentation/esapi4java-core-2.2.2.0-release-notes.txt
@@ -0,0 +1,250 @@
+Release notes for ESAPI 2.2.2.0
+ Release date: 2020-November-27
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.2.1.1, 2020-July-26
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+
+This is a patch release with the primary intent of updating some dependencies with known vulnerabilities. The main vulnerability that was remediated was CVE-2020-13956, which was a vulnerability introduced through the ESAPI transitive dependency org.apache.httpcomponents:httpclient:4.5.12, potentially exposed through org.owasp.antisamy:antisamy:1.5.10. Updating to AntiSamy 1.5.11 remediated that issue. In addition, that update to AntiSamy 1.5.11 also addressed AntiSamy issue #48 (https://github.com/nahsra/antisamy/issues/48), which was a low risk security issue that potentially could be exposed via phishing.
+
+For those of you using a Software Configuration Analysis (SCA) services such as Snyk, BlackDuck, Veracode SourceClear, OWASP Dependency Check, etc., you might notice that there is vulnerability in xerces:xercesImpl:2.12.0 that ESAPI uses (also a transitive dependency) that is similar to CVE-2020-14621. Unfortunately there is no official patch for this in the regular Maven Central repository. Further details are described in Security Bulletin #3, which is viewable here
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin3.pdf
+and associated with this release on GitHub. Manual workarounds possible. See the security bulletin for further details.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.2.1.1 release:
+ 211 Java source files
+ 4312 JUnit tests in 134 Java source files
+
+ESAPI 2.2.2.0 release:
+ 212 Java source files
+ 4313 JUnit tests in 135 Java source files
+
+10 GitHub Issues closed in this release, including those we've decided not to fix (marked '(wontfix)').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2020-07-26)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+303 - HTMLEntityCodec destroys 32-bit CJK (Chinese, Japanese and Korean) characters
+561 - Update ESAPI-release-steps.odt to note how to do 'Release' on GitHub
+566 - API doc comments are not shown when using ESAPI in Intellij Idea (wontfix)
+567 - Release 2.2.1.1 Not Loading Properties in dependant JARs
+568 - encoder-esapi is not aware of changes in esapi 2.2.1.1, making it to crash (wontfix)
+569 - Unable to print the proper package and method name
+571 - Logger.always() fails to log all the time when ESAPI is using org.owasp.esapi.logging.java.JavaLogFactory
+574 - Multiple encoding issue for Google Chrome
+577 - ESAPI decodes html entities without trailing ';'
+581 - Updates to pom.xml to update AntiSamy and other dependencies
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+[If you have already successfully been using ESAPI 2.2.1.0 or later, you probably can skip this section.]
+
+Since ESAPI 2.2.1.0, the new default ESAPI logger is JUL (java.util.logging packages) and we have deprecated the use of Log4J 1.x because we now support SLF4J and Log4J 1.x is way past its end-of-life. We did not want to make SLF4J the default logger (at least not yet) as we did not want to have the default ESAPI use require additional dependencies. However, SLF4J is likely to be the future choice, at least once we start on ESAPI 3.0. A special shout-out to Jeremiah Stacey for making this possible by re-factoring much of the ESAPI logger code. Note, the straw that broke the proverbial camel's back was the announcement of CVE-2019-17571 (rated Critical), for which there is no fix available and likely will never be.
+
+However, if you try to juse the new ESAPI 2.2.1.0 or later logging you will notice that you need to change ESAPI.Logger and also possibly provide some other properties as well to get the logging behavior that you desire.
+
+To use ESAPI logging in ESAPI 2.2.1.0 (and later), you will need to set the ESAPI.Logger property to
+
+ org.owasp.esapi.logging.java.JavaLogFactory - To use the new default, java.util.logging (JUL)
+ org.owasp.esapi.logging.log4j.Log4JLogFactory - To use the end-of-life Log4J 1.x logger
+ org.owasp.esapi.logging.slf4j.Slf4JLogFactory - To use the new (to release 2.2.0.0) SLF4J logger
+
+In addition, if you wish to use JUL for logging, you *MUST* supply an "esapi-java-logging.properties" file in your classpath. This file is included in the 'esapi-2.2.2.0-configuration.jar' file provided under the 'Assets' section of the GitHub Release at
+ https://github.com/ESAPI/esapi-java-legacy/releases/esapi-2.2.2.0
+
+Unfortunately, there was a logic error in the static initializer of JavaLogFactory (now fixed in this release) that caused a NullPointerException to be thrown so that the message about the missing "esapi-java-logging.properties" file was never seen.
+
+If you are using JavaLogFactory, you will also want to ensure that you have the following ESAPI logging properties set:
+ # Set the application name if these logs are combined with other applications
+ Logger.ApplicationName=ExampleApplication
+ # If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true
+ Logger.LogEncodingRequired=false
+ # Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments.
+ Logger.LogApplicationName=true
+ # Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments.
+ Logger.LogServerIP=true
+ # LogFileName, the name of the logging file. Provide a full directory path (e.g., C:\\ESAPI\\ESAPI_logging_file) if you
+ # want to place it in a specific directory.
+ Logger.LogFileName=ESAPI_logging_file
+ # MaxLogFileSize, the max size (in bytes) of a single log file before it cuts over to a new one (default is 10,000,000)
+ Logger.MaxLogFileSize=10000000
+ # Determines whether ESAPI should log the user info.
+ Logger.UserInfo=true
+ # Determines whether ESAPI should log the session id and client IP.
+ Logger.ClientInfo=true
+
+See GitHub issue #560 for additional details.
+
+
+Related to that aforemented Log4J 1.x CVE and how it affects ESAPI, be sure to read
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin2.pdf
+which describes CVE-2019-17571, a deserialization vulnerability in Log4J 1.2.17. ESAPI is *NOT* affected by this (even if you chose to use Log4J 1 as you default ESAPI logger). This security bulletin describes why this CVE is not exploitable as used by ESAPI.
+
+
+Finally, while ESAPI still supports JDK 7 (even though that too is way past end-of-life), the next ESAPI release will move to JDK 8 as the minimal baseline. (We already use Java 8 for development but still to Java 7 source and runtime compatibility.)
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+If you use Java 7 (the minimal Java baseline supported by ESAPI) and try to run 'mvn test' there is one test that fails. This test passes with Java 8. The failing test is:
+
+ [ERROR] Tests run: 5, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.203 s
+ <<< FAILURE! - in org.owasp.esapi.crypto.SecurityProviderLoaderTest
+ [ERROR] org.owasp.esapi.crypto.SecurityProviderLoaderTest.testWithBouncyCastle
+ Time elapsed: 0.116 s <<< FAILURE!
+ java.lang.AssertionError: Encryption w/ Bouncy Castle failed with
+ EncryptionException for preferred cipher transformation; exception was:
+ org.owasp.esapi.errors.EncryptionException: Encryption failure (unavailable
+ cipher requested)
+ at
+ org.owasp.esapi.crypto.SecurityProviderLoaderTest.testWithBouncyCastle(Security
+ ProviderLoaderTest.java:133)
+
+I will spare you all the details and tell you that this has to do with Java 7 not being able to correctly parse the signed Bouncy Castle JCE provider jar. More details are available at:
+ https://www.bouncycastle.org/latest_releases.html
+and
+ https://github.com/bcgit/bc-java/issues/477
+I am sure that there are ways of making Bouncy Castle work with Java 7, but since ESAPI does not rely on Bouncy Castle (it can use any compliant JCE provider), this should not be a problem. (It works fine with the default SunJCE provider.) If it is important to get the BC provider working with the ESAPI Encryptor and Java 7, then open a GitHub issue and we will take a deeper look at it and see if we can suggest something.
+
+
+
+Another problem is if you run 'mvn test' from the 'cmd' prompt (and possibly PowerShell as well), you will get intermittent failures (generally between 10-25% of the time) at arbitrary spots. If you run it again without any changes it will work fine without any failures. We have discovered that it doesn't seem to fail if you run the tests from an IDE like Eclipse or if you redirect both stdout and stderr to a file; e.g.,
+
+ C:\code\esapi-java-legacy> mvn test >testoutput.txt 2>&1
+
+We do not know the reason for these failures, but only that we have observed them on Windows 10. If you see this error, please do NOT report it as a GitHub issue unless you know a fix for it.
+
+
+Lastly, some SCA services may continue to flag vulnerabilties in ESAPI 2.2.2.0 related to log4j 1.2.17 and xerces 2.12.0. We do not believe the way that ESAPI uses either of these in a manner that leads to any exploitable behavior. See the security bulletins
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin2.pdf
+and
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin3.pdf
+respectively, for additional details.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Minor updates to README.md file
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.2.1.1 and 2.2.2.0, i.e., between 2020-07-26 and 2020-11-27)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+========================================================
+jeremiahjstacey 8 6 1
+dependabot 1 1 1
+kwwall 7 8 0
+========================================================
+ Total PRs: 2
+
+There were also several snyk-bot PRs that were rejected for various reasons, mostly because 1) I was already making the proposed changes and preferred to do them in single commit or 2) there were other reasons for rejecting them (such as the dependency requiring Java 8). The proposed changes that were not outright rejected were included as part of commit a8a79bc5196653500ce664b7b063284e60bddaa0.
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2020-07-26 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.2.1.1) release.
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn dependency:tree
+ [INFO] Scanning for projects...
+ [INFO]
+ [INFO] -----------------------< org.owasp.esapi:esapi >------------------------
+ [INFO] Building ESAPI 2.2.2.0
+ [INFO] --------------------------------[ jar ]---------------------------------
+ [INFO]
+ [INFO] --- maven-dependency-plugin:3.1.2:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.2.2.0-SNAPSHOT
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.0.1:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- com.io7m.xom:xom:jar:1.2.10:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.3.3:compile
+ [INFO] +- log4j:log4j:jar:1.2.17:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.5.11:compile
+ [INFO] | +- net.sourceforge.nekohtml:nekohtml:jar:1.9.22:compile
+ [INFO] | +- org.apache.httpcomponents:httpclient:jar:4.5.13:compile
+ [INFO] | | \- org.apache.httpcomponents:httpcore:jar:4.4.13:compile
+ [INFO] | \- commons-codec:commons-codec:jar:1.15:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:1.7.30:compile
+ [INFO] +- commons-io:commons-io:jar:2.6:compile
+ [INFO] +- org.apache.xmlgraphics:batik-css:jar:1.13:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.13:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-util:jar:1.13:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-constants:jar:1.13:compile
+ [INFO] | | \- org.apache.xmlgraphics:batik-i18n:jar:1.13:compile
+ [INFO] | +- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.4:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- xalan:xalan:jar:2.7.2:compile
+ [INFO] | \- xalan:serializer:jar:2.7.2:compile
+ [INFO] +- xerces:xercesImpl:jar:2.12.0:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.1.4:compile (optional)
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile (optional)
+ [INFO] +- net.jcip:jcip-annotations:jar:1.0:compile (optional)
+ [INFO] +- junit:junit:jar:4.13.1:test
+ [INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.65.01:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-core:jar:2.0.7:test
+ [INFO] +- org.javassist:javassist:jar:3.25.0-GA:test
+ [INFO] +- org.mockito:mockito-core:jar:2.28.2:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.9.10:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.9.10:test
+ [INFO] | \- org.objenesis:objenesis:jar:2.6:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.7:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.7:test
+ [INFO] +- org.openjdk.jmh:jmh-core:jar:1.23:test
+ [INFO] | +- net.sf.jopt-simple:jopt-simple:jar:4.6:test
+ [INFO] | \- org.apache.commons:commons-math3:jar:3.2:test
+ [INFO] \- org.openjdk.jmh:jmh-generator-annprocess:jar:1.23:test
+ [INFO] ------------------------------------------------------------------------
+ [INFO] BUILD SUCCESS
+ [INFO] ------------------------------------------------------------------------
+ [INFO] Total time: 0.749 s
+ [INFO] Finished at: 2020-11-25T16:55:26-05:00
+ [INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ Another hat tip to Dave Wichers for promptly releasing AntiSamy 1.5.11. And thanks to Matt Seil, Jeremiah Stacey, and Dave for reviewing these boring release notes and Security Bulletin #3. Despite their assistance, I take full responsibility for any errors.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.2.3.0-release-notes.txt b/documentation/esapi4java-core-2.2.3.0-release-notes.txt
new file mode 100644
index 000000000..1b96a6657
--- /dev/null
+++ b/documentation/esapi4java-core-2.2.3.0-release-notes.txt
@@ -0,0 +1,288 @@
+Release notes for ESAPI 2.2.3.0
+ Release date: 2021-03-23
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.2.2.0, 2020-11-27
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+
+Important news for this current release
+---------------------------------------
+This is a patch release with the primary intent of updating some dependencies, some with known vulnerabilities. Main update are:
+ -- AntiSamy, from 1.5.11 to 1.6.2.
+ -- As a result of the AntiSamy upgrade, the transitive dependency xercesImpl was updated from 2.12.0 to 2.12.1 which should address CVE-2020-14338.
+ -- Apache batik-css, updated from 1.13 to 1.14.
+
+Details follow.
+
+ * IMPORTANT: Effects of updating to AntiSamy 1.6.2
+ - AntiSamy 1.6.2 which we are now using, is not doing XML schema validation of AntiSamy policy files. It is IMPORTANT that you read through
+ https://github.com/nahsra/antisamy#note-schema-validation-behavior-change-starting-with-antisamy-160
+ to know how that affects you as an ESAPI user. In particular, changes important to ESAPI users include:
+ o AntiSamy now includes the dependency 'slf4j-simple'. This means if you are using an SLF4J library *other* than that, you should add
+
+ org.slf4j
+ slf4j-simple
+
+ in your dependency for ESAPI in your application's pom.xml. (You Gradle, Ivy, etc. other build tool users will have to figure out how to do this yourself.)
+ This is especially important if you are using SLF4J logging in ESAPI with some other SLF4J logger such as slf4j-log4j2, etc. If you don't do that, your logging may not come out as expected. See , under its section discussing Logging for more details.
+
+ o Previously, ESAPI shipped with a default AntiSamy policy file called 'antisamy-esapi.xml'. For 10 plus years, unbeknownst to anyone, that file contained an unused '' node that not only did ESAPI not directly used, but was also completely ignored by AntiSamy! However, starting with AntiSamy 1.6.0, AntiSamy does XML schema validation by default, so that causes any non-compliant AntiSamy policy file to be rejected. This may result in some rather obtuse error messages and you may want to set the AntiSamy system property 'owasp.validator.validateschema' to "false" temporarily until you have time to correct your AntiSamy policy file(s).
+
+ Old News
+ --------
+ * For those of you using a Software Configuration Analysis (SCA) services such as Snyk, BlackDuck, Veracode's SourceClear, OWASP Dependency Check, etc., you will get a notice for CVE-2020-9488 (related to log4j 1.2.17) and you might get a notice that there is still a vulnerability in xerces:xercesImpl:2.12.1 that ESAPI uses (as a transitive dependency of AntiSamy) that is identical or similar to CVE-2020-14338. (A certain SCA service, which I won't mention, referred to CVE-2020-14621, but it's certainly not obvious from the description that this has anything to do with Xerces. But, on the hand, this is for Oracle products, and they are more obtuse than most when it comes to their vulnerability descriptions.) Unfortunately there is no official patch for the former CVE-2020-9488, as log4j 1.x is now well past its end-of-life. And for the latter CVE(s), it (they?) supposedly is (are?) fixed in the 2.12.1 release, but based on the CPEs in NVD for CVE-2020-14621, it's not clear if all SCA services would detect that.
+ Further details of these vulnerabilities and there potential impact on ESAPI are analyzed in ESAPI Security Advisories #2, #3 and #3, which are viewable here
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin2.pdf -- The Log4j 1.x CVE
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin3.pdf -- The XercesImpl CVE
+ https://pastebin.com/Pm6AbcF7 (A somewhat more in-depth analysis that late to security bulletin #3.)
+ *NEW* -- https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin3.pdf -- Another Log4j 1.x CVE
+ and associated with this release on GitHub. Manual workarounds possible for each. See the security bulletin for further details.
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.2.2.0 release:
+ 212 Java source files
+ 4313 JUnit tests in 135 Java source files
+
+ESAPI 2.2.3.0 release:
+ 212 Java source files
+ 4316 JUnit tests in 136 Java source files
+
+12 GitHub Issues closed in this release, including those we've decided not to fix (marked '(wontfix)').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2020-11-27)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+408 Update Travis CI configuration
+517 Encoded input is not treated as an attack
+586 Upgrade pom.xml to use AntiSamy 1.5.12 Vulnerable Dependencies
+588 Possible bug in StringValidationRule.getValid with canonicalize
+592 Not able to turn off Java.util.Logging for ESAPI
+593 Logger.LogLevel in ESAPI.properties not working if set to ERROR/FATAL
+594 Not able to turn off ESAPI logging
+599 encodeForCSS changes '#' character after upgrading from 2.0.1 to 2.2.1.1
+602 Update failing ValidatorTest in 'Java CI with Maven' GitHub workflow
+606 Vulnerability in transitive dependency of esapi
+609 Change log4j dependency scope to provided Build-Maven Component-Docs Component-Logger Configuration
+614 Potentlial XXE Injection vulnerability in loading XML version of ESAPI properties file
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+
+Search for 'IMPORTANT: Effects of updating to AntiSamy 1.6.2' and read that section. The details are all covered there.
+
+
+Old News -- Important Logging Changes
+-------------------------------------
+[If you have already successfully been using ESAPI 2.2.1.0 or later, you probably can skip this section, which discusses important logging changes.]
+
+Since ESAPI 2.2.1.0, the new default ESAPI logger is JUL (java.util.logging packages) and we have deprecated the use of Log4J 1.x because we now support SLF4J and Log4J 1.x is way past its end-of-life. We did not want to make SLF4J the default logger (at least not yet) as we did not want to have the default ESAPI use require additional dependencies. However, SLF4J is likely to be the future choice, at least once we start on ESAPI 3.0. A special shout-out to Jeremiah Stacey for making this possible by re-factoring much of the ESAPI logger code. Note, the straw that broke the proverbial camel's back was the announcement of CVE-2019-17571 (rated Critical), for which there is no fix available and likely will never be.
+
+However, if you try to juse the new ESAPI 2.2.1.0 or later logging you will notice that you need to change ESAPI.Logger and also possibly provide some other properties as well to get the logging behavior that you desire.
+
+To use ESAPI logging in ESAPI 2.2.1.0 (and later), you will need to set the ESAPI.Logger property to
+
+ org.owasp.esapi.logging.java.JavaLogFactory - To use the new default, java.util.logging (JUL)
+ org.owasp.esapi.logging.log4j.Log4JLogFactory - To use the end-of-life Log4J 1.x logger
+ org.owasp.esapi.logging.slf4j.Slf4JLogFactory - To use the new (to release 2.2.0.0) SLF4J logger
+
+In addition, if you wish to use JUL for logging, you *MUST* supply an "esapi-java-logging.properties" file in your classpath. This file is included in the 'esapi-2.2.2.0-configuration.jar' file provided under the 'Assets' section of the GitHub Release at
+ https://github.com/ESAPI/esapi-java-legacy/releases/esapi-2.2.2.0
+
+Unfortunately, there was a logic error in the static initializer of JavaLogFactory (now fixed in this release) that caused a NullPointerException to be thrown so that the message about the missing "esapi-java-logging.properties" file was never seen.
+
+If you are using JavaLogFactory, you will also want to ensure that you have the following ESAPI logging properties set:
+ # Set the application name if these logs are combined with other applications
+ Logger.ApplicationName=ExampleApplication
+ # If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true
+ Logger.LogEncodingRequired=false
+ # Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments.
+ Logger.LogApplicationName=true
+ # Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments.
+ Logger.LogServerIP=true
+ # LogFileName, the name of the logging file. Provide a full directory path (e.g., C:\ESAPI\ESAPI_logging_file) if you
+ # want to place it in a specific directory.
+ Logger.LogFileName=ESAPI_logging_file
+ # MaxLogFileSize, the max size (in bytes) of a single log file before it cuts over to a new one (default is 10,000,000)
+ Logger.MaxLogFileSize=10000000
+ # Determines whether ESAPI should log the user info.
+ Logger.UserInfo=true
+ # Determines whether ESAPI should log the session id and client IP.
+ Logger.ClientInfo=true
+
+See GitHub issue #560 for additional details.
+
+
+Related to that aforemented Log4J 1.x CVE and how it affects ESAPI, be sure to read
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin2.pdf
+which describes CVE-2019-17571, a deserialization vulnerability in Log4J 1.2.17. ESAPI is *NOT* affected by this (even if you chose to use Log4J 1 as you default ESAPI logger). This security bulletin describes why this CVE is not exploitable as used by ESAPI.
+
+
+Finally, while ESAPI still supports JDK 7 (even though that too is way past end-of-life), the next ESAPI release will move to JDK 8 as the minimal baseline. (We already use Java 8 for development but still to Java 7 source and runtime compatibility.) We need to do this out of necessity because some of our dependencies are no longer doing updates that support Java 7.
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+
+New News
+--------
+See UPDATE, below, in next sub-section under Old News.
+
+
+Old News - Failing JUnit tests
+------------------------------
+ If you use Java 7 (the minimal Java baseline supported by ESAPI) and try to run 'mvn test' there is one test that fails. This test passes with Java 8. The failing test is:
+
+ [ERROR] Tests run: 5, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.203 s
+ <<< FAILURE! - in org.owasp.esapi.crypto.SecurityProviderLoaderTest
+ [ERROR] org.owasp.esapi.crypto.SecurityProviderLoaderTest.testWithBouncyCastle
+ Time elapsed: 0.116 s <<< FAILURE!
+ java.lang.AssertionError: Encryption w/ Bouncy Castle failed with
+ EncryptionException for preferred cipher transformation; exception was:
+ org.owasp.esapi.errors.EncryptionException: Encryption failure (unavailable
+ cipher requested)
+ at
+ org.owasp.esapi.crypto.SecurityProviderLoaderTest.testWithBouncyCastle(Security
+ ProviderLoaderTest.java:133)
+
+ I will spare you all the details and tell you that this has to do with Java 7 not being able to correctly parse the signed Bouncy Castle JCE provider jar. More details are available at:
+ https://www.bouncycastle.org/latest_releases.html
+ and
+ https://github.com/bcgit/bc-java/issues/477
+ I am sure that there are ways of making Bouncy Castle work with Java 7, but since ESAPI does not rely on Bouncy Castle (it can use any compliant JCE provider), this should not be a problem. (It works fine with the default SunJCE provider.) If it is important to get the BC provider working with the ESAPI Encryptor and Java 7, then open a GitHub issue and we will take a deeper look at it and see if we can suggest something.
+
+
+
+ Another problem is if you run 'mvn test' from the 'cmd' prompt (and possibly PowerShell as well), you will get intermittent failures (generally between 10-25% of the time) at arbitrary spots. If you run it again without any changes it will work fine without any failures. We have discovered that it doesn't seem to fail if you run the tests from an IDE like Eclipse or if you redirect both stdout and stderr to a file; e.g.,
+
+ C:\code\esapi-java-legacy> mvn test >testoutput.txt 2>&1
+
+ UPDATE: We now believe these at least some of these failures may be because the maven-surefire-plugin is, by default, not creating a new JVM process for each test class. We are looking into this. For now, we have only have observed this behavior on Windows 10. If you see this error, please do NOT report it as a GitHub issue unless you know a fix for it. (And yes, we are aware of 'false' in the pom for the maven-surefire-plugin, but that causes other tests to fail that we haven't had time to fix.) See GitHub issue #604 (https://github.com/ESAPI/esapi-java-legacy/issues/604) for additional details.
+
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, most of which were not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Added GitHub CI workflow to run 'mvn package' to test if PRs pass tests.
+* Added GitHub workflow for "Super Linter".
+* Minor updates to README.md file (still trying to get 'Build Status' badge to work)
+* Updated deployment process documentation for ESAPI release steps.
+* Updated Security Advisory #3 with new links.
+* Created Security Advisory #4.
+* Updated ESAPI.properties file to reflect new OWASP wiki page.
+* Miscellaneous pom.xml changes related to plugins.
+* Updates to CONTRIBUTING-TO-ESAPI.txt to add paragraph on GitHub deprecating passwords for git operations.
+* Remove invalid node from antisamy-esapi.xml AntiSamy policy file used by ESAPI.
+* Add prominent warnings in log4j.xml about ESAPI's use of Log4J 1.x being deprecated.
+
+-----------------------------------------------------------------------------
+
+Closed PRs Activity Report (Changes between release 2.2.2.0 and 2.2.3.0, i.e., between 2020-11-27 and 2021-03-23)
+
+ See https://github.com/ESAPI/esapi-java-legacy/pulls?q=type%3Apr+state%3Aclosed+closed%3A%3E2020-11-27+updated%3A%3C2021-03-24
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2020-11-27 --until=2021-03-23 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.2.2.0) and until the current (2.2.3.0) release.
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ [INFO] Scanning for projects...
+ [INFO]
+ [INFO] -----------------------< org.owasp.esapi:esapi >------------------------
+ [INFO] Building ESAPI 2.2.3.0-SNAPSHOT
+ [INFO] --------------------------------[ jar ]---------------------------------
+ [INFO]
+ [INFO] --- maven-dependency-plugin:3.1.2:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.2.3.0-SNAPSHOT
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.0.1:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- com.io7m.xom:xom:jar:1.2.10:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.3.3:compile
+ [INFO] +- log4j:log4j:jar:1.2.17:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.6.2:compile
+ [INFO] | +- commons-codec:commons-codec:jar:1.15:compile
+ [INFO] | +- net.sourceforge.nekohtml:nekohtml:jar:1.9.22:compile
+ [INFO] | +- org.apache.httpcomponents:httpclient:jar:4.5.13:compile
+ [INFO] | +- org.apache.httpcomponents:httpcore:jar:4.4.14:compile
+ [INFO] | +- org.slf4j:slf4j-simple:jar:1.7.30:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.1:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:1.7.30:compile
+ [INFO] +- commons-io:commons-io:jar:2.6:compile
+ [INFO] +- org.apache.xmlgraphics:batik-css:jar:1.14:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.14:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-util:jar:1.14:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-constants:jar:1.14:compile
+ [INFO] | | \- org.apache.xmlgraphics:batik-i18n:jar:1.14:compile
+ [INFO] | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.6:compile
+ [INFO] +- xalan:xalan:jar:2.7.2:compile
+ [INFO] | \- xalan:serializer:jar:2.7.2:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.2.0:compile (optional)
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile (optional)
+ [INFO] +- net.jcip:jcip-annotations:jar:1.0:compile (optional)
+ [INFO] +- junit:junit:jar:4.13.1:test
+ [INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.68:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-core:jar:2.0.7:test
+ [INFO] +- org.javassist:javassist:jar:3.25.0-GA:test
+ [INFO] +- org.mockito:mockito-core:jar:2.28.2:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.9.10:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.9.10:test
+ [INFO] | \- org.objenesis:objenesis:jar:2.6:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.7:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.7:test
+ [INFO] +- org.openjdk.jmh:jmh-core:jar:1.23:test
+ [INFO] | +- net.sf.jopt-simple:jopt-simple:jar:4.6:test
+ [INFO] | \- org.apache.commons:commons-math3:jar:3.2:test
+ [INFO] \- org.openjdk.jmh:jmh-generator-annprocess:jar:1.23:test
+ [INFO] ------------------------------------------------------------------------
+ [INFO] BUILD SUCCESS
+ [INFO] ------------------------------------------------------------------------
+ [INFO] Total time: 0.906 s
+ [INFO] Finished at: 2021-03-21T22:03:50-04:00
+[INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ Another hat tip to Dave Wichers for promptly releasing AntiSamy 1.6.2. A special shout-out to @simon0117 for adding the Maven and Super-Linter GitHub Actions (PR #583)
+ And lastly, thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.2.3.1-release-notes.txt b/documentation/esapi4java-core-2.2.3.1-release-notes.txt
new file mode 100644
index 000000000..f53aa8360
--- /dev/null
+++ b/documentation/esapi4java-core-2.2.3.1-release-notes.txt
@@ -0,0 +1,165 @@
+Release notes for ESAPI 2.2.3.1
+ Release date: 2021-05-07
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.2.3.0, 2021-03-23
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a very small patch release with the primary intent of updating some dependencies.
+
+Major changes:
+ * Restores Apache Commons IO from 1.3.1 (what it was in 2.2.3.0) to 2.6 (what it was in 2.2.2.0).
+ * Updates AntiSamy from 1.6.2 to 1.6.3
+
+Unless you have already updated to ESAPI 2.2.3.0 and read those release notes, you should read those release notes for additional details. You can find it at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.3.0-release-notes.txt
+
+That discusses things like security bulletins and other important details that I am not going into for this release.
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.2.3.1 release (no change since last release):
+ 212 Java source files
+ 4316 JUnit tests in 136 Java source files
+
+3 GitHub Issues closed in this release, including those we've decided not to fix (marked '(wontfix)').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2021-03-23)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+614 Potentlial XXE Injection vulnerability in loading XML version of ESAPI properties file
+617 Unresolved Reference for com.ibm.uvm.tools in an OSGI Bundle
+624 Update pom.xml to use AntiSamy 1.6.3 and Apache Commons IO 2.6
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+See this section from the previous release notes at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.3.0-release-notes.txt
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+See this section from the previous release notes at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.3.0-release-notes.txt
+
+NEW since last release (ESAPI 2.2.3.0) - CVE-2021-29425
+ https://nvd.nist.gov/vuln/detail/CVE-2021-29425
+
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+None known.
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.2.3.0 and 2.2.3.1, i.e., between 2021-03-23 and 2021-05-07)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+========================================================
+jeremiahjstacey 8 6 1
+dependabot 1 1 1
+kwwall 7 8 0
+========================================================
+ Total PRs: 2
+
+There were also several snyk-bot PRs that were rejected for various reasons, mostly because 1) I was already making the proposed changes and preferred to do them in single commit or 2) there were other reasons for rejecting them (such as the dependency requiring Java 8). The proposed changes that were not outright rejected were included as part of commit a8a79bc5196653500ce664b7b063284e60bddaa0.
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2021-03-23 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.2.3.0) release.
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn dependency:tree
+ [INFO] Scanning for projects...
+ [INFO]
+ [INFO] -----------------------< org.owasp.esapi:esapi >------------------------
+ [INFO] Building ESAPI 2.2.3.1-SNAPSHOT
+ [INFO] --------------------------------[ jar ]---------------------------------
+ [INFO]
+ [INFO] --- maven-dependency-plugin:3.1.2:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.2.3.1-SNAPSHOT
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.0.1:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- com.io7m.xom:xom:jar:1.2.10:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.3.3:compile
+ [INFO] +- log4j:log4j:jar:1.2.17:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.6.3:compile
+ [INFO] | +- net.sourceforge.nekohtml:nekohtml:jar:1.9.22:compile
+ [INFO] | +- org.apache.httpcomponents:httpclient:jar:4.5.13:compile
+ [INFO] | +- org.apache.httpcomponents:httpcore:jar:4.4.14:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.14:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.14:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.14:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.14:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.14:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.6:compile
+ [INFO] | +- org.slf4j:slf4j-simple:jar:1.7.30:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.1:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:1.7.30:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- commons-io:commons-io:jar:2.6:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.2.2:compile (optional)
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile (optional)
+ [INFO] +- commons-codec:commons-codec:jar:1.15:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.68:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:1.3:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.7:test
+ [INFO] +- org.javassist:javassist:jar:3.25.0-GA:test
+ [INFO] +- org.mockito:mockito-core:jar:2.28.2:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.9.10:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.9.10:test
+ [INFO] | \- org.objenesis:objenesis:jar:2.6:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.7:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.7:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.7:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.28:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:4.6:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.2:test
+ [INFO] ------------------------------------------------------------------------
+ [INFO] BUILD SUCCESS
+ [INFO] ------------------------------------------------------------------------
+ [INFO] Total time: 0.759 s
+ [INFO] Finished at: 2021-05-07T01:13:27-04:00
+ [INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ Another hat tip to Dave Wichers for promptly releasing AntiSamy 1.6.2 and for the PR to fix GitHub issue #614. And thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.3.0.0-release-notes.txt b/documentation/esapi4java-core-2.3.0.0-release-notes.txt
new file mode 100644
index 000000000..e4cdefb1d
--- /dev/null
+++ b/documentation/esapi4java-core-2.3.0.0-release-notes.txt
@@ -0,0 +1,211 @@
+Release notes for ESAPI 2.3.0.0
+ Release date: 2022-04-17
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.2.3.1, 2021-05-07
+
+Important Announcement
+----------------------
+Do NOT: Do NOT use GitHub Issues to ask questions about this of future releases. That is what the ESAPI Google groups are for. (See our GitHub README.md for further details.) If you can't do the ESAPI Google groups, then drop and email to either one or both of the project leaders (email addresses provided above). We will NOT respond to questions posted in GitHub Issues.
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a very important ESAPI release, as it remediates several potentially exploitable vulnerabilities. Part of the remediation may include reviewing and updating your antisamy-esapi.xml configuration file, so be sure to read through ALL the details thoroughly or you may not be fully protected even though you have installed the new ESAPI 2.3.0.0 jar. This will also certainly be the last ESAPI release to support Java 7, so you would do well to prepare to move to Java 8 or later if you have not already done so.
+
+The primary intent of this release is to patch several potentially exploitable vulnerabilities in ESAPI. Many of these are related to AntiSamy and were introduced by vulnerable transitive dependencies. All but one those (a DoS vulnerability in an AntiSamy dependency) is believed to have been fixed with an update to use the new AntiSamy 1.6.7 release. There are also two vulnerabilities within ESAPI itself which have been remediated as part of this release, one of which dates back to at least ESAPI 1.4.
+
+In addition to these patches (discussed in a bit more detail later under the section 'Changes Requiring Special Attention'), there were other updates to dependencies made in this release done to simply to keep them as up-to-date as possible. We have also added the generation of an SBOM (Software Bill of Materials) generated via the cyclonedx:cyclonedx-maven-plugin.
+
+Lastly, support for the deprecated value of "fixed" for the ESAPI property "Encryptor.ChooseIVMethod" has been completely removed from this release. It had been deprecated since 2.2.0.0 and it's removal long scheduled for the 2.3.0.0 release. See the GitHub issue 679 for further details.
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.2.3.1 release (previous release):
+ 212 Java source files
+ 4316 JUnit tests in 136 Java source files
+
+ESAPI 2.3.0.0 release (current / new release):
+ 212 Java source files
+ 4325 JUnit tests in 136 Java source files (1 test ignored)
+
+24 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+[Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2021-05-07]
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+163 Limit max size of entire cookies Component-Validator enhancement good first issue help wanted imported Priority-High
+198 Uninitialized esapi logging assumes logging to System.out/System.err - Make configurable/extensible bug imported wontfix
+324 ClassCastException during web application redeploy due to the grift logging classes enhancement imported
+564 Create release notes for 2.2.1.1 patch release Component-Docs
+567 Release 2.2.1.1 Not Loading Properties in dependent JARs
+574 Multiple encoding issue for Google Chrome wontfix
+608 Move HTMLValidationRule static Classpath handling into DefaultSecurityConfiguration
+624 Update pom.xml to use AntiSamy 1.6.3 and Apache Commons IO 2.6 Build-Maven
+629 Define .snyk ignore content
+630 Incorrect result for isEnabled() in Slf4JLogger
+631 Create Default Logging level configuration for ESAPI library wontfix
+634 Removing \ from JSON string by ESAPI.encoder().canonicalize(value)
+640 Decouple from AntiSamy slf4j-api dependency & Update dependency
+648 Log4J CVE-2021-4104
+652 Fix code scanning alert - tracker 3 duplicate
+653 java.io.FileNotFoundException Error in Logs When ESAPI.properties and validation.properties are in resources.
+657 Need to update Xerces transitive dependency to fix CVE-2022-23437
+658 Vulnerability issue on dependency commons-io
+664 ValidationException exposing potentially sensitive user supplied input to log wontfix
+669 JavaEncryptor.java HARDCODED_CREDENTIALS
+671 Version 2.2.3.1 contains 5 vulnerabilities in ESAPI dependencies
+672 HTMLEntityCodec Bug Decoding "Left Angular Bracket" Symbol
+673 Validator.HTTPHeaderValue changed automatically
+679 Completely remove support for fixed IVs and throw a ConfigurationException if encountered
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+
+1) This likely will be the LAST ESAPI release supporting Java 7. There are just some vulnerabilities (notably a DoS one in Neko HtmlUnit that was assigned CVE-2022-28366 after the ESAPI 2.3.0.0 release) that because they are transitive dependencies, that we simply cannot remediate without at least moving on to Java 8 as the minimally supported JDK. Please plan accordingly.
+
+2) If you are not upgrading to ESAPI release 2.3.0.0 from 2.2.3.1 (the previous release), then you NEED to read at least the release notes in 2.2.3.1 and ideally, all the ones in all the previous ESAPI release notes from where you are updating to 2.3.0.0. In particular, if you were using ESAPI 2.2.1.0 or earlier, you need to see those ESAPI release notes in regards to changes in the ESAPI.Logger property.
+
+ !!!!! VULNERABILITY ALERTS !!!!!
+
+3) There is one VERY SERIOUS (as in easy to exploit) vulnerability in ESAPI's default antisamy-esapi.xml configuration file. This problem seems to date back to at least ESAPI release 1.4. If you do nothing else, you should update your antisamy-esapi.xml to the one provided in the esapi-2.3.0.0-configuration.jar that can be found on GitHub under "https://github.com/ESAPI/esapi-java-legacy/releases/tag/esapi-2.3.0.0". The ESAPI team will be submitting an official CVE for this, but the bottom line is that the default ESAPI antisamy-esapi.xml configuration file does not properly sanitize 'javascript:' URLs in most cases, but instead accepts the input as "safe". A few more details regarding the configuration is provided in the section "Important checks you take as a developer using ESAPI" given below. (Update: This vulnerability was assigned CVE ID CVE-2022-24891. See GitHub Security Adivisory https://github.com/ESAPI/esapi-java-legacy/security/advisories/GHSA-q77q-vx4q-xx6q and ESAPI Security Bulletin 8 at https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin8.pdf for further details.)
+
+4) Several other vulnerabilities associated with AntiSamy have been patched via the AntiSamy 1.6.7 (or prior) release. See the AntiSamy release notes for 1.6.7, 1.6.6.1, 1.6.6, 1.6.5 and 1.6.4 at https://github.com/nahsra/antisamy/releases for further details on what has been remediated. Note that the default ESAPI.properties and ESAPI AntiSamy configuration did not really leave ESAPI vulnerable to CVE-2021-35043 which was fixed in AntiSamy 1.6.4, but that was a moot point because of #3, above.
+
+5) A vulnerability found by GitHub Security Lab that is an example of CWE-22 [Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')], was discovered by GHSL security researcher Jaroslav LobaÄŤevski. You can find details of it under "documentation/GHSL-2022-008_The_OWASP_Enterprise_Security_API.md" or "documentation/GHSL-2022-008_The_OWASP_Enterprise_Security_API.pdf" on ESAPI's GitHub repo or from the ESAPI source zip or tarball files associated with this (or later) release. (Update: After this release, this vulnerability was assigned CVE ID CVE-2022-23457. See GitHub Security Adivisory https://github.com/ESAPI/esapi-java-legacy/security/advisories/GHSA-8m5h-hrqm-pxm2 for further details.)
+
+6) There remains one known unpatched, potentially exploitable vulnerability (a DoS vulnerability in the transitive dependency Neko HtmlUnit) in ESAPI 2.3.0.0. That vulnerability was later assigned CVE-20222-28366, but it is fixed in certain versions of Neko HtmlUnit after release 2.24.0. However, release 2.24.0 is the last Neko HtmlUnit release that supports Java 7 and thus is the latest one that we can use. That vulnerability is patched only fixed in a version of Neko HtmlUnit that was compiled with Java 8. Since ESAPI (as of release 2.3.0.0) only supports Java 7, we are currently unable to patch to remediate this DoS vulnerability. (This is why we are currently committed for this 2.3.0.0 release to be last release at least to support Java 7). The ESAPI team plans to release a 2.4.0.0 release that will require Java 8 or later as the minimal JDK, and with that release, we will update to AntiSamy 1.7.0 (which requires Java 8) and which uses Neko HtmlUnit 2.60.0 (which also requires Java 8 or later) and that addresses the DoS vulnerability. For further information, see the JUnit test testNekoDOSWithAnHTMLComment in "src/test/java/org/owasp/esapi/reference/validation/HTMLValidationRuleCleanTest.java". (Note that currently, this JUnit test is annotated as '@Ignore' since it would not pass under Java 7 and using Neko HtmlUnit 2.24.0.)
+
+7) *NEW* It later came to our attention that there was a unknown XSS vulnerability in AntiSamy [later identified as CVE-2022-29577] that was patched in AntiSamy 1.6.8, which was not available at the time of the ESAPI 2.3.0.0 release. (Someone on the AntiSamy team probably told me about this, but I just forgot. Sorry ESAPI folks!)
+
+NOTE: We plan on issuing an updated README.md and updated security bulletins on #3 and #4 soon, but we wanted to focus on getting the patches out rather than getting the documentation out. This probably will not be in a separate release, but we will announce in on the ESAPI Users and ESAPI Dev Google lists once we drop them on our GitHub repo under the "documentation" folder.
+
+
+FALSE POSITIVE ALERT ==> A final word on vulnerabilities -- CVE-2020-5529 is a False Positive
+
+Dependency Check picks up a false positive CVE in ESAPI 2.3.0.0. Other SCA tools may as well. Specifically, Dependency Check flags CVE-2020-5529 in a different (the original) Neko HtmlUnit then the one that AntiSamy is using. In Dependency Check, this is a False Positive caused by a mismatch of the CPE (i.e., Common Platform Enumeration) identifier. If you follow the "Hyperlink" section referenced on https://nvd.nist.gov/vuln/detail/CVE-2020-5529 page, you will see that it ultimately references https://github.com/HtmlUnit/htmlunit/releases/tag/2.37.0, which is the old, unmaintained version of Neko that AntiSamy had been using up until recently. Dependency Check is incorrectly matching "net.sourceforge.htmlunit:htmlunit" rather than matching "net.sourceforge.htmlunit:neko-htmlunit", which it what if should be matching. This CPE matching confusion is a common problem with Dependency Check, but it's by design. Understandably, Jeremy Long and other Dependency Check contributors have deliberately tweaked Dependency Check to fall more on the side of False Positives so as to avoid False Negatives, because False Positives are a lot easier to vet and rule out, and one can--if so desired--create a suppressions.xml entry for it to ignore them. (I've decided against suppressing it in Dependency Check--at least for the time being--because there are likely other SCA tools that will also flag this as a False Positive.) For now, it's easier to just acknowledge it in the release notes. (Especially since we'll be releasing a 2.4.0.0 version soon after the 2.3.0.0 version that will support Java 8 as the minimal SDK so this problem will disappear.) Note however that Snyk does not flag ESAPI as being vulnerable to CVE-2020-5529.
+
+----------------------------------------------------------------------------e
+
+Important security checks you SHOULD take as a developer using ESAPI
+
+Simply upgrading to the esapi-2.3.0.0.jar may not be enough. This 2.3.0.0 release patches a bypass around some AntiSamy related sanitization that has been present since at least the ESAPI 1.4 release. It is specifically fixed in the esapi-2.3.0.0-configuration.jar, which you may download from https://github.com/ESAPI/esapi-java-legacy/releases/download/esapi-2.3.0.0/esapi-2.3.0.0-configuration.jar. From that, you will want to extract the configuration/esapi/antisamy-esapi.xml file and use it to replace your previous stock antisamy-esapi.xml file. However, if you have customized your antisamy-esapi.xml file, then to address the vulnerability, you MUST find the vulnerable configuration line where the "onsiteURL" attribute is defined and change the regular expression.
+
+ The original (vulnerable) line will look like:
+
+
+ The corrected line should look like:
+
+
+We have also updated the other regular expressions in the '' node for our antisamy-esapi.xml file to reflect the latest regex values from AntiSamy's antisamy.xml configuration file in their official AntiSamy 1.6.7 release. This was done as a precautionary measure only, as the regex pattern seemed to be malformed along the same lines of "onsiteURL" and thus potentially could allow unintended characters to be passed through as "safe". Note however that there are no vulnerabilities known to the ESAPI team regarding these other 2 regular expressions for "htmlTitle" and "offsiteURL". If these prove to be problematic with your applications using ESAPI, you may decide to change the probablematic ones to the original values.
+
+ The original (possibly vulnerable???) regular expression values for htmlTitle and offsiteURL:
+
+
+
+ The updated regular expression values for them:
+
+
+
+In future ESAPI releases, we may consider just replacing ESAPI's antisamy-esapi.xml file with AntiSamy's antisamy.xml, but we will not be doing that lightly. We tested with the latter and it broke some ESAPI JUnit tests so such a change now likely would break some client ESAPI code as well. However, the changes to the "" node did not break any of our ESAPI JUnit tests so we believe they are probably okay. (If not, we apologize in advance, but we prefer to error on the side of caution here.)
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.2.3.1 and 2.3.0.0, i.e., between 2021-05-07 and 2022-04-17)
+
+Normally, I (Kevin) write up lots of other details in the release notes, especially to credit those who have contributed PRs to address ESAPI issues. I apologize for not spending time on this right now, but I will try to update this set of release notes for 2.3.0.0 in the near future to add such things.
+
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May we suggest:
+
+ git log --stat --since=2021-05-07 --reverse --pretty=medium
+
+ or clone the ESAPI/esapi-java-legacy repo and then run
+
+ mvn site
+
+ and finally, point your browser at
+
+ target/site/changelog.html
+
+ Both approaches should show all the commits since just after the previous (2.2.3.1) release. [Note that the both approaches may include commits after the 2.3.0.0 release, but the first allows to to easily add an end date via '--until=2022-04-17'.]
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.3.0:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.3.0.0
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.0.1:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- com.io7m.xom:xom:jar:1.2.10:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.3.3:compile
+ [INFO] +- log4j:log4j:jar:1.2.17:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.6.7:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.1.3:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.1.3:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.1.3:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.14:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.14:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.14:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.14:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.14:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.6:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- net.sourceforge.htmlunit:neko-htmlunit:jar:2.24:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:1.7.36:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- commons-io:commons-io:jar:2.6:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.6.0:compile
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile
+ [INFO] +- commons-codec:commons-codec:jar:1.15:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.70:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:1.3:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.7:test
+ [INFO] +- org.javassist:javassist:jar:3.25.0-GA:test
+ [INFO] +- org.mockito:mockito-core:jar:2.28.2:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.9.10:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.9.10:test
+ [INFO] | \- org.objenesis:objenesis:jar:2.6:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.7:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.7:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.7:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.7:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.35:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.2:test
+ ...
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ * A special shout out to Jaroslav LobaÄŤevski, a security researcher at GitHub Security Labs, who notified the ESAPI team via responsible disclosure and allowed us sufficient time to address GHSL-2022-008.
+ * A huge hat-tip to Dave Wichers and Sebastian Passaro for promptly addressing vulnerabilities in AntiSamy, many of which were caused by poorly maintained dependencies of AntiSamy.
+ * A special thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI contributors whom I've undoubtedly forgotten.
+ * Finally, to all the ESAPI users who make our efforts worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.4.0.0-release-notes.txt b/documentation/esapi4java-core-2.4.0.0-release-notes.txt
new file mode 100644
index 000000000..bfc50362d
--- /dev/null
+++ b/documentation/esapi4java-core-2.4.0.0-release-notes.txt
@@ -0,0 +1,147 @@
+Release notes for ESAPI 2.4.0.0
+ Release date: 2022-04-24
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.3.0.0, 2022-04-17
+
+Important Announcement
+----------------------
+Do NOT: Do NOT use GitHub Issues to ask questions about this of future releases. That is what the ESAPI Google groups are for. (See our GitHub README.md for further details.) If you can't do the ESAPI Google groups, then drop and email to either one or both of the project leaders (email addresses provided above). We will NOT respond to questions posted in GitHub Issues.
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a very important ESAPI release as it is the first release to be FULLY INCOMPATIBLE WITH JAVA 1.7! This was expedited in response to some dependencies to resolve prior CVEs (see release notes in 2.3.0.0) that could not be updated as those versions required a JDK > 1.7 which we were forced to. The slightly premature update to Java 1.8 is done to address CVE-2022-28366 that had to be fixed with a version of the transitive depenedency via AntiSamy of NekoHTML that was Java 1.8+ only. (Wrapped into issue #682) It is important to note that the solution to fix CVE-2022-28366 does not exist in ESAPI 2.3.0.0 and there is no intention to fix it for Java 1.7.
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.3.0.0 release (previous release):
+ 212 Java source files
+ 4325 JUnit tests in 136 Java source files (1 test ignored)
+
+ESAPI 2.4.0.0 release (current / new release):
+ 212 Java source files
+ 4326 JUnit tests in 136 Java source files
+
+3 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+[Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2022-04-17]
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+644 Do not include a logging implementation as a dependency slf4j-simple
+672 (wontfix) HTMLEntityCodec Bug Decoding "Left Angular Bracket" Symbol
+679 Completely remove support for fixed IVs and throw a ConfigurationException if encountered.
+682 Update baseline to Java 1.8
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+
+1) This is the first ESAPI release that does not support Java 1.7. This library will no longer work if your application is that old.
+
+ !!!!! VULNERABILITY ALERTS !!!!!
+
+2) This release fixes the known vulnerability ESAPI 2.3.0.0 that had to wait until we supported Java 8 to be patched. The patch was in Neko-HtmlUntil and was fixed in version 2.27, which required Java 8 or later. It was a transitive dependency via AntiSamy and we picked it up by updating to AntiSamy 1.6.8. This was a DoS vulnerability discovered in HtmlUnit-Neko affecting all versions up to 2.26. Full details from MITRE are here: https://cve.mitre.org/cgi-bin/cvename.cgi?name=2022-28366
+
+3) This release also patches the (known, but forgotten?) XSS vulnerability ESAPI 2.3.0.0 in AntiSamy 1.6.7 but was fixed in 1.6.8. (The 2.3.0.0 release notes have been updated to mention this.) Full details from MITRE are here: https://cve.mitre.org/cgi-bin/cvename.cgi?name=2022-29577
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.3.0.0 and 2.4.0.0, i.e., between 2022-04-17 and 2022-04-24)
+
+Special thanks to Dave Wichers and Sebastian Pessaro from AntiSamy for their work to provide version 1.6.8 which patched 2 CVEs.
+Special thanks to Jeremiah J. Stacey for his work to update and prep the library to support java 1.8. (He literally created the PR the day after 2.3.0.0's release.)
+Special thanks to Kevin Wall for support in pushing out this release.
+
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May we suggest:
+
+ git log --stat --since=2022-04-17 --reverse --pretty=medium
+
+ or clone the ESAPI/esapi-java-legacy repo and then run
+
+ mvn site
+
+ and finally, point your browser at
+
+ target/site/changelog.html
+
+ Both approaches should show all the commits since just after the previous (2.2.3.1) release. [Note that the both approaches may include commits after the 2.3.0.0 release, but the first allows to to easily add an end date via '--until=2022-04-17'.]
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] org.owasp.esapi:esapi:jar:2.4.0.0-SNAPSHOT
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- com.io7m.xom:xom:jar:1.2.10:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.4:compile
+ [INFO] +- log4j:log4j:jar:1.2.17:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.4:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.6.8:compile
+ [INFO] | +- net.sourceforge.htmlunit:neko-htmlunit:jar:2.61.0:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.1.3:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.1.3:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.1.3:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.14:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.14:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.14:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.14:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.14:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.6:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:1.7.36:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- commons-io:commons-io:jar:2.11.0:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.6.0:compile
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile
+ [INFO] +- commons-codec:commons-codec:jar:1.15:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.70:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.35:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.2:test
+ ...
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ * A huge hat-tip to Dave Wichers and Sebastian Passaro for promptly releasing AntiSamy 1.6.8 which simplified this releaese
+ * A special thanks to Jeremiah Stacey to wrote the PR #683, that addressed the updates for Java 8.
+ * Finally, to all the ESAPI users who make our efforts worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696) <== (Him too, this time! :)
diff --git a/documentation/esapi4java-core-2.5.0.0-release-notes.txt b/documentation/esapi4java-core-2.5.0.0-release-notes.txt
new file mode 100644
index 000000000..b47b084e0
--- /dev/null
+++ b/documentation/esapi4java-core-2.5.0.0-release-notes.txt
@@ -0,0 +1,254 @@
+Release notes for ESAPI 2.5.0.0
+ Release date: 2022-07-20
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.4.0.0, 2022-04-24
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+
+In addition to this summary, please also be sure to thoroughly read the section "Changes Requiring Special Attention", below.
+
+Major changes:
+ Logging:
+ The major change in ESAPI 2.5.0.0 is the removal of the Log4J 1 dependency (specifically, log4j-1.2.17). It has been removed because in accordance with the ESAPI deprecation policy (see the README.md file), the Log4J supported logger has been deprecated for 2 years.
+
+ For those of you using a Software Configuration Analysis (SCA) services such as Snyk, BlackDuck, Veracode SourceClear, OWASP Dependency Check, etc., you will notice that the 4 Log4J 1.x related CVEs are no longer flagged. This is because of removal of the Log4J 1.2.17 dependency.
+
+ Any remaining flagged vulnerabilities (e.g., CVE-2020-7791 for transitive dependency batik-i18n-1.14) are believed to be false positives.
+
+ You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+ AntiSamy 1.7.0 and potentially breaking changes
+ We have updated to AntiSamy 1.7.0. If you have a custom version of antisamy-esapi.xml,then be sure to read the section "Changes Requiring Special Attention", below.
+
+Minor changes:
+ Miscellaneous bug fixes, Javadoc enhancements, and minor dependency updates.
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.4.0.0 release:
+ 212 Java source files
+ 4325 JUnit tests in 136 Java source files (1 test skipped)
+
+ESAPI 2.5.0.0 release:
+ 206 Java source files
+ 4274 JUnit tests in 131 Java source files (0 tests skipped)
+
+19 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2022-04-24)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+717 Update to AntiSamy 1.7.0 once it is officially released
+715 ESAPI - Not working with Eclipse bug
+713 Should '/' be encoded for LDAP searches? bug
+705 Add more details to DefaultValidator class-level javadoc on ESAPI canonicalization properties Component-Docs Component-Validator javadoc
+702 ValidatorTest#testIsValidDirectoryPathGHSL_POC fails on Mac
+695 Esapi 2.3.0.0 does not supported in opensaml 2.6.6 bug
+692 Multiple (2x) encoding detected in from PercentCodec question
+690 Plugin/Dependency Version Updates
+689 Clean-up ESAPI Javadoc Component-Docs javadoc
+686 ESAPI canonicalization in DefaultEncoder ignoring Encoder.DefaultCodecList property bug Component-Encoder
+684 Hello world
+682 Update baseline to java 1.8
+674 Add the missing Javadoc for the Validator interface Component-Docs Component-Validator good first issue
+656 DefaultHTTPUtility uses hard coded Header name/value lengths (Note: Actually fixed in ESAPI 2.3.0.0, but just closed this release. - kww)
+644 Do not include a logging implementation as a dependency slf4j-simple
+620 Move the default property names and values out of a reference implementation class Component-SecurityConfiguration
+587 Drop Xerces dependency from pom.xml Build-Maven Vulnerable Dependencies
+534 Delete Deprecated Log4J implementation and Dependencies wait4future
+507 LDAP encoding of slash character
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it having first been deprecated.) Thus, your only choice for ESAPI logging are:
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implementation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+ * Create your own custom logger.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+Potentially Breaking Changes in AntiSamy 1.7.0
+
+* This version of ESAPI has upgraded to the latest version of AntiSamy (1.7.0 at the time of our release). AntiSamy 1.7.0 has some breaking changes to its SDK and the way that it processes AntiSamy policy files, of which the antisamy-esapi.xml file, included in our esapi-2.5.0.0-configuration.jar found at https://github.com/ESAPI/esapi-java-legacy/releases/download/esapi-2.5.0.0/esapi-2.4.0.0-configuration.jar, is the one we include.
+
+* None of the AntiSamy SDK changes affected how ESAPI, in its default configuration, uses it, but you may be affected if you have customized your AntiSamy policy file. If your regression tests fail when you upgrade to ESAPI 2.5.0.0 sand they seem to be related to AntiSamy, then please review https://github.com/nahsra/antisamy/blob/main/README.md#important---api-breaking-changes-in-170. Also, as a temporary workaround, you could do something like this (in Maven, but similar exclusion can be done with Gradle) to allow you time to correct your customized AntiSamy policy file:
+
+
+ org.owasp.esapi
+ esapi
+ 2.5.0.0
+
+
+
+ org.owasp.antisamy
+ antisamy
+
+
+
+
+ org.owasp.antisamy
+ antisamy
+ 1.6.8
+
+
+Indeed the only change that we had to make is to alter a JUnit test that was intended to ensure that invalid AntiSamy policy files could be disabled by setting
+ Policy.setSchemaValidation(false);
+before processing any AntiSamy policy file not conforming to its schema. This specific (previously deprecated) method was removed in AntiSamy 1.7.0 so the schema validation checks can no longer be ignored. (And hence the reason for the workaround noted above.)
+
+Instead, we simply changed the JUnit test to check that the expected AntiSamy org.owasp.validator.html.PolicyException class is thrown when the invalid policy file is loaded.
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+* 'mvn site' fails to build these two reports:
+ "Tag reference" report --- maven-taglib-plugin:2.4:tagreference
+ "Taglibdoc documentation" report --- maven-taglib-plugin:2.4:taglibdoc
+
+ Thus no tag library documentation will be generated. :-(
+
+ We are attempting to find a solution, but on the surface, it seems like the maven-taglib-plugin does not play nicely with versions of Java after Java 6. (So, this probably has been happening for a while and we just noticed it.)
+
+* We have had to suppress CVE-2017-10355, related to the transitive dependency xercesImpl-2.12.2.jar via antisamy-1.7.0.jar. It is the same jar that has been used for the past 2 years but the CVE just started popping up now, apparently because of changes to Sonatype's OSS Index. More details are available in the OWASP Dependency Check suppression rules contained in the 'suppressions.xml' file. Note that other SCA tools such as Snyk or GitHub Dependabot are not presently reporting it, but it bears watching.
+
+* Trying to run 'mvn test' with Java 11 or later results in multiple errors in maven-surefire-plugin, so for now, that should be avoided. We think we may have a solution, but at this point, it is too late to test for this release.
+
+* No others problems are known, other than the remaining open issues on GitHub.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Minor updates to README.md file with respect to version information.
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.4.0.0 and 2.5.0.0, i.e., between 2022-04-24 and 2022-07-20)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+
+#
+# 34 PRs merged since ESAPI 2.4.0.0 release
+# Apparent disparement in the figures below may be explained by serveral things:
+# * My failure to do proper counting and basic arithmetic after 4 hours of tweak release notes.
+# * Different basis for calculations:
+# - Figures here may not agree with generated Change Log Report, which is date-based, as some commits included in this release were prior to ESAPI 2.4.0.0 and thus not included in the Change Log Report.
+# - Some commits are done without PRs. Generally, we don't require PRs when we don't require code reviews. That generally is restricted to documenation files, making simple config file changes, and correcting obvious typos. Commits without PRs are resricted to the 3 ESAPI core team members.
+# - Sometimes in a PR, multiple commits touch a file multiple times so we count those files once for each commit.
+#
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+========================================================
+jeremiahjstacey 265 180 24
+kwwall 39 69 5
+xeno6696 1 267 1
+noloader 5 2 1
+stevebosman-oc 4 3 2
+VinodAnandan 1 1 1
+========================================================
+ Total PRs: 34
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2022-04-24 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.4.0.0) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.3.0:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.5.0.0
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.7:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.4:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.4:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.0:compile
+ [INFO] | +- net.sourceforge.htmlunit:neko-htmlunit:jar:2.63.0:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.1.3:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.1.3:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.1.4:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.14:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.14:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.14:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.14:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.14:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.6:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:1.7.36:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- commons-io:commons-io:jar:2.11.0:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.7.1:compile
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile
+ [INFO] +- commons-codec:commons-codec:jar:1.15:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.70:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.35:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.2:test
+ ...
+
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ A special shout-out our new contributors noloader, stevebosman-oc, and VinodAnandan.
+ Another hat tip to Dave Wichers, Sebastián Passaro, and the rest of the AntiSamy crew for promptly releasing AntiSamy 1.7.0. And thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.5.1.0-release-notes.txt b/documentation/esapi4java-core-2.5.1.0-release-notes.txt
new file mode 100644
index 000000000..b8bfb220e
--- /dev/null
+++ b/documentation/esapi4java-core-2.5.1.0-release-notes.txt
@@ -0,0 +1,203 @@
+Release notes for ESAPI 2.5.1.0
+ Release date: 2022-11-27
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.5.0.0, 2022-07-20
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a patch release with the primary intent of updating some dependencies, some which addressed known vulnerabilities in these dependencies, but which we do not believe were exploitable via ESAPI. The major updates are:
+ * Updates to latest versions of direct dependencies, including:
+ - An update to AntiSamy: 1.7.0 --> 1.7.2
+ - An update to SLFJ4 API: 1.7.36 --> 2.0.4 (Note: 2.0.5 is available and likely would would result in "convergence" issues with the version AntiSamy 1.7.2 pulls in)
+ * A new codec (org.owasp.esapi.codecs.JSONCodec) is provided that provides JSON output encoding as per section 7 of RFC 8259. It is made available via Encoder.encodeForJSON(). (Note unlike other encoders, there is no corresponding decoder (i.e., decodeForJSON()) made available. Since that would normally be done by your JavaScript code, it wasn't deemed essential.
+ * Executing 'mvn site' now creates Javadoc for the ESAPI tag library (GitHub issue #733).
+
+For those of you using a Software Configuration Analysis (SCA) services such as Snyk, BlackDuck, Veracode SourceClear, OWASP Dependency Check, etc., you will notice that the 4 Log4J 1.x related CVEs are no longer flagged. This is because we have finally removed the Log4J 1.2.17 dependency in ESAPI 2.5.0.0.
+
+Any remaining flagged vulnerabilities (e.g., CVE-2017-10355 for transitive dependency apache:xerces2_java:2.12.2) are believed to be false postives.
+
+You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.5.0.0 release:
+ 206 Java source files
+ 4274 JUnit tests in 131 Java source files (0 tests skipped)
+
+ESAPI 2.5.1.0 release:
+ 207 Java source files
+ 4292 JUnit tests in 131 Java source files (0 tests skipped)
+
+15 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2022-07-20)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+757 again .. [falsepositive]
+755 Upgrade batik-css-1.14 because of vulnerability
+754 JSON encoder
+749 Error in initializing org.owasp.esapi.logging.java.JavaLogFactory. [Converted to discussion #750.]
+747 Encoder class (org.owasp.esapi.reference.DefaultEncoder) CTOR threw exception [Converted to discussion #751]
+743 Indirect dependency to vulnerable Xerces, CVE-2017-10355 [falsepositive, wontfix]
+740 Update SLF4J log bridge to allow NULL EventTypes
+735 Improve ConfigurationException message thrown from EsapiPropertyLoaderFactory.createPropertyLoader()
+734 Change skin for mvn site report to use fluido Build-Maven
+733 Executing 'mvn site' does not produce tag documentation
+727 ESAPI - Not working with Eclipse [falsepositive, wontfix]
+710 JavaLogFactory configuration should not override custom java LogManager configuration
+610 Add Deprecation Logging content for Log4JLogFactory Usage
+527 Configuration flag for disabling Logger User and App Information [falsepositive]
+433 Class Cast Exception when trying to run JUnit Tests [question, wontfix]
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it haveing first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implemmentation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+None known, other than the remaining open issues on GitHub.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Minor updates to README.md file with respect to version information.
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.5.0.0 and 2.5.1.0, i.e., between 2022-07-20 and 2022-11-27)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+========================================================
+jeremiahjstacey 10 10 3
+noloader 4 316 4
+Jeff-Walker 2 3 1
+HenriquePinto333 2 1 1
+davewichers 2 3 1
+xeno6696 31 6 1
+kwwall 17 9 0
+========================================================
+ Total Merged PRs: 11
+
+ (Note: Total # commits as reflected in CHANGELOG [see below] are less since commits from PRs are generally "squashed" when the are merged.)
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2022-07-20 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.5.0.0) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.3.0:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.5.1.0-SNAPSHOT
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.8:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.4:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.4:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.2:compile
+ [INFO] | +- net.sourceforge.htmlunit:neko-htmlunit:jar:2.66.0:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.2:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.2:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.2:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.16:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.16:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.16:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.16:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.16:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.7:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:2.0.4:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- commons-io:commons-io:jar:2.11.0:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.7.3:compile
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile
+ [INFO] +- commons-codec:commons-codec:jar:1.15:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.70:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.36:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.2:test
+ [INFO] ------------------------------------------------------------------------
+ [INFO] BUILD SUCCESS
+ [INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ Special thanks to
+ noloader, Jeff-Walker, HenriquePinto333, & davewichers
+ for submitting PRs to ESAPI.
+
+ Another hat tip to the AntiSamy crew for promptly releasing AntiSamy 1.7.2. And thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.5.2.0-release-notes.txt b/documentation/esapi4java-core-2.5.2.0-release-notes.txt
new file mode 100644
index 000000000..b695e9b05
--- /dev/null
+++ b/documentation/esapi4java-core-2.5.2.0-release-notes.txt
@@ -0,0 +1,188 @@
+Release notes for ESAPI 2.5.2.0
+ Release date: 2023-04-12
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.5.1.0, 2022-11-27
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a patch release with the primary intent of updating some dependencies, one with a known DoS vulnerability and a more recent one with a potential RCE. From a vulnerability perspective, it addresses CVE-2023-24998 by upgrading to version 1.5 of Apache Commons File Uploads and adding the necessary call to FileBaseUpload.setFileCountMax(). It also updates to version 1.7.3 of AntiSamy to address CVE-2023-26119, a vulnerability in one of their dependencies.
+
+If you are not updating from the previous ESAPI release (2.5.1.0), you should go back and FIRST read all the subsequent release notes in turn. For instance, if you are currently on release 2.3.0.0 and upgrading to this release (2.5.2.0), you should MINIMALLY
+read the sections "Changes Requiring Special Attention" in each of the subsequent release notes. So, going from release 2.3.0.0 to 2.5.2.0, you should in turn, read:
+
+ esapi4java-core-2.4.0.0-release-notes.txt
+ esapi4java-core-2.5.0.0-release-notes.txt
+ esapi4java-core-2.5.1.0-release-notes.txt
+ esapi4java-core-2.5.2.0-release-notes.txt
+
+in that order. YOU HAVE BEEN WARNED!!!
+
+If your SCA tool is reporting any CVE from a direct or transitive dependency in ESAPI, before reporting it as an GitHub issue, please make sure that you review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md. Please email us or contact us in our GitHub Discussions page if you have questions about this. See also the SECURITY.md file to report any security issues with ESAPI.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.5.1.0 release:
+ 207 Java source files
+ 4292 JUnit tests in 131 Java source files (0 tests skipped)
+
+ESAPI 2.5.2.0 release: (unchanged since previous release)
+ 207 Java source files
+ 4293 JUnit tests in 131 Java source files (0 tests skipped, 1 commented out)
+
+7 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2022-11-27)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+773 Esapi giving issue working with graal native image bug
+770 latest version of ESAPI 2.5.1.0 not working with spring boot 3.0, it gives classNotFound for javax.servlet. duplicate enhancement
+769 ESAPI 2.5.1.0 not working with spring boot 3.0, spring 6 bug
+767 Add support for Jakarta Servlet API Specification enhancement [converted to Discussion #768]
+764 unable to locate resource: esapi-java-logging.properties
+761 JavaLogFactory is not loaded from ESAPI.properties file bug
+760 Could not initialize class org. Owasp. Esapi. Reference. DefaultValidator bug
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+* We are aware that ESAPI does not support Spring Boot 3.x or later or Spring Framework 6.x or later.
+ - This is because these projects use a version of Jakarta Servlet API that is incompatible with the the Java EE Servlet API. (The package names are different!)
+ - See Discussion #768 for more details. Please do NOT report this as an issue.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it haveing first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implemmentation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+None known, other than the remaining open issues on GitHub.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Minor updates to README.md file with respect to version information.
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.5.1.0 and 2.5.2.0, i.e., between 2022-11-27-ish and 2023-04-12)
+Generated manually based on merged PRs. All errors are the fault of kwwall and his inability to do simple arithmetic.
+
+Developer Total Total # of Unique # Merged
+(GitHub ID) commits Files Changed PRs
+========================================================
+davewichers 2 4 2
+josephWitthuhnTR 2 2 1
+dependabot 1 1 1
+kwwall 40 31 2
+========================================================
+ Total merged PRs: 6
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2022-11-27 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.5.1.0) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.5.0:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.5.2.0-SNAPSHOT
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.8:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.5:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.4:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.2:compile
+ [INFO] | +- net.sourceforge.htmlunit:neko-htmlunit:jar:2.66.0:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.2:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.2:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.2:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.16:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.16:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.16:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.16:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.16:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.7:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:2.0.6:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- commons-io:commons-io:jar:2.11.0:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.7.3:compile
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile
+ [INFO] +- commons-codec:commons-codec:jar:1.15:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.70:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.36:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.2:test
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ Thanks to my ESAPI co-contributors Matt Seil, Jeremiah Stacey, as well as all the ESAPI users who make our efforts worthwhile. Without you, there would be little point in maintaining this project. Lastly, a special shout-out to Joseph Witthuhn for submitting 2 PRs for this release.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.5.3.0-release-notes.txt b/documentation/esapi4java-core-2.5.3.0-release-notes.txt
new file mode 100644
index 000000000..953e1e0c5
--- /dev/null
+++ b/documentation/esapi4java-core-2.5.3.0-release-notes.txt
@@ -0,0 +1,210 @@
+Release notes for ESAPI 2.5.3.0
+ Release date: 2023-11-24
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.5.2.0, 2023-04-12
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a patch release with the primary intent of providing a Jakarta compatible version of ESAPI (see ESAPI Discussion https://github.com/ESAPI/esapi-java-legacy/discussions/768) as well as updating some dependencies, some with known vulnerabilities. Details follow.
+* We updated ESAPI's AntiSamy dependency from 1.7.3 to 1.7.4. AntiSamy 1.7.4 was released to address an XSS vulnerability in AntiSamy (CVE-2023-43643). Testing ESAPI's use of AntiSamy along with ESAPI's default antsamy-esapi.xml AntiSamy policy file, indicated there was no exploitable path of this CVE via ESAPI. This is because ESAPI's AntiSamy policy file is ultra-strict. (Of course, YMMV if you are not using the default AntiSamy policy file or are customized it to disable the 'preserveComments' directive.)
+* We have deprecated both of ESAPI's Validator.isValidSafeHTML interfaces, as we discovered that they cannot be guaranteed safe. Note that we intend to REMOVE both of these interfaces one year after the ESAPI 2.5.3.0 release. For more details, see GitHub Security Advisory https://github.com/ESAPI/esapi-java-legacy/security/advisories/GHSA-r68h-jhhj-9jvm. There is also an accompanying "ESAPI Security Bulletin 12" (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin12.pdf). The Security Bulletin explains why we did not submit this as a CVE as well as explains some potential workarounds that may work for you.
+* Changed ESAPI so that the default RSA modulus length (sometimes referred to as the key size) from 1024-bits to 2048-bits. Note that if you are using an old version of ESAPI.properties file prior to 2.5.3.0 and are using any of the Encryptor interfaces that directly or indirectly use digital signatures (i.e., sign, verifySignature, seal, unseal, verifySeal), you may wish to consider updating properties:
+ Encryptor.DigitalSignatureAlgorithm=SHA256withDSA # The old SHA1withDSA doesn't support 2048-bit RSA modulus length
+ Encryptor.DigitalSignatureKeyLength=2048
+ Note that if you have persisted previous digital signatures that you must continue to verify, you will have to regenerate them.
+* Thanks to a PR by @jcputney (PR #799), I have attempted to upload additional artifacts to Maven Central that will be a transformed jar suitable for use with the new 'jakarata.servlet' changes for Jakarata EE 9 and later. (Previously, 'javax.servlet' was the name space). Because we are still supporting JDK 8 at this point, we still need to support the 'javax.servlet' namespace as well. In addition to the standard jar artifacts, there should be a new esapi--jakarta.jar (which uses 'jakarta.servlet' instead of 'javax.servlet' namespace) as well as corresponding *-javadoc.jar and *-sources.jar files. I am not sure it will work as we have no tests for it, but looing at the binaries, it seems like it should.
+ For additional details, see:
+ https://github.com/ESAPI/esapi-java-legacy/pull/799
+ https://github.com/ESAPI/esapi-java-legacy/discussions/768
+
+Notes if you are not updating from the immediate previous release. release 2.5.2.0:
+ * You need to read through the series of release notes FIRST, going in order.
+ * For example, if you were updating from an older ESAPI release (say, 2.3.0.0), you should go back and FIRST read all the subsequent release notes in turn. For instance, if you are currently on release 2.3.0.0 and upgrading to (say) release 2.x.y.z, you should MINIMALLY read the sections "Changes Requiring Special Attention" in each of the subsequent release notes. So, going from release 2.3.0.0 to 2.x.y.z, you should in turn, read:
+
+ esapi4java-core-2.4.0.0-release-notes.txt
+ esapi4java-core-2.5.0.0-release-notes.txt
+ esapi4java-core-2.5.1.0-release-notes.txt
+ esapi4java-core-2.5.2.0-release-notes.txt
+ ...etc., up through the current set of release notes...
+ esapi4java-core-2.x.y.z-release-notes.txt
+
+in that order. YOU HAVE BEEN WARNED!!! (These release notes are too large to put all this in a given document; very few read them thoroughly as it is.)
+
+If your SCA tool is reporting any CVE from a direct or transitive dependency in ESAPI, before reporting it as an GitHub issue, please make sure that you review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md. Please email us or contact us in our GitHub Discussions page if you have questions about this. See also the SECURITY.md file to report any security issues with ESAPI.
+
+You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.5.2.0 release:
+ 207 Java source files
+ 4293 JUnit tests in 131 Java source files (0 tests skipped, 1 commented out)
+
+ESAPI 2.5.3.0 release:
+ 207 Java source files
+ 4293 JUnit tests in 131 Java source files (0 failures, 0 errors, 0 tests skipped)
+
+8 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2023-04-12)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+560 Could not initialize class org.owasp.esapi.logging.java.JavaLogFactory (ESAPI 2.2.1.0)
+760 Could not initialize class org. Owasp. Esapi. Reference. DefaultValidator
+775 Add documenttion to CONTRIBUTING-TO-ESAPI.txt to mention signed commits are now required.
+792 Ń…Đ·
+796 Logs printed using println() are always printed and no option to disable them.
+798 Insecure default signature key length
+805 Does esapi-java-legacy support jDK17
+808 Fix typo in comment in validation.properties files
+812 Fix Encoder.encodeForLDAP and Encoder.encodeForDN so they are strictly conformant with Section 3 of RFC 4515
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+Deprecated methods to be removed 1 year after the 2.5.3.0 release
+* As of the ESAPI 2.5.3.0 release, both Validator.isValidSafeHTML have been deprecated and will be removed one year after the 2.5.3.0 release date.
+
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it haveing first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implemmentation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+The effect of upgrade to AntiSamy 1.7.4 in ESAPI 2.5.3.0 can result in ESAPI's Validator.getValidSafeHTML returning a different cleansed (i.e., sanitized) string than previous versions of ESAPI which used earlier versions of AntiSamy did. There presently is no concern for alarm as all these observed different sanitized strings returned by AntiSamy 1.7.4 still all appear to be "safe"; they are just different than before. However, as a result, this could break any regression tests that you previously had that involved ESAPI's Validator.getValidSafeHTML. See https://github.com/nahsra/antisamy/issues/389 and https://github.com/nahsra/antisamy/pull/388 for additional details.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Minor updates to README.md file with respect to version information.
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.5.2.0 and 2.5.3.0, i.e., between 2023-04-12 and 2023-11-24)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+========================================================
+kwwall 40 37 2
+noloader 6 12 3
+preetgami 1 1 1
+robstoll 2 2 1
+jcputney 1 1 1
+========================================================
+ Total PRs: 8
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2023-04-12 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.5.2.0) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.6.1:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.5.3.0
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.9:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.5:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.4:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.4:compile
+ [INFO] | +- org.htmlunit:neko-htmlunit:jar:3.6.0:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.2.1:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.2:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.2.3:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.17:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.17:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.17:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.17:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.17:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.9:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:2.0.6:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- commons-io:commons-io:jar:2.14.0:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.8.1:compile
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile
+ [INFO] +- commons-codec:commons-codec:jar:1.15:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.70:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.37:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.6.1:test
+ [INFO] ------------------------------------------------------------------------
+ [INFO] BUILD SUCCESS
+ [INFO] ------------------------------------------------------------------------
+ [INFO] Total time: 1.701 s
+ [INFO] Finished at: 2023-11-24T13:01:00-05:00
+ [INFO] ------------------------------------------------------------------------
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ Thanks to @noloader, @preetgami, and @jcputney for submitting PRs to help move ESAPI forward. And thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.5.3.1-release-notes.txt b/documentation/esapi4java-core-2.5.3.1-release-notes.txt
new file mode 100644
index 000000000..810cb55ca
--- /dev/null
+++ b/documentation/esapi4java-core-2.5.3.1-release-notes.txt
@@ -0,0 +1,184 @@
+Release notes for ESAPI 2.5.3.1
+ Release date: 2023-12-01
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.5.3.0, 2023-11-24
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+* Rewrite the Javadoc for Validator.isValidSafeHTML to make the dangers more evident.\
+* Changes to the DefaultValidator.isValidSafeHTM method so that a warning is always logs one time about the method being deprecated and a reference to the relevant GitHub Security Advisory.
+
+Notes if you are not updating from the immediate previous release. release 2.5.3.0:
+ * You need to read through the series of release notes FIRST, going in order.
+ * For example, if you were updating from an older ESAPI release (say, 2.3.0.0), you should go back and FIRST read all the subsequent release notes in turn. For instance, if you are currently on release 2.3.0.0 and upgrading to (say) release 2.x.y.z, you should MINIMALLY read the sections "Changes Requiring Special Attention" in each of the subsequent release notes. So, going from release 2.3.0.0 to 2.x.y.z, you should in turn, read:
+
+ esapi4java-core-2.4.0.0-release-notes.txt
+ esapi4java-core-2.5.0.0-release-notes.txt
+ esapi4java-core-2.5.1.0-release-notes.txt
+ esapi4java-core-2.5.2.0-release-notes.txt
+ ...etc., up through the current set of release notes...
+ esapi4java-core-2.x.y.z-release-notes.txt
+
+in that order. YOU HAVE BEEN WARNED!!! (These release notes are too large to put all this in a given document; very few read them thoroughly as it is.)
+
+If your SCA tool is reporting any CVE from a direct or transitive dependency in ESAPI, before reporting it as an GitHub issue, please make sure that you review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md. Please email us or contact us in our GitHub Discussions page if you have questions about this. See also the SECURITY.md file to report any security issues with ESAPI.
+
+You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.5.3.0 release:
+ 207 Java source files
+ 4293 JUnit tests in 131 Java source files (0 failures, 0 errors, 0 tests skipped)
+
+ESAPI 2.5.3.1 release: (unchanged)
+ 207 Java source files
+ 4293 JUnit tests in 131 Java source files (0 failures, 0 errors, 0 tests skipped)
+
+1 GitHub Issue closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2023-11-24)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+794 canonicalize sees entity which isn't there (wontfix)
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it haveing first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implemmentation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+None known, other than the remaining open issues on GitHub.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Minor updates to README.md file with respect to version information.
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.5.3.0 and 2.5.3.1, i.e., between 2023-11-24 and 2023-12-01)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+========================================================
+kwwall 14 16 2
+========================================================
+ Total PRs: 2
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2023-11-24 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.5.3.0) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.6.1:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.5.3.1
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.9:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.5:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.4:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.4:compile
+ [INFO] | +- org.htmlunit:neko-htmlunit:jar:3.6.0:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.2.1:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.2:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.2.3:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.17:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.17:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.17:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.17:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.17:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.9:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:2.0.6:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- commons-io:commons-io:jar:2.14.0:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.8.2:compile
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile
+ [INFO] +- commons-codec:commons-codec:jar:1.16.0:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.70:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.37:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.6.1:test
+ ...
+
+ -----------------------------------------------------------------------------
+
+Acknowledgments:
+ Another hat tip to Dave Wichers for suggesting logging a warning via the deprecated isValidSafeHTML method.
+ And, as always, thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.5.4.0-release-notes.txt b/documentation/esapi4java-core-2.5.4.0-release-notes.txt
new file mode 100644
index 000000000..665c1d280
--- /dev/null
+++ b/documentation/esapi4java-core-2.5.4.0-release-notes.txt
@@ -0,0 +1,205 @@
+Release notes for ESAPI 2.5.4.0
+ Release date: 2024-05-29
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.5.3.1, 2023-12-01
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a patch release with a few bug fixes and dependency updates. While the AntiSamy 1.7.5 update was intended to address an XSS vulnerability (CVE-2024-23635), the ESAPI team verified that this vulnerability did not affect the default configuration of ESAPI and its strict AntiSamy policy file, antisamy-esapi.xml. (Our AntiSamy policy file has the 'preserveComments' directive disabled.)
+
+There is one important issue that was patched (GitHub issue # 839) that has a side-effect. In particular, if you have ESAPI configured to use JUL (i.e., Java Util Logging) as your default logger (i.e., you have ESAPI.Logger set to 'org.owasp.esapi.logging.java.JavaLogFactory', then you MUST delete your 'esapi-java-logging.properties' to set some of the JUL properties. This file was conflicting with the other uses of JUL not used through ESAPI. If you start ESAPI 2.5.4.0 and this file is found as a resource, then a ConfigurationException will be thrown and the exception message will direct you to our GitHub wiki page, https://github.com/ESAPI/esapi-java-legacy/wiki/Configuring-the-JavaLogFactory
+
+Notes if you are not updating from the immediate previous release. release 2.5.3.1:
+ * You need to read through the series of release notes FIRST, going in order.
+ * For example, if you were updating from an older ESAPI release (say, 2.3.0.0), you should go back and FIRST read all the subsequent release notes in turn. For instance, if you are currently on release 2.3.0.0 and upgrading to (say) release 2.x.y.z, you should MINIMALLY read the sections "Changes Requiring Special Attention" in each of the subsequent release notes. So, going from release 2.3.0.0 to 2.x.y.z, you should in turn, read:
+
+ esapi4java-core-2.4.0.0-release-notes.txt
+ esapi4java-core-2.5.0.0-release-notes.txt
+ esapi4java-core-2.5.1.0-release-notes.txt
+ esapi4java-core-2.5.2.0-release-notes.txt
+ ...etc., up through the current set of release notes...
+ esapi4java-core-2.x.y.z-release-notes.txt
+
+in that order. YOU HAVE BEEN WARNED!!! (These release notes are too large to put all this in a given document; very few read them thoroughly as it is.)
+
+If your SCA tool is reporting any CVE from a direct or transitive dependency in ESAPI, before reporting it as an GitHub issue, please make sure that you review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md. Please email us or contact us in our GitHub Discussions page if you have questions about this. See also the SECURITY.md file to report any security issues with ESAPI.
+
+You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.5.3.1 release:
+ 207 Java source files
+ 4293 JUnit tests in 131 Java source files (0 failures, 0 errors, 0 tests skipped)
+
+ESAPI 2.5.4.0 release:
+ 207 Java source files
+ 4297 JUnit tests in 131 Java source files (0 failures, 0 errors, 0 tests skipped)
+
+8 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2023-12-01)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+824 DefaultEncoder / getCanonicalizedURI returns mix encoding for HTML special characters
+826 Fix Encoder.getCanonicalizedURI(URI) for the test case of a double-ampersand in the HTML Query
+827 HTMLEntityCodec Mysteriously decodes &or
+831 java.io.FileNotFoundException Error in Logs When ESAPI.properties and validation.properties are in resources. and the application is up ,features are not working.
+832 easpi .properties and validation properties are present but still it is throwing error and the application is failing do you have any solution for this
+835 Validator.isValidSafeHTML() is vulnerable as per CVE-2023-4780
+837 Validation does not work with esapi jakarta jar
+839 ConcurrentModificationException
+
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+Important Note affecting ESAPI 2.5.4.0 and later:
+* If you are using JUL for ESAPI logging, you will need to delete esapi-java-logging.properties file so it is not found as a resource stream. Failure to do so will result in a ConfigurationException being thrown. For details, see our GitHub wiki page, https://github.com/ESAPI/esapi-java-legacy/wiki/Configuring-the-JavaLogFactory
+
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it haveing first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (with your choice of supported SLF4J logging implemmentation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+None known, other than the remaining open issues on GitHub.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Minor updates to README.md file with respect to version information.
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.5.3.1 and 2.5.4.0, i.e., between 2023-12-01 and 2024-05-29)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+========================================================
+xeno6696 5 4 1
+jeremiahjstacey 2 4 1
+dependabot 1 1 1
+mpreziuso 1 2 1
+kwwall 11 6 0 (direct merge)
+========================================================
+ Total PRs: 4
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2023-12-01 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.5.3.1) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.6.1:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.5.4.0
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.9:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.5:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.5.0-M1:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.5:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.3.1:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.2.4:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.2.4:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.17:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.17:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.17:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.17:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.17:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.9:compile
+ [INFO] | +- org.htmlunit:neko-htmlunit:jar:3.11.1:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:2.0.13:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- commons-io:commons-io:jar:2.15.1:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.8.5:compile
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile
+ [INFO] +- commons-codec:commons-codec:jar:1.17.0:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk15on:jar:1.70:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.37:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.6.1:test
+ [INFO] ------------------------------------------------------------------------
+ [INFO] BUILD SUCCESS
+ [INFO] ------------------------------------------------------------------------
+ [INFO] Total time: 0.903 s
+ [INFO] Finished at: 2024-05-29T18:31:30-04:00
+ [INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ A special hat tip to Arshan Dabirsiaghis, original creator of AntiSamy and the creator of the antisamy-esapi.xml file, the ultrastrict AntiSamy policy used by ESAPI. That avoided a vulnerability that affected AntiSamy itself, so kudos to that foresite.
+ A shutout to Michele Preziuso for the PR that updated AntiSamy, added a test, and avoided the convergence issue that resulted in me having to reject the Snyk and Dependabot PRs. I appreciate you saving me having to do the work.
+ And special kudos to Jerry Devis for one of the best bug reports (GitHub issue #839) that I've seen since I began working on ESAPI in 2009. I hope your bug report can be an example to all. Excellent work.
+
+ Lastly, our usual special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.5.5.0-release-notes.txt b/documentation/esapi4java-core-2.5.5.0-release-notes.txt
new file mode 100644
index 000000000..69a4e6e77
--- /dev/null
+++ b/documentation/esapi4java-core-2.5.5.0-release-notes.txt
@@ -0,0 +1,199 @@
+Release notes for ESAPI 2.5.5.0
+ Release date: 2024-10-07
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.5.4.0, 2024-05-30
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a minor release. All changes should be backward compatible with the previous ESAPI version.
+The updates cover the following areas:
+* Updates to dependencies and Maven plugins.
+* New logging feature added which should be useful in cloud environments where you are paying for log storage.
+ See GitHub issue https://github.com/ESAPI/esapi-java-legacy/issues/844 for details.
+* Documentation clean-up.
+
+Notes if you are not updating from the immediate previous release. release 2.5.4.0:
+ * You need to read through the series of release notes FIRST, going in order.
+ * For example, if you were updating from an older ESAPI release (say, 2.3.0.0), you should go back and FIRST read all the subsequent release notes in turn. For instance, if you are currently on release 2.3.0.0 and upgrading to (say) release 2.x.y.z, you should MINIMALLY read the sections "Changes Requiring Special Attention" in each of the subsequent release notes. So, going from release 2.3.0.0 to 2.x.y.z, you should in turn, read:
+
+ esapi4java-core-2.4.0.0-release-notes.txt
+ esapi4java-core-2.5.0.0-release-notes.txt
+ esapi4java-core-2.5.1.0-release-notes.txt
+ esapi4java-core-2.5.2.0-release-notes.txt
+ ...etc., up through the current set of release notes...
+ esapi4java-core-2.x.y.z-release-notes.txt
+
+in that order. YOU HAVE BEEN WARNED!!! (These release notes are too large to put all this in a given document; very few read them thoroughly as it is.)
+
+If your SCA tool is reporting any CVE from a direct or transitive dependency in ESAPI, before reporting it as an GitHub issue, please make sure that you review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md. Please email us or contact us in our GitHub Discussions page if you have questions about this. See also the SECURITY.md file to report any security issues with ESAPI.
+
+You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.5.4.0 release:
+ 207 Java source files
+ 4297 JUnit tests in 131 Java source files (0 failures, 0 errors, 0 tests skipped)
+
+ESAPI 2.5.5.0 release:
+ 207 Java source files
+ 4315 JUnit tests in 133 Java source files (0 failures, 0 errors, 0 tests skipped)
+
+8 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive')
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2024-05-30)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+844 Update the logging properties to opt-out of the prefix events Component-Logger enhancement
+846 ESAPI.encoder().canonicalize() converts "&or" or similar strings without having trailing semicolon as logical operator
+847 Update ESAPI pom to use latest version of AntiSamy (1.7.6)
+851 Fix typos
+
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it haveing first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implemmentation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+None known, other than the remaining open issues on GitHub.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Minor updates to README.md file with respect to version information.
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.5.4.0 and 2.5.5.0, i.e., between 2024-05-30 and 2024-10-07)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+Note: This only lists merged PRs, not those that were closed as rejected.
+
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+============================================================
+DebajitKumarPhukan 7 1 1
+DarioViva42 57 44 1
+mickeyz07 10 12 1
+kwwall 11 8 2
+============================================================
+ Total PRs: 5
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2024-05-30 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.5.4.0) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ [INFO] -----------------------< org.owasp.esapi:esapi >------------------------
+ [INFO] Building ESAPI 2.5.5.0-SNAPSHOT
+ [INFO] --------------------------------[ jar ]---------------------------------
+ [INFO]
+ [INFO] --- maven-dependency-plugin:3.7.1:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.5.5.0-SNAPSHOT
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.9:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.5:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.5.0-M2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.6:compile
+ [INFO] | +- commons-io:commons-io:jar:2.16.1:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.3.1:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.2.4:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.2.5:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.17:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.17:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.17:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.17:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.17:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.9:compile
+ [INFO] | +- org.htmlunit:neko-htmlunit:jar:4.3.0:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:2.0.13:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.8.6:compile (optional)
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile (optional)
+ [INFO] +- commons-codec:commons-codec:jar:1.17.0:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk18on:jar:1.78.1:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.37:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.6.1:test
+ [INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ A special shout-out to our new ESAPI contributors, mickeyz07, DarioViva42, and DebajitKumarPhukan.
+ Another hat tip to Dave Wichers and the AntiSamy crew for promptly releasing AntiSamy 1.7.0. And thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.6.0.0-release-notes.txt b/documentation/esapi4java-core-2.6.0.0-release-notes.txt
new file mode 100644
index 000000000..1a9d41759
--- /dev/null
+++ b/documentation/esapi4java-core-2.6.0.0-release-notes.txt
@@ -0,0 +1,192 @@
+Release notes for ESAPI 2.6.0.0
+ Release date: 2024-11-25
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.5.5.0, 2024-10-08
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This ESAPI release removes the Validator.isValidSafeHTML methods and references to it from ESAPI code. We will NOT be replacing it. This is to fulfill GitHub Security Advisory https://github.com/ESAPI/esapi-java-legacy/security/advisories/GHSA-r68h-jhhj-9jvm and GitHub issue #859.
+
+ESAPI was also updated to use the latest version of AntiSamy, 1.7.7.
+
+Notes if you are not updating from the immediate previous release. release 2.5.5.0:
+ * You need to read through the series of release notes FIRST, going in order.
+ * For example, if you were updating from an older ESAPI release (say, 2.3.0.0), you should go back and FIRST read all the subsequent release notes in turn. For instance, if you are currently on release 2.3.0.0 and upgrading to (say) release 2.x.y.z, you should MINIMALLY read the sections "Changes Requiring Special Attention" in each of the subsequent release notes. So, going from release 2.3.0.0 to 2.x.y.z, you should in turn, read:
+
+ esapi4java-core-2.4.0.0-release-notes.txt
+ esapi4java-core-2.5.0.0-release-notes.txt
+ esapi4java-core-2.5.1.0-release-notes.txt
+ esapi4java-core-2.5.2.0-release-notes.txt
+ ...etc., up through the current set of release notes...
+ esapi4java-core-2.x.y.z-release-notes.txt
+
+in that order. YOU HAVE BEEN WARNED!!! (These release notes are too large to put all this in a given document; very few read them thoroughly as it is.)
+
+If your SCA tool is reporting any CVE from a direct or transitive dependency in ESAPI, before reporting it as an GitHub issue, please make sure that you review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md. Please email us or contact us in our GitHub Discussions page if you have questions about this. See also the SECURITY.md file to report any security issues with ESAPI.
+
+You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.5.5.0 release:
+ 207 Java source files
+ 4297 JUnit tests in 131 Java test files
+
+ESAPI 2.6.0.0 release:
+ 207 Java source files
+ 4312 JUnit tests in 133 Java source files
+
+2 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2024-10-08)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+204 DefalutValidator.isValidSafeHTML() doesn't work (wontfix)
+859 Remove deprecated Validator.isValidSafeHTML methods
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+Breaking Change - deprecated methods removed
+* As of 2.6.0.0, the methods Validator.isValidSafeHTML are deleted. We won't be bring them back. See https://github.com/ESAPI/esapi-java-legacy/security/advisories/GHSA-r68h-jhhj-9jvm and the associated Security Bulletin for details.
+
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it haveing first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implemmentation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+None known, other than the remaining open issues on GitHub.
+
+-----------------------------------------------------------------------------
+
+Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Minor updates to README.md file with respect to version information.
+
+-----------------------------------------------------------------------------
+
+Developer Activity Report (Changes between release 2.5.5.0 and 2.6.0.0, i.e., between 2024-10-08 and 2024-11-25)
+Generated manually (this time) -- all errors are the fault of kwwall and his inability to do simple arithmetic.
+Figures do not include rejected PRs.
+
+Developer Total Total Number # Merged
+(GitHub ID) commits of Files Changed PRs
+========================================================
+kwwall 15 13 1
+========================================================
+ Total PRs: 1
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2024-10-08 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.5.5.0) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.8.0:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.6.0.0-SNAPSHOT
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.9:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.5:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.5.0-M2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.7:compile
+ [INFO] | +- commons-io:commons-io:jar:2.18.0:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.4.1:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.3.1:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.3.1:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.18:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.18:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.18:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.18:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.18:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.10:compile
+ [INFO] | +- org.htmlunit:neko-htmlunit:jar:4.6.0:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:2.0.16:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.8.6:compile (optional)
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile (optional)
+ [INFO] +- commons-codec:commons-codec:jar:1.17.1:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk18on:jar:1.78.1:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.37:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.6.1:test
+ [INFO] ------------------------------------------------------------------------
+ [INFO] BUILD SUCCESS
+ [INFO] ------------------------------------------------------------------------
+ [INFO] Total time: 0.884 s
+ [INFO] Finished at: 2024-11-25T15:35:40-05:00
+ [INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ Another hat tip to Dave Wichers and the AntiSamy crew for promptly releasing AntiSamy 1.7.7. And thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.6.1.0-release-notes.txt b/documentation/esapi4java-core-2.6.1.0-release-notes.txt
new file mode 100644
index 000000000..e81f3bda0
--- /dev/null
+++ b/documentation/esapi4java-core-2.6.1.0-release-notes.txt
@@ -0,0 +1,189 @@
+Release notes for ESAPI 2.6.1.0
+ Release date: 2025-05-19
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.6.0.0, 2024-11-25
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a patch release with the primary intent of updating the AntiSamy dependency from v1.7.7 to v1.7.8. Among other fixes, AntiSamy 1.7.8 updated HttpClient 5.x to address CVE-2025-27820, which potentially could affect ESAPI users if they had customized their aAntiSamy Policy File (by default, antisamy-esapi.xml) to allow certain CSS constructs. (The default policy file does not allow CSS markup at all, and I don't believe that it would be exploitable via ESAPI.)
+
+
+Notes if you are not updating from the immediate previous release. release 2.6.0.0:
+ * You need to read through the series of release notes FIRST, going in order.
+ * For example, if you were updating from an older ESAPI release (say, 2.3.0.0), you should go back and FIRST read all the subsequent release notes in turn. For instance, if you are currently on release 2.3.0.0 and upgrading to (say) release 2.x.y.z, you should MINIMALLY read the sections "Changes Requiring Special Attention" in each of the subsequent release notes. So, going from release 2.3.0.0 to 2.x.y.z, you should in turn, read:
+
+ esapi4java-core-2.4.0.0-release-notes.txt
+ esapi4java-core-2.5.0.0-release-notes.txt
+ esapi4java-core-2.5.1.0-release-notes.txt
+ esapi4java-core-2.5.2.0-release-notes.txt
+ ...etc., up through the current set of release notes...
+ esapi4java-core-2.x.y.z-release-notes.txt
+
+in that order. YOU HAVE BEEN WARNED!!! (These release notes are too large to put all this in a given document; very few read them thoroughly as it is.)
+
+If your SCA tool is reporting any CVE from a direct or transitive dependency in ESAPI, before reporting it as an GitHub issue, please make sure that you review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md. Please email us or contact us in our GitHub Discussions page if you have questions about this. See also the SECURITY.md file to report any security issues with ESAPI.
+
+You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.6.0.0 release:
+ 207 Java source files
+ 4312 JUnit tests in 133 Java source files
+
+ESAPI 2.6.1.0 release:
+ 207 Java source files
+ 4312 JUnit tests in 133 Java source files
+
+9 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2024-11-25)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+204 DefalutValidator.isValidSafeHTML() doesn't work - bug, Component-Validator, imported, Milestone-Release2.2, Priority-Medium, wontfix
+838 Getting org.owasp.esapi.errors.ConfigurationException: java.lang.reflect.InvocationTargetException Encoder class (org.owasp.esapi.reference.DefaultEncoder) CTOR threw exception. - bug, wontfix
+858 Fail to run Linux command with double quotes using executeSystemCommand - question, ConvertedToDiscussion
+859 Remove deprecated Validator.isValidSafeHTML methods - bug (Note: fixed in previous release, 2.6.0.0)
+863 2.6.0.0 still using javax HttpServletRequest - enhancement, falsepositive
+867 How to turn off ESAPI logs or change its log level - question, ConvertedToDiscussion
+868 Do not depend on commons-collections4 milestone (use 4.4 instead) - bug, Vulnerable Dependencies, wontfix
+874 jakarta.servlet-api 5.0(Jakarta EE 9) change the package name from javax.xxx to jakarta.xxxx - enhancement, duplicate, NothingToFixHere
+876 Upgrade version of antisamy to 1.7.8 to update transitive dependency affected by CVE-2025-27820 - enhancement, duplicate, NothingToFixHere
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it haveing first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implemmentation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+None known, other than the remaining open issues on GitHub.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Changes since last release 2.6.0.0 and 2.6.1.0, i.e., changes between 2025-11-25 and 2025-05-19.
+
+ Note: I am no longer going to provide the 'Developer Activity Report' that I used to this manually create in tabluar form. This is in part because I use to use 'mvn site' to assist with its creation, but neither the 'Developer Activiity' nor 'File Activity' sections of the 'mvn site' output is currently working.
+
+ That said, I don't care as this was always a major PITA and I think it had dubious value to start with.
+
+ Therefore, I am replacing it to a stock GitHub tag comparison of the current and previous release, which I can automate.
+
+ Please see,
+
+ https://github.com/ESAPI/esapi-java-legacy/compare/esapi-2.6.0.0...esapi-2.6.1.0
+
+ for details. It contains all the information that the previous 'Developer Activity Reports' did and then some.
+
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2024-11-25 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.6.0.0) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.8.1:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.6.1.0
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.9:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.9.4:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.5:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.5.0-M2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.8:compile
+ [INFO] | +- commons-io:commons-io:jar:2.19.0:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.4.4:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.3.4:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.3.4:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.19:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.19:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.19:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.19:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.19:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.11:compile
+ [INFO] | +- org.htmlunit:neko-htmlunit:jar:4.11.0:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:2.0.16:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.9.3:compile (optional)
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile (optional)
+ [INFO] +- commons-codec:commons-codec:jar:1.17.1:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk18on:jar:1.78.1:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.37:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.6.1:test
+ [INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ A special thanks to the AntiSamy team in getting a new AntiSamy release out in short order. And thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.6.2.0-release-notes.txt b/documentation/esapi4java-core-2.6.2.0-release-notes.txt
new file mode 100644
index 000000000..a909feea2
--- /dev/null
+++ b/documentation/esapi4java-core-2.6.2.0-release-notes.txt
@@ -0,0 +1,180 @@
+Release notes for ESAPI 2.6.2.0
+ Release date: 2025-06-02
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.6.1.0, 2025-05-19
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a minor patch release with the intent of updating the Apache Commons BeanUtils dependency from v1.9.4 to v1.11.0 to CVE-2025-48734. This CVE wouuld only potentially affect application code that uses the ESAPI's AccessController component. It is extremently unlikely that anyone is using that because the default implmentation for that (the class "org.owasp.esapi.reference.DefaultAccessController") is really a toy implementation that doesn't scale to enterprise levels with out some customization. (The class "org.owasp.esapi.filters.ESAPIFilter" also uses "DefaultAccessController", but it is unlikely that anyone is using that either, unless they are using a customized AccessController implementation.) We plan to deprecate this ESAPI "DefaultAccessControler" shortly in a future release.
+
+Notes if you are not updating from the immediate previous release. release 2.6.1.0:
+ * You need to read through the series of release notes FIRST, going in order.
+ * For example, if you were updating from an older ESAPI release (say, 2.3.0.0), you should go back and FIRST read all the subsequent release notes in turn. For instance, if you are currently on release 2.3.0.0 and upgrading to (say) release 2.x.y.z, you should MINIMALLY read the sections "Changes Requiring Special Attention" in each of the subsequent release notes. So, going from release 2.3.0.0 to 2.x.y.z, you should in turn, read:
+
+ esapi4java-core-2.4.0.0-release-notes.txt
+ esapi4java-core-2.5.0.0-release-notes.txt
+ esapi4java-core-2.5.1.0-release-notes.txt
+ esapi4java-core-2.5.2.0-release-notes.txt
+ ...etc., up through the current set of release notes...
+ esapi4java-core-2.x.y.z-release-notes.txt
+
+in that order. YOU HAVE BEEN WARNED!!! (These release notes are too large to put all this in a given document; very few read them thoroughly as it is.)
+
+If your SCA tool is reporting any CVE from a direct or transitive dependency in ESAPI, before reporting it as an GitHub issue, please make sure that you review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md. Please email us or contact us in our GitHub Discussions page if you have questions about this. See also the SECURITY.md file to report any security issues with ESAPI.
+
+You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.6.1.0 release:
+ 207 Java source files
+ 4312 JUnit tests in 133 Java source files
+
+ESAPI 2.6.2.0 release:
+ 207 Java source files
+ 4312 JUnit tests in 133 Java source files
+
+1 GitHub Issue closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2025-05-19)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+883 Update Apache Commons BeanUtils from 1.9.4 to 1.11.0 to address CVE-2025-48734
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it haveing first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implemmentation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+None known, other than the remaining open issues on GitHub and that 'mvn site' fails to properly build some pieces as the ESAPI tag library Javadoc. I suspect this is related to problems with one or more of the Maven plugins.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Changes since last release 2.6.1.0 and 2.6.2.0, i.e., changes between 2025-05-19 and 2025-06-02).
+
+ Note: I am no longer going to provide the 'Developer Activity Report' that I used to this manually create in tabluar form. This is in part because I use to use 'mvn site' to assist with its creation, but neither the 'Developer Activiity' nor 'File Activity' sections of the 'mvn site' output is currently working.
+
+ That said, I don't care as this was always a major PITA and I think it had dubious value to start with.
+
+ Therefore, I am replacing it to a stock GitHub tag comparison of the current and previous release, which I can automate.
+
+ Please see,
+
+ https://github.com/ESAPI/esapi-java-legacy/compare/esapi-...esapi-2.6.2.0
+
+ for details. It contains all the information that the previous 'Developer Activity Reports' did and then some.
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2025-05-19 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.6.1.0) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.8.1:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.6.1.0
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.9:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.11.0:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.2:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.5:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.5.0-M2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.8:compile
+ [INFO] | +- commons-io:commons-io:jar:2.19.0:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.4.4:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.3.4:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.3.4:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.19:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.19:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.19:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.19:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.19:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.11:compile
+ [INFO] | +- org.htmlunit:neko-htmlunit:jar:4.11.0:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:2.0.16:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.9.3:compile (optional)
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile (optional)
+ [INFO] +- commons-codec:commons-codec:jar:1.17.1:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk18on:jar:1.78.1:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.37:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.6.1:test
+ [INFO] ------------------------------------------------------------------------
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ Thanks to GitHub Advanced Security's Dependabot SCA tool for flagging and fixing this one. And thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-core-2.7.0.0-release-notes.txt b/documentation/esapi4java-core-2.7.0.0-release-notes.txt
new file mode 100644
index 000000000..f88656067
--- /dev/null
+++ b/documentation/esapi4java-core-2.7.0.0-release-notes.txt
@@ -0,0 +1,194 @@
+Release notes for ESAPI 2.7.0.0
+ Release date: 2025-06-27
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI 2.6.2.0, 2025-06-02
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+This is a major patch release with the primary intent of addressing CVE-2025-5878. See https://nvd.nist.gov/vuln/detail/CVE-2025-5078 and especially Security Bulletin #13 (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin13.pdf) for details. It also updates Apache Commons FileUploads to 1.6.0 to address CVE-2025-48976. That CVE likely does not affect the HTTP.getFileUloads interfaces (which is the only methods that use that library), but we have not had time to analyze it fully given the CVE cited against ESAPI. Apache Commons BeanUtils was also updated to 1.11.0 to address CVE-2025-48734 which potentially could anyone using ESAPI's AccessController and has placed their access control policy in a place where an attacker may be overwrite it. That is highly unlikely, but better safe than sorry.
+
+This 2.7.0.0 release also has significant Javadoc clarifications. Security Bulletin #13 explains why.
+
+If you fail to read Security Bulletin #13 and you are affected by CVE-2025-5878, your application using ESAPI 2.7.0.0 will not work, so it is VERY IMPORTANT that you read that.
+
+Notes if you are NOT updating from the immediate previous release. release 2.6.2.0:
+ * You need to read through the series of release notes FIRST, going in order.
+ * For example, if you were updating from an older ESAPI release (say, 2.3.0.0), you should go back and FIRST read all the subsequent release notes in turn. For instance, if you are currently on release 2.3.0.0 and upgrading to (say) release 2.x.y.z, you should MINIMALLY read the sections "Changes Requiring Special Attention" in each of the subsequent release notes. So, going from release 2.3.0.0 to 2.x.y.z, you should in turn, read:
+
+ esapi4java-core-2.4.0.0-release-notes.txt
+ esapi4java-core-2.5.0.0-release-notes.txt
+ esapi4java-core-2.5.1.0-release-notes.txt
+ esapi4java-core-2.5.2.0-release-notes.txt
+ ...etc., up through the current set of release notes...
+ esapi4java-core-2.x.y.z-release-notes.txt
+
+in that order. YOU HAVE BEEN WARNED!!! (These release notes are too large to put all this in a given document; very few read them thoroughly as it is.)
+
+If your SCA tool is reporting any CVE from a direct or transitive dependency in ESAPI, before reporting it as an GitHub issue, please make sure that you review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md. Please email us or contact us in our GitHub Discussions page if you have questions about this. See also the SECURITY.md file to report any security issues with ESAPI.
+
+You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI 2.6.2.0 release:
+ 207 Java source files
+ 4312 JUnit tests in 133 Java source files
+
+ESAPI 2.7.0.0 release:
+ 208 Java source files
+ 4312 JUnit tests in 134 Java source files
+
+1 GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D2025-06-02)
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+883 Update Apache Commons BeanUtils from 1.9.4 to 1.11.0 to address CVE-2025-48734
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+
+IMPORTANT: Read Security Bulletin #13 (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/ESAPI-security-bulletin13.pdf)
+
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it having first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implementation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+None known, other than the remaining open issues on GitHub.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Changes since last release 2.6.2.0 and 2.7.0.0, i.e., changes between 2025-06-02 and 2025-06-27).
+
+ Note: I am no longer going to provide the 'Developer Activity Report' that I used to this manually create in tabular form. This is in part because I use to use 'mvn site' to assist with its creation, but neither the 'Developer Activity' nor 'File Activity' sections of the 'mvn site' output is currently working.
+
+ That said, I don't care as this was always a major PITA and I think it had dubious value to start with.
+
+ Therefore, I am replacing it to a stock GitHub tag comparison of the current and previous release, which I can automate.
+
+ Please see,
+
+ https://github.com/ESAPI/esapi-java-legacy/compare/esapi-...esapi-2.7.0.0
+
+ for details. It contains all the information that the previous 'Developer Activity Reports' did and then some.
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=2025-06-02 --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (2.6.2.0) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+ ...
+ [INFO] --- maven-dependency-plugin:3.8.1:tree (default-cli) @ esapi ---
+ [INFO] org.owasp.esapi:esapi:jar:2.7.0.0-SNAPSHOT
+ [INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
+ [INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.3.3:provided
+ [INFO] +- xom:xom:jar:1.3.9:compile
+ [INFO] +- commons-beanutils:commons-beanutils:jar:1.11.0:compile
+ [INFO] | +- commons-logging:commons-logging:jar:1.3.5:compile
+ [INFO] | \- commons-collections:commons-collections:jar:3.2.2:compile
+ [INFO] +- commons-configuration:commons-configuration:jar:1.10:compile
+ [INFO] +- commons-lang:commons-lang:jar:2.6:compile
+ [INFO] +- commons-fileupload:commons-fileupload:jar:1.6.0:compile
+ [INFO] +- org.apache.commons:commons-collections4:jar:4.5.0-M2:compile
+ [INFO] +- org.apache-extras.beanshell:bsh:jar:2.0b6:compile
+ [INFO] +- org.owasp.antisamy:antisamy:jar:1.7.8:compile
+ [INFO] | +- commons-io:commons-io:jar:2.19.0:compile
+ [INFO] | +- org.apache.httpcomponents.client5:httpclient5:jar:5.4.4:compile
+ [INFO] | | \- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.3.4:compile
+ [INFO] | +- org.apache.httpcomponents.core5:httpcore5:jar:5.3.4:compile
+ [INFO] | +- org.apache.xmlgraphics:batik-css:jar:1.19:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-shared-resources:jar:1.19:compile
+ [INFO] | | +- org.apache.xmlgraphics:batik-util:jar:1.19:compile
+ [INFO] | | | +- org.apache.xmlgraphics:batik-constants:jar:1.19:compile
+ [INFO] | | | \- org.apache.xmlgraphics:batik-i18n:jar:1.19:compile
+ [INFO] | | \- org.apache.xmlgraphics:xmlgraphics-commons:jar:2.11:compile
+ [INFO] | +- org.htmlunit:neko-htmlunit:jar:4.11.0:compile
+ [INFO] | +- xerces:xercesImpl:jar:2.12.2:compile
+ [INFO] | \- xml-apis:xml-apis-ext:jar:1.3.04:compile
+ [INFO] +- org.slf4j:slf4j-api:jar:2.0.16:compile
+ [INFO] +- xml-apis:xml-apis:jar:1.4.01:compile
+ [INFO] +- com.github.spotbugs:spotbugs-annotations:jar:4.9.3:compile (optional)
+ [INFO] | \- com.google.code.findbugs:jsr305:jar:3.0.2:compile (optional)
+ [INFO] +- commons-codec:commons-codec:jar:1.17.1:test
+ [INFO] +- junit:junit:jar:4.13.2:test
+ [INFO] +- org.bouncycastle:bcprov-jdk18on:jar:1.78.1:test
+ [INFO] +- org.hamcrest:hamcrest-core:jar:2.2:test
+ [INFO] | \- org.hamcrest:hamcrest:jar:2.2:test
+ [INFO] +- org.powermock:powermock-api-mockito2:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-api-support:jar:2.0.9:test
+ [INFO] +- org.mockito:mockito-core:jar:3.12.4:test
+ [INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.13:test
+ [INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.13:test
+ [INFO] | \- org.objenesis:objenesis:jar:3.2:test
+ [INFO] +- org.powermock:powermock-core:jar:2.0.9:test
+ [INFO] | \- org.javassist:javassist:jar:3.27.0-GA:test
+ [INFO] +- org.powermock:powermock-module-junit4:jar:2.0.9:test
+ [INFO] | \- org.powermock:powermock-module-junit4-common:jar:2.0.9:test
+ [INFO] +- org.powermock:powermock-reflect:jar:2.0.9:test
+ [INFO] \- org.openjdk.jmh:jmh-core:jar:1.37:test
+ [INFO] +- net.sf.jopt-simple:jopt-simple:jar:5.0.4:test
+ [INFO] \- org.apache.commons:commons-math3:jar:3.6.1:test
+ [INFO] ------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+
+Acknowledgments:
+ A whole bunch of folks to thank this time:
+ - Longlong Gong (uglory-gll) - The security researcher who discovered the vulnerability that became CVE-2025-5878.
+ Most people curse those who find CVEs in their software, but because of Longlong's work, we feel ESAPI is a better library and has a more secure future. (See the "Lessons Learned" section of Security Bulletin #13 for an explanation.)
+ - The VulDB CNA team.
+ - In no particular order, Jeff Williams, Matt Seil, Jeremiah Stacey, Erika von Kampen, Bill Sempf, and Ken Pyle, all who provided me with excellent feedback on the documentation and code changes and help me keep my sanity for the past 3 weeks.
+ - My wife for tolerating my long evenings for the past 3 weeks. I know I've been cranky and it's been stressful for us both, but thanks for being so understanding and supportive.
+ - And finally, thanks to all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/documentation/esapi4java-disa.JPG b/documentation/esapi4java-disa.JPG
new file mode 100644
index 000000000..5578904dc
Binary files /dev/null and b/documentation/esapi4java-disa.JPG differ
diff --git a/documentation/esapi4java-google-code.JPG b/documentation/esapi4java-google-code.JPG
new file mode 100644
index 000000000..b2878c08c
Binary files /dev/null and b/documentation/esapi4java-google-code.JPG differ
diff --git a/documentation/esapi4java-google-code.doc b/documentation/esapi4java-google-code.doc
new file mode 100644
index 000000000..67dca183a
Binary files /dev/null and b/documentation/esapi4java-google-code.doc differ
diff --git a/documentation/esapi4java-waf-2.0-policy-file-spec.docx b/documentation/esapi4java-waf-2.0-policy-file-spec.docx
new file mode 100644
index 000000000..719f91f3b
Binary files /dev/null and b/documentation/esapi4java-waf-2.0-policy-file-spec.docx differ
diff --git a/documentation/esapi4java-waf-2.0-policy-file-spec.pdf b/documentation/esapi4java-waf-2.0-policy-file-spec.pdf
new file mode 100644
index 000000000..401d251e4
Binary files /dev/null and b/documentation/esapi4java-waf-2.0-policy-file-spec.pdf differ
diff --git a/documentation/esapi4java-waf.JPG b/documentation/esapi4java-waf.JPG
new file mode 100644
index 000000000..80a104b02
Binary files /dev/null and b/documentation/esapi4java-waf.JPG differ
diff --git a/documentation/how-to-build-and-develop-with-intellij.md b/documentation/how-to-build-and-develop-with-intellij.md
new file mode 100644
index 000000000..c73fcdafa
--- /dev/null
+++ b/documentation/how-to-build-and-develop-with-intellij.md
@@ -0,0 +1,14 @@
+# How to Build and Develop ESAPI with IntelliJ
+
+IntelliJ is set up to run pretty seamlessly out of the box, but there are still a few configuration options we need to change in order to get Unit Tests to run properly.
+
+1. Click `Run` > `Edit Configurations...`
+2. Click `+` > `JUnit` to add a new Run Configuration for JUnit
+3. Set the `Name:` field to `JUnit Config`
+4. Set the `Test kind:` field to `All in package`
+5. Set the `Search for tests:` field to `In whole project`
+6. Set the `Working directory:` field to **your** project root directory (e.g. ~/workspace/esapi-java-legacy)
+
+In order to Run ESAPI with Tests, you just need to select `Run` > `Run 'JUnit Config' with Coverage`
+
+That's it!
diff --git a/javadoc.xml b/javadoc.xml
index 381d9eceb..791f62ae7 100644
--- a/javadoc.xml
+++ b/javadoc.xml
@@ -1,6 +1,6 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/javadoc/allclasses-frame.html b/javadoc/allclasses-frame.html
deleted file mode 100644
index 01beef047..000000000
--- a/javadoc/allclasses-frame.html
+++ /dev/null
@@ -1,222 +0,0 @@
-
-
-
-
-
-
-All Classes
-
-
-
-
-
-
-
-
-
-
-All Classes
-
-
-
-This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
-Overview
-
-
-
-The Overview page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.
-
-Package
-
-
-
-Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:
-
Interfaces (italic)
Classes
Exceptions
Errors
-
-
-Class/Interface
-
-
-
-Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
-
Class inheritance diagram
Direct Subclasses
All Known Subinterfaces
All Known Implementing Classes
Class/interface declaration
Class/interface description
-
-
Nested Class Summary
Field Summary
Constructor Summary
Method Summary
-
-
Field Detail
Constructor Detail
Method Detail
-Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
-
-Use
-
-Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
-
-Tree (Class Hierarchy)
-
-There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
-
When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
-
-
-Deprecated API
-
-The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
-
-Index
-
-The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
-
-Prev/Next
-These links take you to the next or previous class, interface, package, or related page.
-Frames/No Frames
-These links show and hide the HTML frames. All pages are available with or without frames.
-
-
-Serialized Form
-Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
-
-
-
-This help file applies to API documentation generated using the standard doclet.
-
-
-
The AccessReferenceMap interface is used to map from a set of internal
- direct object references to a set of indirect references that are safe to
- disclose publicly.
An AuthenticationHostException should be thrown when there is a problem with
- the host involved with authentication, particularly if the host changes unexpectedly.
Authenticates the user's credentials from the HttpServletRequest if
- necessary, creates a session if necessary, and sets the user as the
- current user.
-
Encodes or decodes two files from the command line;
- feel free to delete this method (in fact you probably should)
- if you're embedding this code into a larger program.
-
Extension to java.io.File to prevent against null byte injections and
- other unforeseen problems resulting from unprintable characters
- causing problems in path lookups.
Sets the content type on each HTTP response, to help protect against cross-site scripting attacks and other types
- of injection into HTML documents.
-
This method generates a redirect response that can only be used to redirect the browser to safe locations,
- as configured in the ESAPI security configuration.
-
A Base64.InputStream will read data from another
- java.io.InputStream, given in the constructor,
- and encode/decode to/from Base64 notation on the fly.
A Base64.OutputStream will write data to another
- java.io.OutputStream, given in the constructor,
- and encode/decode to/from Base64 notation on the fly.
Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
-
Updates the access reference map with a new set of directReferences, maintaining
- any existing indirectReferences associated with items that are in the new list.
-
The ValidationErrorList class defines a well-formed collection of
- ValidationExceptions so that groups of validation functions can be
- called in a non-blocking fashion.
A ValidationException should be thrown to indicate that the data provided by
- the user or from some other external source does not match the validation
- rules that have been specified for that data.
Verifies a seal (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or data mismatch.
-
Password character set, is alphanumerics (without l, i, I, o, O, and 0)
- selected specials like + (bad for URL encoding, | is like i and 1,
- etc...)
-
The Codec interface defines a set of methods for encoding and decoding application level encoding schemes,
- such as HTML entity encoding and percent encoding (aka URL encoding).
Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
-
The doFilter method of the Filter is called by the container each time a
- request/response pair is passed through the chain due to a client request
- for a resource at the end of the chain.
-
Return the URL without any changes, to prevent disclosure of the
- JSESSIONID The default implementation of this method can add the
- JSESSIONID to the URL if support for cookies is not detected.
-
Return the URL without any changes, to prevent disclosure of the
- JSESSIONID The default implementation of this method can add the
- JSESSIONID to the URL if support for cookies is not detected.
-
Return the URL without any changes, to prevent disclosure of the
- JSESSIONID The default implementation of this method can add the
- JSESSIONID to the URL if support for cookies is not detected.
-
Executes a system command after checking that the executable exists and
- that the parameters have not been subject to injection with untrusted
- user data.
-
The HTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests,
- responses, sessions, cookies, headers, and logging.
-The IAccessController interface defines a set of methods that can be used in a wide variety of applications to
- enforce access control. In most applications, access control must be performed in multiple different locations across
- the various applicaton layers. This class provides access control for URLs, business functions, data, services, and
- files.
-
-
-
- The implementation of this interface will need to access some sort of user information repository to determine what
- roles or permissions are assigned to the accountName passed into the various methods. In addition, the implementation
- will also need information about the resources that are being accessed. Using the user information and the resource
- information, the implementation should return an access control decision.
-
- Implementers are encouraged to build on existing access control mechanisms, such as methods like isUserInRole() or
- hasPrivilege(). While powerful, these methods can be confusing, as users may be in multiple roles or possess multiple
- overlapping privileges. These methods encourage the use of complex boolean tests throughout the code. The point of
- this interface is to centralize access control logic so that it is easy to use and easy to verify.
-
-
-
- Note that in the user interface layer, access control checks can be used to control whether particular controls are
- rendered or not. These checks are supposed to fail when an unauthorized user is logged in, and do not represent
- attacks. Remember that regardless of how the user interface appears, an attacker can attempt to invoke any business
- function or access any data in your application. Therefore, access control checks in the user interface should be
- repeated in both the business logic and data layers.
-
-
Checks if an account is authorized to access the referenced URL. The implementation should allow
- access to be granted to any part of the URL. Generally, this method should be invoked in the
- application's controller or a filter as follows:
-
Checks if an account is authorized to access the referenced function. The implementation should define the
- function "namespace" to be enforced. Choosing something simple like the classname of action classes or menu item
- names will make this implementation easier to use.
-
Checks if an account is authorized to access the referenced service. This can be used in applications that
- provide access to a variety of backend services.
-
Checks if an account is authorized to access the referenced URL. The implementation should allow
- access to be granted to any part of the URL. Generally, this method should be invoked in the
- application's controller or a filter as follows:
-
Checks if an account is authorized to access the referenced function. The implementation should define the
- function "namespace" to be enforced. Choosing something simple like the classname of action classes or menu item
- names will make this implementation easier to use.
-
Checks if an account is authorized to access the referenced service. This can be used in applications that
- provide access to a variety of backend services.
-
-The AccessReferenceMap interface is used to map from a set of internal
- direct object references to a set of indirect references that are safe to
- disclose publicly. This can be used to help protect database keys,
- filenames, and other types of direct object references. As a rule, developers
- should not expose their direct object references as it enables attackers to
- attempt to manipulate them.
-
-
-
-
- Indirect references are handled as strings, to facilitate their use in HTML.
- Implementations can generate simple integers or more complicated random
- character strings as indirect references. Implementations should probably add
- a constructor that takes a list of direct references.
-
- Note that in addition to defeating all forms of parameter tampering attacks,
- there is a side benefit of the AccessReferenceMap. Using random strings as indirect object
- references, as opposed to simple integers makes it impossible for an attacker to
- guess valid identifiers. So if per-user AccessReferenceMaps are used, then request
- forgery (CSRF) attacks will also be prevented.
-
-
- Set fileSet = new HashSet();
- fileSet.addAll(...); // add direct references (e.g. File objects)
- AccessReferenceMap map = new AccessReferenceMap( fileSet );
- // store the map somewhere safe - like the session!
- String indRef = map.getIndirectReference( file1 );
- String href = "http://www.aspectsecurity.com/esapi?file=" + indRef );
- ...
- // if the indirect reference doesn't exist, it's likely an attack
- // getDirectReference throws an AccessControlException
- // you should handle as appropriate
- String indref = request.getParameter( "file" );
- File file = (File)map.getDirectReference( indref );
-
-
-
-
-
-
-
-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
addDirectReference(java.lang.Object direct)
-
-
- Adds a direct reference to the AccessReferenceMap and generates an associated indirect reference.
-
-
-
- java.lang.Object
-
getDirectReference(java.lang.String indirectReference)
-
-
- Get the original direct object reference from an indirect reference.
-
-
-
- java.lang.String
-
getIndirectReference(java.lang.Object directReference)
-
-
- Get a safe indirect reference to use in place of a potentially sensitive
- direct object reference.
-
-
-
- java.util.Iterator
-
iterator()
-
-
- Get an iterator through the direct object references.
-
-
-
- java.lang.String
-
removeDirectReference(java.lang.Object direct)
-
-
- Removes a direct reference and its associated indirect reference from the AccessReferenceMap.
-
-
-
- void
-
update(java.util.Set directReferences)
-
-
- Updates the access reference map with a new set of directReferences, maintaining
- any existing indirectReferences associated with items that are in the new list.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Detail
-
-
-
-
-iterator
-
-public java.util.Iterator iterator()
-
-
Get an iterator through the direct object references. No guarantee is made as
- to the order of items returned.
-
Get a safe indirect reference to use in place of a potentially sensitive
- direct object reference. Developers should use this call when building
- URL's, form fields, hidden fields, etc... to help protect their private
- implementation information.
-
Get the original direct object reference from an indirect reference.
- Developers should use this when they get an indirect reference from a
- request to translate it back into the real direct reference. If an
- invalid indirectReference is requested, then an AccessControlException is
- thrown.
-
-
-
Parameters:
indirectReference - the indirect reference
-
Returns:
the direct reference
-
Throws:
-
AccessControlException - if no direct reference exists for the
- specified indirect reference
Updates the access reference map with a new set of directReferences, maintaining
- any existing indirectReferences associated with items that are in the new list.
-
-An AuthenticationException should be thrown when anything goes wrong during
- login or logout. They are also appropriate for any problems related to
- identity management.
-
AuthenticationAccountsException(java.lang.String userMessage,
- java.lang.String logMessage)
-
-
- Creates a new instance of EnterpriseSecurityException.
-
-
-
AuthenticationAccountsException(java.lang.String userMessage,
- java.lang.String logMessage,
- java.lang.Throwable cause)
-
-
- Instantiates a new authentication exception.
-An AuthenticationException should be thrown when anything goes wrong during
- login or logout. They are also appropriate for any problems related to
- identity management.
-
AuthenticationCredentialsException(java.lang.String userMessage,
- java.lang.String logMessage)
-
-
- Creates a new instance of EnterpriseSecurityException.
-
-
-
AuthenticationCredentialsException(java.lang.String userMessage,
- java.lang.String logMessage,
- java.lang.Throwable cause)
-
-
- Instantiates a new authentication exception.
-An AuthenticationException should be thrown when anything goes wrong during
- login or logout. They are also appropriate for any problems related to
- identity management.
-
-An AuthenticationHostException should be thrown when there is a problem with
- the host involved with authentication, particularly if the host changes unexpectedly.
-
-An AuthenticationException should be thrown when anything goes wrong during
- login or logout. They are also appropriate for any problems related to
- identity management.
-
-The Authenticator interface defines a set of methods for generating and
- handling account credentials and session identifiers. The goal of this
- interface is to encourage developers to protect credentials from disclosure
- to the maximum extent possible.
-
-
-
- One possible implementation relies on the use of a thread local variable to
- store the current user's identity. The application is responsible for calling
- setCurrentUser() as soon as possible after each HTTP request is received. The
- value of getCurrentUser() is used in several other places in this API. This
- eliminates the need to pass a user object to methods throughout the library.
- For example, all of the logging, access control, and exception calls need
- access to the currently logged in user.
-
- The goal is to minimize the responsibility of the developer for
- authentication. In this example, the user simply calls authenticate with the
- current request and the name of the parameters containing the username and
- password. The implementation should verify the password if necessary, create
- a session if necessary, and set the user as the current user.
-
-
- public void doPost(ServletRequest request, ServletResponse response) {
- try {
- User user = ESAPI.authenticator().login(request, response);
- // continue with authenticated user
- } catch (AuthenticationException e) {
- // handle failed authentication (it's already been logged)
- }
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- void
-
changePassword(User user,
- java.lang.String currentPassword,
- java.lang.String newPassword,
- java.lang.String newPassword2)
-
-
- Changes the password for the specified user.
createUser(java.lang.String accountName,
- java.lang.String password1,
- java.lang.String password2)
-
-
- Creates a new User with the information provided.
-
-
-
- boolean
-
exists(java.lang.String accountName)
-
-
- Determine if the account exists.
generateStrongPassword(User user,
- java.lang.String oldPassword)
-
-
- Generate strong password that takes into account the user's information and old password.
getUser(java.lang.String accountName)
-
-
- Returns the User matching the provided accountName.
-
-
-
- java.util.Set
-
getUserNames()
-
-
- Gets a collection containing all the existing user names.
-
-
-
- java.lang.String
-
hashPassword(java.lang.String password,
- java.lang.String accountName)
-
-
- Returns a string representation of the hashed password, using the
- accountName as the salt.
login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Authenticates the user's credentials from the HttpServletRequest if
- necessary, creates a session if necessary, and sets the user as the
- current user.
verifyAccountNameStrength(java.lang.String accountName)
-
-
- Ensures that the account name passes site-specific complexity requirements, like minimum length.
-
-
-
- boolean
-
verifyPassword(User user,
- java.lang.String password)
-
-
- Verify that the supplied password matches the password for this user.
-
-
-
- void
-
verifyPasswordStrength(java.lang.String oldPassword,
- java.lang.String newPassword)
-
-
- Ensures that the password meets site-specific complexity requirements.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Detail
-
-
-
-
-clearCurrent
-
-public void clearCurrent()
-
-
Clear the current user. This allows the thread to be reused safely.
-
Authenticates the user's credentials from the HttpServletRequest if
- necessary, creates a session if necessary, and sets the user as the
- current user.
-
-
-
Parameters:
request - the current HTTP request
response - the response
-
Returns:
the user
-
Throws:
-
AuthenticationException - if the credentials are not verified, or if the account is disabled, locked, expired, or timed out
Verify that the supplied password matches the password for this user. This method
- is typically used for "reauthentication" for the most sensitive functions, such
- as transactions, changing email address, and changing other account information.
-
-
-
Parameters:
user - the user
password - the password
-
Returns:
true, if the password is correct for the specified user
Creates a new User with the information provided. Implementations should check the
- accountName and password for proper format and strength against brute force attacks.
- Two copies of the new password are required to encourage user interface designers to
- include a "re-type password" field in their forms. Implementations should verify that both are the
- same.
-
-
-
Parameters:
accountName - the account name of the new user
password1 - the password of the new user
password2 - the password of the new user. This field is to encourage user interface designers to include two password fields in their forms.
-
Generate a strong password. Implementations should use a large character set that does not
- include confusing characters, such as i I 1 l 0 o and O. There are many algorithms to
- generate strong memorable passwords that have been studied in the past.
-
Generate strong password that takes into account the user's information and old password. Implementations
- should verify that the new password does not include information such as the username, fragments of the
- old password, and other information that could be used to weaken the strength of the password.
-
-
-
Parameters:
user - the user whose information to use when generating password
oldPassword - the old password to use when verifying strength of new password. The new password may be checked for fragments of oldPassword.
-
Changes the password for the specified user. This requires the current password, as well as
- the password to replace it with. This new password must be repeated to ensure that the user has
- typed it in correctly.
-
-
-
Parameters:
user - the user to change the password for
currentPassword - the current password for the specified user
newPassword - the new password to use
newPassword2 - a verification copy of the new password
-
Returns a string representation of the hashed password, using the
- accountName as the salt. The salt helps to prevent against "rainbow"
- table attacks where the attacker pre-calculates hashes for known strings.
- This method specifies the use of the user's account name as the "salt"
- value. The Encryptor.hash method can be used if a different salt is
- required.
-
-
-
Parameters:
password - the password to hash
accountName - the account name to use as the salt
-
Ensures that the password meets site-specific complexity requirements. This
- method takes the old password so that the algorithm can analyze the new password
- to see if it is too similar to the old password. Note that this has to be
- invoked when the user has entered the old password, as the list of old
- credentials stored by ESAPI is all hashed.
-
-
-
Parameters:
oldPassword - the old password
newPassword - the new password
-
Returns:
true, if the new password meets complexity requirements and is not too similar to the old password
-
Throws:
-
AuthenticationException - if newPassword is too similar to oldPassword or if newPassword does not meet complexity requirements
-An AvailabilityException should be thrown when the availability of a limited
- resource is in jeopardy. For example, if a database connection pool runs out
- of connections, an availability exception should be thrown.
-
-ESAPI locator class to make it easy to get a concrete implementation of the
- various ESAPI classes. Use the setters to override the reference implementations
- with instances of any custom ESAPI implementations.
-
-The Encoder interface contains a number of methods related to encoding input
- so that it will be safe for a variety of interpreters. To prevent
- double-encoding, all encoding methods should first check to see that the
- input does not already contain encoded characters. There are a few methods
- related to decoding that are used for canonicalization purposes. See the
- Validator class for more information.
-
-
-
- All of the methods here must use a "whitelist" or "positive" security model,
- meaning that all characters should be encoded, except for a specific list of
- "immune" characters that are known to be safe.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
CHAR_PASSWORD_LOWERS
-
-
- Password character set, is alphanumerics (without l, i, I, o, O, and 0)
- selected specials like + (bad for URL encoding, | is like i and 1,
- etc...)
canonicalize(java.lang.String input)
-
-
- This method performs canonicalization on data received to ensure that it
- has been reduced to its most basic form before validation.
encodeForCSS(java.lang.String input)
-
-
- Encode data for use in Cascading Style Sheets (CSS) content.
-
-
-
- java.lang.String
-
encodeForDN(java.lang.String input)
-
-
- Encode data for use in an LDAP distinguished name.
-
-
-
- java.lang.String
-
encodeForHTML(java.lang.String input)
-
-
- Encode data for use in HTML content.
-
-
-
- java.lang.String
-
encodeForHTMLAttribute(java.lang.String input)
-
-
- Encode data for use in HTML attributes.
-
-
-
- java.lang.String
-
encodeForJavaScript(java.lang.String input)
-
-
- Encode data for insertion inside a data value in JavaScript.
-
-
-
- java.lang.String
-
encodeForLDAP(java.lang.String input)
-
-
- Encode data for use in LDAP queries.
-
-
-
- java.lang.String
-
encodeForSQL(Codec codec,
- java.lang.String input)
-
-
- Encode for SQL according to the selected codec.
-
-
-
- java.lang.String
-
encodeForURL(java.lang.String input)
-
-
- Encode for use in a URL.
-
-
-
- java.lang.String
-
encodeForVBScript(java.lang.String input)
-
-
- Encode data for insertion inside a data value in a visual basic script.
-
-
-
- java.lang.String
-
encodeForXML(java.lang.String input)
-
-
- Encode data for use in an XML element.
-
-
-
- java.lang.String
-
encodeForXMLAttribute(java.lang.String input)
-
-
- Encode data for use in an XML attribute.
-
-
-
- java.lang.String
-
encodeForXPath(java.lang.String input)
-
-
- Encode data for use in an XPath query.
-
-
-
- java.lang.String
-
normalize(java.lang.String input)
-
-
- Reduce all non-ascii characters to their ASCII form so that simpler
- validation rules can be applied.
-
-
-
-
-
-
-
-
-
-
-
-Field Detail
-
-
-
-
-CHAR_LOWERS
-
-public static final char[] CHAR_LOWERS
-
-
Standard character sets
-
-
-
-
-
-
-
-CHAR_UPPERS
-
-public static final char[] CHAR_UPPERS
-
-
-
-
-
-
-
-CHAR_DIGITS
-
-public static final char[] CHAR_DIGITS
-
-
-
-
-
-
-
-CHAR_SPECIALS
-
-public static final char[] CHAR_SPECIALS
-
-
-
-
-
-
-
-CHAR_LETTERS
-
-public static final char[] CHAR_LETTERS
-
-
-
-
-
-
-
-CHAR_ALPHANUMERICS
-
-public static final char[] CHAR_ALPHANUMERICS
-
-
-
-
-
-
-
-CHAR_PASSWORD_LOWERS
-
-public static final char[] CHAR_PASSWORD_LOWERS
-
-
Password character set, is alphanumerics (without l, i, I, o, O, and 0)
- selected specials like + (bad for URL encoding, | is like i and 1,
- etc...)
-
-
-
-
-
-
-
-CHAR_PASSWORD_UPPERS
-
-public static final char[] CHAR_PASSWORD_UPPERS
-
-
-
-
-
-
-
-CHAR_PASSWORD_DIGITS
-
-public static final char[] CHAR_PASSWORD_DIGITS
-
-
-
-
-
-
-
-CHAR_PASSWORD_SPECIALS
-
-public static final char[] CHAR_PASSWORD_SPECIALS
This method performs canonicalization on data received to ensure that it
- has been reduced to its most basic form before validation. For example,
- URL-encoded data received from ordinary "application/x-www-url-encoded"
- forms so that it may be validated properly.
-
- Canonicalization is simply the operation of reducing a possibly encoded
- string down to its simplest form. This is important, because attackers
- frequently use encoding to change their input in a way that will bypass
- validation filters, but still be interpreted properly by the target of
- the attack. Note that data encoded more than once is not something that a
- normal user would generate and should be regarded as an attack.
-
- For input that comes from an HTTP servlet request, there are generally
- two types of encoding to be concerned with. The first is
- "applicaton/x-www-url-encoded" which is what is typically used in most
- forms and URI's where characters are encoded in a %xy format. The other
- type of common character encoding is HTML entity encoding, which uses
- several formats:
-
-
<
,
-
u
, and
-
:
.
-
- Note that all of these formats may possibly render properly in a
- browser without the trailing semi-colon.
-
- Double-encoding is a particularly thorny problem, as applying ordinary decoders
- may introduce encoded characters, even characters encoded with a different
- encoding scheme. For example %26lt; is a < character which has been entity encoded
- and then the first character has been url-encoded. Implementations should
- throw an IntrusionException when double-encoded characters are detected.
-
- Note that there is also "multipart/form" encoding, which allows files and
- other binary data to be transmitted. Each part of a multipart form can
- itself be encoded according to a "Content-Transfer-Encoding" header. See
- the HTTPUtilties.getSafeFileUploads() method.
-
- For more information on form encoding, please refer to the W3C
- specifications.
-
Reduce all non-ascii characters to their ASCII form so that simpler
- validation rules can be applied. For example, an accented-e character
- will be changed into a regular ASCII e character.
-
Encode data for insertion inside a data value in JavaScript. Putting user data directly
- inside a script is quite dangerous. Great care must be taken to prevent putting user data
- directly into script code itself, as no amount of encoding will prevent attacks there.
-
Encode data for insertion inside a data value in a visual basic script. Putting user data directly
- inside a script is quite dangerous. Great care must be taken to prevent putting user data
- directly into script code itself, as no amount of encoding will prevent attacks there.
-
Encode data for use in an XML element. The implementation should follow the XML Encoding
- Standard from the W3C.
-
- The use of a real XML parser is strongly encouraged. However, in the
- hopefully rare case that you need to make sure that data is safe for
- inclusion in an XML document and cannot use a parse, this method provides
- a safe mechanism to do so.
-
Encode data for use in an XML attribute. The implementation should follow
- the XML Encoding
- Standard from the W3C.
-
- The use of a real XML parser is highly encouraged. However, in the
- hopefully rare case that you need to make sure that data is safe for
- inclusion in an XML document and cannot use a parse, this method provides
- a safe mechanism to do so.
-
-
-
Parameters:
input - the text to encode for use as an XML attribute
-
Decode from URL. Implementations should first canonicalize and
- detect any double-encoding. If this check passes, then the data is decoded using URL
- decoding.
-
-The EncryptedProperties interface represents a properties file where all the data is
- encrypted before it is added, and decrypted when it retrieved. This interface can be
- implemented in a number of ways, the simplest being extending Properties and overloading
- the getProperty and setProperty methods.
-
-
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
getProperty(java.lang.String key)
-
-
- Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller.
setProperty(java.lang.String key,
- java.lang.String value)
-
-
- Encrypts the plaintext property value and stores the ciphertext value in the encrypted store.
-The Encryptor interface provides a set of methods for performing common
- encryption, random number, and hashing operations. Implementations should
- rely on a strong cryptographic implementation, such as JCE or BouncyCastle.
- Implementors should take care to ensure that they initialize their
- implementation with a strong "master key", and that they protect this secret
- as much as possible.
-
-
-
- Possible future enhancements (depending on feedback) might include:
-
-
encryptFile
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
decrypt(java.lang.String ciphertext)
-
-
- Decrypts the provided ciphertext string (encrypted with the encrypt
- method) and returns a plaintext string.
-
-
-
- java.lang.String
-
encrypt(java.lang.String plaintext)
-
-
- Encrypts the provided plaintext and returns a ciphertext string.
-
-
-
- long
-
getRelativeTimeStamp(long offset)
-
-
- Gets an absolute timestamp representing an offset from the current time to be used by
- other functions in the library.
-
-
-
- long
-
getTimeStamp()
-
-
- Gets a timestamp representing the current date and time to be used by
- other functions in the library.
-
-
-
- java.lang.String
-
hash(java.lang.String plaintext,
- java.lang.String salt)
-
-
- Returns a string representation of the hash of the provided plaintext and
- salt.
-
-
-
- java.lang.String
-
seal(java.lang.String data,
- long timestamp)
-
-
- Creates a seal that binds a set of data and includes an expiration timestamp.
-
-
-
- java.lang.String
-
sign(java.lang.String data)
-
-
- Create a digital signature for the provided data and return it in a
- string.
-
-
-
- java.lang.String
-
unseal(java.lang.String seal)
-
-
- Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
-
-
-
- boolean
-
verifySeal(java.lang.String seal)
-
-
- Verifies a seal (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or data mismatch.
-
-
-
- boolean
-
verifySignature(java.lang.String signature,
- java.lang.String data)
-
-
- Verifies a digital signature (created with the sign method) and returns
- the boolean result.
Returns a string representation of the hash of the provided plaintext and
- salt. The salt helps to protect against a rainbow table attack by mixing
- in some extra data with the plaintext. Some good choices for a salt might
- be an account name or some other string that is known to the application
- but not to an attacker. See this article for
- more information about hashing as it pertains to password schemes.
-
-
-
Parameters:
plaintext - the plaintext String to encrypt
salt - the salt
-
Returns:
the encrypted hash of 'plaintext' stored as a String
-
Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
-
-
-
Parameters:
seal - the sealed data
-
Returns:
the original data
-
Throws:
-
ExcryptionException - if the unsealed data cannot be retrieved for any reason
-
Verifies a seal (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or data mismatch.
-
-
-
Parameters:
seal - the seal
-
Returns:
true, if the seal is valid
-
-
-
-
-
-getRelativeTimeStamp
-
-public long getRelativeTimeStamp(long offset)
-
-
Gets an absolute timestamp representing an offset from the current time to be used by
- other functions in the library.
-
-
-
Parameters:
offset - the offset to add to the current time
-
Returns:
the absolute timestamp
-
-
-
-
-
-getTimeStamp
-
-public long getTimeStamp()
-
-
Gets a timestamp representing the current date and time to be used by
- other functions in the library.
-
-EnterpriseSecurityException is the base class for all security related exceptions. You should pass in the root cause
- exception where possible. Constructors for classes extending EnterpriseSecurityException should be sure to call the
- appropriate super() method in order to ensure that logging and intrusion detection occur properly.
-
- All EnterpriseSecurityExceptions have two messages, one for the user and one for the log file. This way, a message
- can be shown to the user that doesn't contain sensitive information or unnecessary implementation details. Meanwhile,
- all the critical information can be included in the exception so that it gets logged.
-
- Note that the "logMessage" for ALL EnterpriseSecurityExceptions is logged in the log file. This feature should be
- used extensively throughout ESAPI implementations and the result is a fairly complete set of security log records.
- ALL EnterpriseSecurityExceptions are also sent to the IntrusionDetector for use in detecting anomolous patterns of
- application usage.
-
EnterpriseSecurityException(java.lang.String userMessage,
- java.lang.String logMessage)
-
-
- Creates a new instance of EnterpriseSecurityException.
-
-
-
EnterpriseSecurityException(java.lang.String userMessage,
- java.lang.String logMessage,
- java.lang.Throwable cause)
-
-
- Creates a new instance of EnterpriseSecurityException that includes a root cause Throwable.
Creates a new instance of EnterpriseSecurityException. This exception is automatically logged, so that simply by
- using this API, applications will generate an extensive security log. In addition, this exception is
- automatically registered with the IntrusionDetector, so that quotas can be checked.
-
-The Executor interface is used to run an OS command with reduced security risk.
- Implementations should do as much as possible to minimize the risk of
- injection into either the command or parameters. In addition, implementations
- should timeout after a specified time period in order to help prevent denial
- of service attacks. The class should perform logging and error handling as
- well. Finally, implementation should handle errors and generate an
- ExecutorException with all the necessary information.
-
-
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
executeSystemCommand(java.io.File executable,
- java.util.List params,
- java.io.File workdir,
- int timeoutSeconds)
-
-
- Executes a system command after checking that the executable exists and
- that the parameters have not been subject to injection with untrusted
- user data.
Executes a system command after checking that the executable exists and
- that the parameters have not been subject to injection with untrusted
- user data. Implementations shall change to the specified working
- directory before invoking the command. Also, processes should be
- interrupted after the specified timeout period has elapsed.
-
-
-
Parameters:
params - the parameters of the command being executed
workdir - the working directory
timeoutSeconds - the amount of time to allow this process to run
-
-The HTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests,
- responses, sessions, cookies, headers, and logging.
-
-
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
addCSRFToken(java.lang.String href)
-
-
- Adds the current user's CSRF token (see User.getCSRFToken()) to the URL for purposes of preventing CSRF attacks.
-
-
-
- void
-
assertSecureRequest(javax.servlet.http.HttpServletRequest request)
-
-
- Ensures that the current request uses SSL and POST to protect any sensitive parameters
- in the querystring from being sniffed or logged.
-
-
-
- javax.servlet.http.HttpSession
-
changeSessionIdentifier(javax.servlet.http.HttpServletRequest request)
-
-
- Invalidate the old session after copying all of its contents to a newly created session with a new session id.
-
-
-
- java.lang.String
-
decryptHiddenField(java.lang.String encrypted)
-
-
- Decrypts an encrypted hidden field value and returns the cleartext.
-
-
-
- java.util.Map
-
decryptQueryString(java.lang.String encrypted)
-
-
- Takes an encrypted querystring and returns a Map containing the original parameters.
-
-
-
- java.util.Map
-
decryptStateFromCookie(javax.servlet.http.HttpServletRequest request)
-
-
- Retrieves a map of data from a cookie encrypted with encryptStateInCookie().
-
-
-
- java.lang.String
-
encryptHiddenField(java.lang.String value)
-
-
- Encrypts a hidden field value for use in HTML.
-
-
-
- java.lang.String
-
encryptQueryString(java.lang.String query)
-
-
- Takes a querystring (i.e.
-
-
-
- void
-
encryptStateInCookie(javax.servlet.http.HttpServletResponse response,
- java.util.Map cleartext)
-
-
- Stores a Map of data in an encrypted cookie.
-
-
-
- javax.servlet.http.Cookie
-
getCookie(javax.servlet.http.HttpServletRequest request,
- java.lang.String name)
-
-
- Get the first cookie with the matching name.
-
-
-
- java.lang.String
-
getCSRFToken()
-
-
- Returns the current user's CSRF token.
getSafeFileUploads(javax.servlet.http.HttpServletRequest request,
- java.io.File tempDir,
- java.io.File finalDir)
-
-
- Extract uploaded files from a multipart HTTP requests.
-
-
-
- void
-
killAllCookies(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Kill all cookies received in the last request from the browser.
-
-
-
- void
-
killCookie(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response,
- java.lang.String name)
-
-
- Kills the specified cookie by setting a new cookie that expires immediately.
-
-
-
- void
-
logHTTPRequest(javax.servlet.http.HttpServletRequest request,
- Logger logger)
-
-
- Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file.
-
-
-
- void
-
logHTTPRequest(javax.servlet.http.HttpServletRequest request,
- Logger logger,
- java.util.List parameterNamesToObfuscate)
-
-
- Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file.
-
-
-
- void
-
safeSendForward(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response,
- java.lang.String context,
- java.lang.String location)
-
-
- This method perform a forward to any resource located inside the WEB-INF directory.
-
-
-
- void
-
safeSetContentType(javax.servlet.http.HttpServletResponse response)
-
-
- Sets the content type on each HTTP response, to help protect against cross-site scripting attacks and other types
- of injection into HTML documents.
-
-
-
- void
-
setCurrentHTTP(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Stores the current HttpRequest and HttpResponse so that they may be readily accessed throughout
- ESAPI (and elsewhere)
-
-
-
- void
-
setNoCacheHeaders(javax.servlet.http.HttpServletResponse response)
-
-
- Set headers to protect sensitive information against being cached in the browser.
-
-
-
- java.lang.String
-
setRememberToken(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response,
- java.lang.String password,
- int maxAge,
- java.lang.String domain,
- java.lang.String path)
-
-
- Set a cookie containing the current User's remember me token for automatic authentication.
-
-
-
- void
-
verifyCSRFToken(javax.servlet.http.HttpServletRequest request)
-
-
- Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and
- throws an IntrusionException if it is missing.
-
-
-
-
-
-
-
-
-
-
-
-Field Detail
-
-
-
-
-REMEMBER_TOKEN_COOKIE_NAME
-
-public static final java.lang.String REMEMBER_TOKEN_COOKIE_NAME
Ensures that the current request uses SSL and POST to protect any sensitive parameters
- in the querystring from being sniffed or logged. For example, this method should
- be called from any method that uses sensitive data from a web form.
-
- This method uses getCurrentRequest() to obtain the current HttpServletRequest object
-
Adds the current user's CSRF token (see User.getCSRFToken()) to the URL for purposes of preventing CSRF attacks.
- This method should be used on all URLs to be put into all links and forms the application generates.
-
-
-
Parameters:
href - the URL to which the CSRF token will be appended
-
Returns:
the updated URL with the CSRF token parameter added
Invalidate the old session after copying all of its contents to a newly created session with a new session id.
- Note that this is different from logging out and creating a new session identifier that does not contain the
- existing session contents. Care should be taken to use this only when the existing session does not contain
- hazardous contents.
-
- This method uses getCurrentRequest() to obtain the current HttpSession object
-
Decrypts an encrypted hidden field value and returns the cleartext. If the field does not decrypt properly,
- an IntrusionException is thrown to indicate tampering.
-
Set a cookie containing the current User's remember me token for automatic authentication. The use of remember me tokens
- is generally not recommended, but this method will help do it as safely as possible. The user interface should strongly warn
- the user that this should only be enabled on computers where no other users will have access.
-
- The username can be retrieved with: User username = ESAPI.authenticator().getCurrentUser();
-
-
-
Parameters:
password - the user's password
maxAge - the length of time that the token should be valid for in relative seconds
domain - the domain to restrict the token to or null
path - the path to restrict the token to or null
-
Extract uploaded files from a multipart HTTP requests. Implementations must check the content to ensure that it
- is safe before making a permanent copy on the local filesystem. Checks should include length and content checks,
- possibly virus checking, and path and name checks. Refer to the file checking methods in Validator for more
- information.
-
- This method uses getCurrentRequest() to obtain the HttpServletRequest object
-
Kill all cookies received in the last request from the browser. Note that new cookies set by the application in
- this response may not be killed by this method.
-
Kills the specified cookie by setting a new cookie that expires immediately. Note that this
- method does not delete new cookies that are being set by the application for this response.
-
Stores a Map of data in an encrypted cookie. Generally the session is a better
- place to store state information, as it does not expose it to the user at all.
- If there is a requirement not to use sessions, or the data should be stored
- across sessions (for a long time), the use of encrypted cookies is an effective
- way to prevent the exposure.
-
This method perform a forward to any resource located inside the WEB-INF directory. Forwarding to
- publicly accessible resources can be dangerous, as the request will have already passed the URL
- based access control check. This method ensures that you can only forward to non-publicly
- accessible resources.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
Sets the content type on each HTTP response, to help protect against cross-site scripting attacks and other types
- of injection into HTML documents.
-
Set headers to protect sensitive information against being cached in the browser. Developers should make this
- call for any HTTP responses that contain any sensitive data that should not be cached within the browser or any
- intermediate proxies or caches. Implementations should set headers for the expected browsers. The safest approach
- is to set all relevant headers to their most restrictive setting. These include:
-
-
-
- Note that the header "pragma: no-cache" is only useful in HTTP requests, not HTTP responses. So even though there
- are many articles recommending the use of this header, it is not helpful for preventing browser caching. For more
- information, please refer to the relevant standards:
-
Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file. Be careful not
- to log sensitive information, and consider masking with the
- logHTTPRequest( List parameterNamesToObfuscate ) method.
-
Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file. The list of parameters to
- obfuscate should be specified in order to prevent sensitive information
- from being logged. If a null list is provided, then all parameters will
- be logged. If HTTP request logging is done in a central place, the
- parameterNamesToObfuscate could be made a configuration parameter. We
- include it here in case different parts of the application need to obfuscate
- different parameters.
-
- This method uses getCurrentResponse() to obtain the HttpServletResponse object
-
-
-
Parameters:
logger - the logger to write the request to
parameterNamesToObfuscate - the sensitive parameters
-An AvailabilityException should be thrown when the availability of a limited
- resource is in jeopardy. For example, if a database connection pool runs out
- of connections, an availability exception should be thrown.
-
-The IntrusionDetector interface is intended to track security relevant events and identify attack behavior. The
- implementation can use as much state as necessary to detect attacks, but note that storing too much state will burden
- your system.
-
-
-
-
- The interface is currently designed to accept exceptions as well as custom events. Implementations can use this
- stream of information to detect both normal and abnormal behavior.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- void
-
addEvent(java.lang.String eventName,
- java.lang.String logMessage)
-
-
- Adds the event to the IntrusionDetector.
-
-
-
- void
-
addException(java.lang.Exception exception)
-
-
- Adds the exception to the IntrusionDetector.
-An IntrusionException should be thrown anytime an error condition arises that is likely to be the result of an attack
- in progress. IntrusionExceptions are handled specially by the IntrusionDetector, which is equipped to respond by
- either specially logging the event, logging out the current user, or invalidating the current user's account.
-
- Unlike other exceptions in the ESAPI, the IntrusionException is a RuntimeException so that it can be thrown from
- anywhere and will not require a lot of special exception handling.
-
-The LogFactory interface is intended to allow substitution of various logging packages, while providing
- a common interface to access them.
-
- In the default implementation, JavaLogFactory.java implements this interface. JavaLogFactory.java also contains an
- inner class called JavaLogger which implements Logger.java and uses the Java logging package to log events.
-
-The Logger interface defines a set of methods that can be used to log
- security events. Implementors should use a well established logging library
- as it is quite difficult to create a high-performance logger.
-
-
-
-
- The order of logging levels is:
-
-
trace
-
debug
-
info
-
warn
-
error
-
fatal (the most serious)
-
-
- In the default implementation, this interface is implemented by JavaLogger.class, which is an inner class in JavaLogFactory.java
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-Reference implementation of the AccessReferenceMap interface. This
- implementation generates random 6 character alphanumeric strings for indirect
- references. It is possible to use simple integers as indirect references, but
- the random string approach provides a certain level of protection from CSRF
- attacks, because an attacker would have difficulty guessing the indirect
- reference.
-
RandomAccessReferenceMap()
-
-
- This AccessReferenceMap implementation uses short random strings to
- create a layer of indirection.
-
-
-
RandomAccessReferenceMap(java.util.Set directReferences)
-
-
- Instantiates a new access reference map.
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
addDirectReference(java.lang.Object direct)
-
-
- Adds a direct reference and a new random indirect reference, overwriting any existing values.
-
-
-
- java.lang.Object
-
getDirectReference(java.lang.String indirectReference)
-
-
- Get the original direct object reference from an indirect reference.
-
-
-
- java.lang.String
-
getIndirectReference(java.lang.Object directReference)
-
-
- Get a safe indirect reference to use in place of a potentially sensitive
- direct object reference.
-
-
-
- java.util.Iterator
-
iterator()
-
-
- Get an iterator through the direct object references.
-
-
-
- java.lang.String
-
removeDirectReference(java.lang.Object direct)
-
-
- Remove a direct reference and the corresponding indirect reference.
-
-
-
- void
-
update(java.util.Set directReferences)
-
-
- This preserves any existing mappings for items that are still in the new
- list.
This AccessReferenceMap implementation uses short random strings to
- create a layer of indirection. Other possible implementations would use
- simple integers as indirect references.
-
-public final void update(java.util.Set directReferences)
-
-
This preserves any existing mappings for items that are still in the new
- list. You could regenerate new indirect references every time, but that
- might mess up anything that previously used an indirect reference, such
- as a URL parameter.
-
Get a safe indirect reference to use in place of a potentially sensitive
- direct object reference. Developers should use this call when building
- URL's, form fields, hidden fields, etc... to help protect their private
- implementation information.
-
Get the original direct object reference from an indirect reference.
- Developers should use this when they get an indirect reference from a
- request to translate it back into the real direct reference. If an
- invalid indirectReference is requested, then an AccessControlException is
- thrown.
-
-The IRandomizer interface defines a set of methods for creating
- cryptographically random numbers and strings. Implementers should be sure to
- use a strong cryptographic implementation, such as the JCE or BouncyCastle.
- Weak sources of randomness can undermine a wide variety of security
- mechanisms.
-
-
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-Extension to java.io.File to prevent against null byte injections and
- other unforeseen problems resulting from unprintable characters
- causing problems in path lookups. This does _not_ prevent against
- directory traversal attacks.
-
-The ISecurityConfiguration interface stores all configuration information
- that directs the behavior of the ESAPI implementation.
-
-
-
- Protection of this configuration information is critical to the secure
- operation of the application using the ESAPI. You should use operating system
- access controls to limit access to wherever the configuration information is
- stored. Please note that adding another layer of encryption does not make the
- attackers job much more difficult. Somewhere there must be a master "secret"
- that is stored unencrypted on the application platform. Creating another
- layer of indirection doesn't provide any real additional security.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-Nested Class Summary
-
-
-
-static class
-
SecurityConfiguration.Threshold
-
-
- Models a simple threshold as a count and an interval, along with a set of actions to take if the threshold is exceeded.
-The User interface represents an application user or user account. There is quite a lot of information that an
- application must store for each user in order to enforce security properly. There are also many rules that govern
- authentication and identity management.
-
-
-
- A user account can be in one of several states. When first created, a User should be disabled, not expired, and
- unlocked. To start using the account, an administrator should enable the account. The account can be locked for a
- number of reasons, most commonly because they have failed login for too many times. Finally, the account can expire
- after the expiration date has been reached. The User must be enabled, not expired, and unlocked in order to pass
- authentication.
-
ANONYMOUS
-
-
- The ANONYMOUS user is used to represent an unidentified user.
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- void
-
addRole(java.lang.String role)
-
-
- Adds a role to an account.
-
-
-
- void
-
addRoles(java.util.Set newRoles)
-
-
- Adds a set of roles to an account.
-
-
-
- void
-
changePassword(java.lang.String oldPassword,
- java.lang.String newPassword1,
- java.lang.String newPassword2)
-
-
- Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
The ANONYMOUS user is used to represent an unidentified user. Since there is
- always a real user, the ANONYMOUS user is better than using null to represent
- this.
-
Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
-
-
-
-
-
-
Parameters:
oldPassword - the old password
newPassword1 - the new password
newPassword2 - the new password - used to verify that the new password was typed correctly
-
Throws:
-
AuthenticationException - if newPassword1 does not match newPassword2, if oldPassword does not match the stored old password, or if the new password does not meet complexity requirements
-
Returns the date that the current user's account will expire, usually when the account will be disabled.
-
-
-
-
-
-
-
Returns:
Date representing the account expiration time.
-
-
-
-
-
-getFailedLoginCount
-
-public int getFailedLoginCount()
-
-
Returns the number of failed login attempts since the last successful login for an account. This method is
- intended to be used as a part of the account lockout feature, to help protect against brute force attacks.
- However, the implementor should be aware that lockouts can be used to prevent access to an application by a
- legitimate user, and should consider the risk of denial of service.
-
-
-
-
-
-
-
Returns:
the number of failed login attempts since the last successful login
-
-
-
-
-
-getLastHostAddress
-
-public java.lang.String getLastHostAddress()
-
-
Returns the last host address used by the user. This will be used in any log messages generated by the processing
- of this request.
-
Returns the date of the last failed login time for a user. This date should be used in a message to users after a
- successful login, to notify them of potential attack activity on their account.
-
Returns the date of the last successful login time for a user. This date should be used in a message to users
- after a successful login, to notify them of potential attack activity on their account.
-
Returns a token to be used as a prevention against CSRF attacks. This token should be added to all links and
- forms. The application should verify that all requests contain the token, or they may have been generated by a
- CSRF attack. It is generally best to perform the check in a centralized location, either a filter or controller.
- See the verifyCSRFToken method.
-
Verify that the supplied password matches the password for this user. This method
- is typically used for "reauthentication" for the most sensitive functions, such
- as transactions, changing email address, and changing other account information.
-
-
-
-
-
-
Parameters:
password - the password that the user entered
-
Returns:
true, if the password passed in matches the account's password
-
-The ValidationErrorList class defines a well-formed collection of
- ValidationExceptions so that groups of validation functions can be
- called in a non-blocking fashion.
-
-
-
-
-
- To use the ValidationErrorList to execute groups of validation
- attempts, your controller code would look something like:
-
-
-A ValidationException should be thrown to indicate that the data provided by
- the user or from some other external source does not match the validation
- rules that have been specified for that data.
-
-The Validator interface defines a set of methods for canonicalizing and
- validating untrusted input. Implementors should feel free to extend this
- interface to accommodate their own data formats. Rather than throw exceptions,
- this interface returns boolean results because not all validation problems
- are security issues. Boolean returns allow developers to handle both valid
- and invalid results more cleanly than exceptions.
-
-
-
- Implementations must adopt a "whitelist" approach to validation where a
- specific pattern or character set is matched. "Blacklist" approaches that
- attempt to identify the invalid or disallowed characters are much more likely
- to allow a bypass with encoding or other tricks.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- void
-
assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- void
-
assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- void
-
assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional,
- ValidationErrorList errorList)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- void
-
assertValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- void
-
assertValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- java.lang.String
-
getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- java.lang.String
-
getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- java.util.Date
-
getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns a valid date as a Date.
-
-
-
- java.util.Date
-
getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a valid date as a Date.
-
-
-
- java.lang.String
-
getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- java.lang.String
-
getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- java.lang.Double
-
getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns a validated real number as a double.
-
-
-
- java.lang.Double
-
getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a validated real number as a double.
-
-
-
- byte[]
-
getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
-
-
-
- byte[]
-
getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns validated file content as a byte array.
-
-
-
- java.lang.String
-
getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.String
-
getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.String
-
getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated input as a String.
-
-
-
- java.lang.String
-
getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns canonicalized and validated input as a String.
-
-
-
- java.lang.Integer
-
getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated integer.
-
-
-
- java.lang.Integer
-
getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a validated integer.
-
-
-
- java.lang.String
-
getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- java.lang.String
-
getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list,
- ValidationErrorList errorList)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- java.lang.Double
-
getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double within the range of minValue to maxValue.
-
-
-
- java.lang.Double
-
getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a validated number as a double within the range of minValue to maxValue.
-
-
-
- byte[]
-
getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a byte array.
-
-
-
- byte[]
-
getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns canonicalized and validated printable characters as a byte array.
-
-
-
- java.lang.String
-
getValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a String.
-
-
-
- java.lang.String
-
getValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns canonicalized and validated printable characters as a String.
-
-
-
- java.lang.String
-
getValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated redirect location as a String.
-
-
-
- java.lang.String
-
getValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated redirect location as a String.
-
-
-
- java.lang.String
-
getValidSafeHTML(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated "safe" HTML.
isValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid credit card.
-
-
-
- boolean
-
isValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns true if input is a valid date according to the specified date format.
-
-
-
- boolean
-
isValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid directory path.
-
-
-
- boolean
-
isValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid double within the range of minValue to maxValue.
-
-
-
- boolean
-
isValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if input is valid file content.
-
-
-
- boolean
-
isValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid file name.
-
-
-
- boolean
-
isValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if a file upload has a valid name, path, and content.
-
-
-
- boolean
-
isValidHTTPRequest()
-
-
- Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- boolean
-
isValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Returns true if the parameters in the current request contain all required parameters and only optional ones in addition.
-
-
-
- boolean
-
isValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is valid according to the specified type.
-
-
-
- boolean
-
isValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid integer within the range of minValue to maxValue.
-
-
-
- boolean
-
isValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns true if input is a valid list item.
-
-
-
- boolean
-
isValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid number within the range of minValue to maxValue.
-
-
-
- boolean
-
isValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input contains only valid printable ASCII characters.
-
-
-
- boolean
-
isValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input contains only valid printable ASCII characters (32-126).
-
-
-
- boolean
-
isValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid redirect location, as defined by "ESAPI.properties".
-
-
-
- boolean
-
isValidSafeHTML(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is "safe" HTML.
-
-
-
- java.lang.String
-
safeReadLine(java.io.InputStream inputStream,
- int maxLength)
-
-
- Reads from an input stream until end-of-line or a maximum number of
- characters.
Returns true if input is valid according to the specified type. The type parameter must be the name
- of a defined type in the ESAPI configuration or a valid regular expression. Implementers should take
- care to make the type storage simple to understand and configure.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
type - The regular expression name that maps to the actual regular expression from "ESAPI.properties".
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if the input is valid based on the rules set by 'type'
-
Returns canonicalized and validated input as a String. Invalid input will generate a descriptive ValidationException,
- and input that is clearly an attack will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
type - The regular expression name that maps to the actual regular expression from "ESAPI.properties".
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns canonicalized and validated input as a String. Invalid input will generate a descriptive ValidationException,
- and input that is clearly an attack will generate a descriptive IntrusionException. Instead of
- throwing a ValidationException on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
type - The regular expression name that maps to the actual regular expression from "ESAPI.properties".
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns true if input is a valid date according to the specified date format.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
format - Required formatting of date inputted.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if input is a valid date according to the format specified by 'format'
-
Returns a valid date as a Date. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
format - Required formatting of date inputted.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a valid date as a Date. Invalid input will generate a descriptive ValidationException and store it inside of
- the errorList argument, and input that is clearly an attack will generate a descriptive IntrusionException. Instead of
- throwing a ValidationException on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
format - Required formatting of date inputted.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns true if input is "safe" HTML. Implementors should reference the OWASP AntiSamy project for ideas
- on how to do HTML validation in a whitelist way, as this is an extremely difficult problem.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns canonicalized and validated "safe" HTML. Implementors should reference the OWASP AntiSamy project for ideas
- on how to do HTML validation in a whitelist way, as this is an extremely difficult problem.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns canonicalized and validated "safe" HTML. Implementors should reference the OWASP AntiSamy project for ideas
- on how to do HTML validation in a whitelist way, as this is an extremely difficult problem. Instead of
- throwing a ValidationException on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns true if input is a valid credit card. Maxlength is mandated by valid credit card type.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a canonicalized and validated credit card number as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a canonicalized and validated credit card number as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns true if input is a valid directory path.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a canonicalized and validated directory path as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a canonicalized and validated directory path as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a canonicalized and validated file name as a String. Implementors should check for allowed file extensions here, as well as allowed file name characters, as declared in "ESAPI.properties". Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a canonicalized and validated file name as a String. Implementors should check for allowed file extensions here, as well as allowed file name characters, as declared in "ESAPI.properties". Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
-public boolean isValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
- throws IntrusionException
-
-
Returns true if input is a valid number within the range of minValue to maxValue.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a validated number as a double within the range of minValue to maxValue. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
Returns a validated number as a double within the range of minValue to maxValue. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
-public boolean isValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
- throws IntrusionException
-
-
Returns true if input is a valid integer within the range of minValue to maxValue.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a validated integer. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
Returns a validated integer. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns true if input is a valid double within the range of minValue to maxValue.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a validated real number as a double. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
Returns a validated real number as a double. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns true if input is valid file content. This is a good place to check for max file size, allowed character sets, and do virus scans.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
maxBytes - The maximum number of bytes allowed in a legal file.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns validated file content as a byte array. This is a good place to check for max file size, allowed character sets, and do virus scans. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
maxBytes - The maximum number of bytes allowed in a legal file.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns validated file content as a byte array. This is a good place to check for max file size, allowed character sets, and do virus scans. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
maxBytes - The maximum number of bytes allowed in a legal file.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context.
-
Returns true if a file upload has a valid name, path, and content.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
filepath - The file path of the uploaded file.
filename - The filename of the uploaded file
content - A byte array containing the content of the uploaded file.
maxBytes - The max number of bytes allowed for a legal file upload.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if a file upload has a valid name, path, and content.
-
Validates the filepath, filename, and content of a file. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
filepath - The file path of the uploaded file.
filename - The filename of the uploaded file
content - A byte array containing the content of the uploaded file.
maxBytes - The max number of bytes allowed for a legal file upload.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Validates the filepath, filename, and content of a file. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
filepath - The file path of the uploaded file.
filename - The filename of the uploaded file
content - A byte array containing the content of the uploaded file.
maxBytes - The max number of bytes allowed for a legal file upload.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters. See the SecurityConfiguration class for the methods to retrieve the whitelists.
-
Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
Returns the list item that exactly matches the canonicalized input. Invalid or non-matching input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The value to search 'list' for.
list - The list to search for 'input'.
-
Returns:
The list item that exactly matches the canonicalized input.
-
Returns the list item that exactly matches the canonicalized input. Invalid or non-matching input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The value to search 'list' for.
list - The list to search for 'input'.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns:
The list item that exactly matches the canonicalized input.
-
Returns true if the parameters in the current request contain all required parameters and only optional ones in addition.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
required - parameters that are required to be in HTTP request
optional - additional parameters that may be in HTTP request
-
Returns:
true, if all required parameters are in HTTP request and only optional parameters in addition. Returns false if parameters are found in HTTP request that are not in either set (required or optional), or if any required parameters are missing from request.
-
Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
required - parameters that are required to be in HTTP request
optional - additional parameters that may be in HTTP request
-
Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException on error,
- this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
required - parameters that are required to be in HTTP request
optional - additional parameters that may be in HTTP request
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns true if input contains only valid printable ASCII characters.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be checked for validity
maxLength - Maximum number of bytes stored in 'input'
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if 'input' is less than maxLength and contains only valid, printable characters
-
Returns canonicalized and validated printable characters as a byte array. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be returned as valid and printable
maxLength - Maximum number of bytes stored in 'input'
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
a byte array containing only printable characters, made up of data from 'input'
-
Returns canonicalized and validated printable characters as a byte array. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException on error,
- this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be returned as valid and printable
maxLength - Maximum number of bytes stored in 'input'
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns:
a byte array containing only printable characters, made up of data from 'input'
-
Returns true if input contains only valid printable ASCII characters (32-126).
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be checked for validity
maxLength - Maximum number of bytes stored in 'input' after canonicalization
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if 'input' is less than maxLength after canonicalization and contains only valid, printable characters
-
Returns canonicalized and validated printable characters as a String. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be returned as valid and printable
maxLength - Maximum number of bytes stored in 'input' after canonicalization
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
a String containing only printable characters, made up of data from 'input'
-
Returns canonicalized and validated printable characters as a String. Invalid input will generate
- a descriptive ValidationException, and input that is clearly an attack will generate a
- descriptive IntrusionException. Instead of throwing a ValidationException on error,
- this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be returned as valid and printable
maxLength - Maximum number of bytes stored in 'input' after canonicalization
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns:
a String containing only printable characters, made up of data from 'input'
-
Returns true if input is a valid redirect location, as defined by "ESAPI.properties".
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - redirect location to be checked for validity, according to rules set in "ESAPI.properties"
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if 'input' is a valid redirect location, as defined by "ESAPI.properties", false otherwise.
-
Returns a canonicalized and validated redirect location as a String. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - redirect location to be returned as valid, according to encoding rules set in "ESAPI.properties"
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
A canonicalized and validated redirect location, as defined in "ESAPI.properties"
-
Returns a canonicalized and validated redirect location as a String. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
-
-
Parameters:
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - redirect location to be returned as valid, according to encoding rules set in "ESAPI.properties"
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errorList - If validation is in error, resulting error will be stored in the errorList by context
-
Returns:
A canonicalized and validated redirect location, as defined in "ESAPI.properties"
-
-public java.lang.String safeReadLine(java.io.InputStream inputStream,
- int maxLength)
- throws ValidationException
-
-
Reads from an input stream until end-of-line or a maximum number of
- characters. This method protects against the inherent denial of service
- attack in reading until the end of a line. If an attacker doesn't ever
- send a newline character, then a normal input stream reader will read
- until all memory is exhausted and the platform throws an OutOfMemoryError
- and probably terminates.
-
-
-
Parameters:
inputStream - The InputStream from which to read data
maxLength - Maximum characters allowed to be read in per line
-
Returns:
a String containing the current line of inputStream
-
AccessController.assertAuthorizedForURL(java.lang.String url)
-
-
- Checks if an account is authorized to access the referenced URL.
-
-
-
- void
-
AccessController.assertAuthorizedForFunction(java.lang.String functionName)
-
-
- Checks if an account is authorized to access the referenced function.
-
-
-
- void
-
AccessController.assertAuthorizedForData(java.lang.String key)
-
-
- Checks if an account is authorized to access the referenced data.
-
-
-
- void
-
AccessController.assertAuthorizedForFile(java.lang.String filepath)
-
-
- Checks if an account is authorized to access the referenced file.
-
-
-
- void
-
AccessController.assertAuthorizedForService(java.lang.String serviceName)
-
-
- Checks if an account is authorized to access the referenced service.
-
-
-
- void
-
HTTPUtilities.assertSecureRequest()
-
-
- Ensures that the current request uses SSL and POST to protect any sensitive parameters
- in the querystring from being sniffed or logged.
-
-
-
- void
-
HTTPUtilities.safeSendForward(java.lang.String context,
- java.lang.String location)
-
-
- This method perform a forward to any resource located inside the WEB-INF directory.
-
-
-
- java.lang.Object
-
AccessReferenceMap.getDirectReference(java.lang.String indirectReference)
-
-
- Get the original direct object reference from an indirect reference.
-
-
-
- java.lang.String
-
AccessReferenceMap.removeDirectReference(java.lang.Object direct)
-
-
- Removes a direct reference and its associated indirect reference from the AccessReferenceMap.
-
-
-
- java.lang.String
-
RandomAccessReferenceMap.removeDirectReference(java.lang.Object direct)
-
-
- Remove a direct reference and the corresponding indirect reference.
AuthenticationHostException
-
-
- An AuthenticationHostException should be thrown when there is a problem with
- the host involved with authentication, particularly if the host changes unexpectedly.
-
-
-
- class
-
AuthenticationLoginException
-
-
- An AuthenticationException should be thrown when anything goes wrong during
- login or logout.
Authenticator.login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Authenticates the user's credentials from the HttpServletRequest if
- necessary, creates a session if necessary, and sets the user as the
- current user.
Authenticator.changePassword(User user,
- java.lang.String currentPassword,
- java.lang.String newPassword,
- java.lang.String newPassword2)
-
-
- Changes the password for the specified user.
-
-
-
- void
-
Authenticator.removeUser(java.lang.String accountName)
-
-
- Removes the account.
-
-
-
- void
-
Authenticator.verifyAccountNameStrength(java.lang.String accountName)
-
-
- Ensures that the account name passes site-specific complexity requirements.
-
-
-
- void
-
Authenticator.verifyPasswordStrength(java.lang.String oldPassword,
- java.lang.String newPassword)
-
-
- Ensures that the password meets site-specific complexity requirements.
-
-
-
- javax.servlet.http.HttpSession
-
HTTPUtilities.changeSessionIdentifier()
-
-
- Invalidate the old session after copying all of its contents to a newly created session with a new session id.
-
-
-
- void
-
User.addRole(java.lang.String role)
-
-
- Adds a role to an account.
-
-
-
- void
-
User.addRoles(java.util.Set newRoles)
-
-
- Adds the roles.
-
-
-
- void
-
User.changePassword(java.lang.String oldPassword,
- java.lang.String newPassword1,
- java.lang.String newPassword2)
-
-
- Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
-
-
-
- java.util.Date
-
User.getLastFailedLoginTime()
-
-
- Returns the date of the last failed login time for a user.
-
-
-
- void
-
User.loginWithPassword(java.lang.String password)
-
-
- Login with password.
-
-
-
- void
-
User.removeRole(java.lang.String role)
-
-
- Removes a role from an account.
-
-
-
- java.lang.String
-
User.resetCSRFToken()
-
-
- Returns a token to be used as a prevention against CSRF attacks.
-
-
-
- void
-
User.setRoles(java.util.Set roles)
-
-
- Sets the roles.
FileBasedAuthenticator.login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- This method should be called for every HTTP request, to login the current user either from the session of HTTP
- request.
Encoder.canonicalize(java.lang.String input)
-
-
- This method performs canonicalization on data received to ensure that it
- has been reduced to its most basic form before validation.
-
-
-
- java.lang.String
-
Encoder.encodeForURL(java.lang.String input)
-
-
- Encode for use in a URL.
-
-
-
- java.lang.String
-
Encoder.decodeFromURL(java.lang.String input)
-
-
- Decode from URL.
Authenticator.hashPassword(java.lang.String password,
- java.lang.String accountName)
-
-
- Returns a string representation of the hashed password, using the
- accountName as the salt.
-
-
-
- java.lang.String
-
HTTPUtilities.encryptHiddenField(java.lang.String value)
-
-
- Encrypts a hidden field value for use in HTML.
-
-
-
- java.lang.String
-
HTTPUtilities.encryptQueryString(java.lang.String query)
-
-
- Takes a querystring (i.e.
-
-
-
- java.util.Map
-
HTTPUtilities.decryptQueryString(java.lang.String encrypted)
-
-
- Takes an encrypted querystring and returns a Map containing the original parameters.
-
-
-
- java.util.Map
-
HTTPUtilities.decryptStateFromCookie()
-
-
- Retrieves a map of data from a cookie encrypted with encryptStateInCookie().
-
-
-
- void
-
HTTPUtilities.encryptStateInCookie(java.util.Map cleartext)
-
-
- Stores a Map of data in an encrypted cookie.
-
-
-
- java.lang.String
-
EncryptedProperties.getProperty(java.lang.String key)
-
-
- Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller.
-
-
-
- java.lang.String
-
EncryptedProperties.setProperty(java.lang.String key,
- java.lang.String value)
-
-
- Encrypts the plaintext property value and stores the ciphertext value in the encrypted store.
-
-
-
- void
-
User.changePassword(java.lang.String oldPassword,
- java.lang.String newPassword1,
- java.lang.String newPassword2)
-
-
- Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
-
-
-
- boolean
-
User.verifyPassword(java.lang.String password)
-
-
- Verify that the supplied password matches the password for this user.
-
-
-
- java.lang.String
-
Randomizer.getRandomGUID()
-
-
- Generates a random GUID.
-
-
-
- java.lang.String
-
Encryptor.hash(java.lang.String plaintext,
- java.lang.String salt)
-
-
- Returns a string representation of the hash of the provided plaintext and
- salt.
-
-
-
- java.lang.String
-
Encryptor.encrypt(java.lang.String plaintext)
-
-
- Encrypts the provided plaintext and returns a ciphertext string.
-
-
-
- java.lang.String
-
Encryptor.decrypt(java.lang.String ciphertext)
-
-
- Decrypts the provided ciphertext string (encrypted with the encrypt
- method) and returns a plaintext string.
-
-
-
- java.lang.String
-
Encryptor.sign(java.lang.String data)
-
-
- Create a digital signature for the provided data and return it in a
- string.
-
-
-
- java.lang.String
-
Encryptor.unseal(java.lang.String seal)
-
-
- Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
JSEEncryptor.hash(java.lang.String plaintext,
- java.lang.String salt)
-
-
- Hashes the data using the specified algorithm and the Java MessageDigest class.
AuthenticationException
-
-
- An AuthenticationException should be thrown when anything goes wrong during
- login or logout.
-
-
-
- class
-
AuthenticationHostException
-
-
- An AuthenticationHostException should be thrown when there is a problem with
- the host involved with authentication, particularly if the host changes unexpectedly.
-
-
-
- class
-
AuthenticationLoginException
-
-
- An AuthenticationException should be thrown when anything goes wrong during
- login or logout.
-
-
-
- class
-
AvailabilityException
-
-
- An AvailabilityException should be thrown when the availability of a limited
- resource is in jeopardy.
-
-
-
- class
-
CertificateException
-
-
- A CertificateException should be thrown for any problems that arise during
- processing of digital certificates.
-
-
-
- class
-
EncodingException
-
-
- An ExecutorException should be thrown for any problems that occur when
- encoding or decoding data.
-
-
-
- class
-
EncryptionException
-
-
- An EncryptionException should be thrown for any problems related to
- encryption, hashing, or digital signatures.
-
-
-
- class
-
ExecutorException
-
-
- An ExecutorException should be thrown for any problems that arise during the
- execution of a system executable.
-
-
-
- class
-
IntegrityException
-
-
- An AvailabilityException should be thrown when the availability of a limited
- resource is in jeopardy.
ValidationException
-
-
- A ValidationException should be thrown to indicate that the data provided by
- the user or from some other external source does not match the validation
- rules that have been specified for that data.
Executor.executeSystemCommand(java.io.File executable,
- java.util.List params,
- java.io.File workdir,
- int timeoutSeconds)
-
-
- Executes a system command after checking that the executable exists and
- that the parameters have not been subject to injection with untrusted
- user data.
HTTPUtilities.verifyCSRFToken()
-
-
- Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and
- throws an IntrusionException if it is missing.
-
-
-
- void
-
IntrusionDetector.addException(java.lang.Exception exception)
-
-
- Adds the exception to the IntrusionDetector.
-
-
-
- void
-
IntrusionDetector.addEvent(java.lang.String eventName)
-
-
- Adds the event to the IntrusionDetector.
-
-
-
- boolean
-
Validator.isValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is valid according to the specified type.
-
-
-
- java.lang.String
-
Validator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated input as a String.
-
-
-
- boolean
-
Validator.isValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns true if input is a valid date according to the specified date format.
-
-
-
- java.util.Date
-
Validator.getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns a valid date as a Date.
-
-
-
- boolean
-
Validator.isValidSafeHTML(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is "safe" HTML.
-
-
-
- boolean
-
Validator.isValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid credit card.
-
-
-
- java.lang.String
-
Validator.getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- boolean
-
Validator.isValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid directory path.
-
-
-
- java.lang.String
-
Validator.getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- boolean
-
Validator.isValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid file name.
-
-
-
- java.lang.String
-
Validator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- boolean
-
Validator.isValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid number.
-
-
-
- java.lang.Double
-
Validator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- boolean
-
Validator.isValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid integer.
-
-
-
- java.lang.Integer
-
Validator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated integer as an int.
-
-
-
- boolean
-
Validator.isValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid double.
-
-
-
- java.lang.Double
-
Validator.getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns a validated real number as a double.
-
-
-
- boolean
-
Validator.isValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if input is valid file content.
-
-
-
- byte[]
-
Validator.getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
-
-
-
- boolean
-
Validator.isValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if a file upload has a valid name, path, and content.
-
-
-
- void
-
Validator.assertValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- boolean
-
Validator.isValidHTTPRequest()
-
-
- Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- void
-
Validator.assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- boolean
-
Validator.isValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns true if input is a valid list item.
-
-
-
- java.lang.String
-
Validator.getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- boolean
-
Validator.isValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Returns true if the parameters in the current request contain all required parameters and only optional ones in addition.
-
-
-
- void
-
Validator.assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- boolean
-
Validator.isValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is valid printable ASCII characters.
-
-
-
- boolean
-
Validator.isValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is valid printable ASCII characters (32-126).
-
-
-
- boolean
-
Validator.isValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid redirect location.
DefaultValidator.isValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if data received from browser is valid.
-
-
-
- java.lang.String
-
DefaultValidator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Validates data received from the browser and returns a safe version.
-
-
-
- boolean
-
DefaultValidator.isValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns true if input is a valid date according to the specified date format.
DefaultValidator.getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- boolean
-
DefaultValidator.isValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if the directory path (not including a filename) is valid.
-
-
-
- java.lang.String
-
DefaultValidator.getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- boolean
-
DefaultValidator.isValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid file name.
-
-
-
- java.lang.String
-
DefaultValidator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- boolean
-
DefaultValidator.isValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
-
-
-
-
- java.lang.Double
-
DefaultValidator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
DefaultValidator.getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- boolean
-
DefaultValidator.isValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
-
-
-
-
- java.lang.Integer
-
DefaultValidator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- boolean
-
DefaultValidator.isValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if input is valid file content.
-
-
-
- byte[]
-
DefaultValidator.getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
-
-
-
- boolean
-
DefaultValidator.isValidFileUpload(java.lang.String context,
- java.lang.String directorypath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if a file upload has a valid name, path, and content.
-
-
-
- void
-
DefaultValidator.assertValidFileUpload(java.lang.String context,
- java.lang.String directorypath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- boolean
-
DefaultValidator.isValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- boolean
-
DefaultValidator.isValidHTTPRequest(javax.servlet.http.HttpServletRequest request)
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- void
-
DefaultValidator.assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- void
-
DefaultValidator.assertIsValidHTTPRequest(javax.servlet.http.HttpServletRequest request)
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- java.lang.String
-
DefaultValidator.getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- void
-
DefaultValidator.assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- boolean
-
DefaultValidator.isValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Checks that all bytes are valid ASCII characters (between 33 and 126
- inclusive).
-
-
-
- byte[]
-
DefaultValidator.getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a byte array.
HTTPUtilities.logHTTPRequest(javax.servlet.http.HttpServletRequest request,
- Logger logger)
-
-
- Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file.
-
-
-
- void
-
HTTPUtilities.logHTTPRequest(javax.servlet.http.HttpServletRequest request,
- Logger logger,
- java.util.List parameterNamesToObfuscate)
-
-
- Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file.
Authenticator.login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Authenticates the user's credentials from the HttpServletRequest if
- necessary, creates a session if necessary, and sets the user as the
- current user.
Authenticator.createUser(java.lang.String accountName,
- java.lang.String password1,
- java.lang.String password2)
-
-
- Creates a new User with the information provided.
Authenticator.verifyPassword(User user,
- java.lang.String password)
-
-
- Verify that the supplied password matches the password for this user.
-
-
-
- java.lang.String
-
Authenticator.generateStrongPassword(User user,
- java.lang.String oldPassword)
-
-
- Generate strong password that takes into account the user's information and old password.
-
-
-
- void
-
Authenticator.changePassword(User user,
- java.lang.String currentPassword,
- java.lang.String newPassword,
- java.lang.String newPassword2)
-
-
- Changes the password for the specified user.
-
-
-
- void
-
Authenticator.setCurrentUser(User user)
-
-
- Sets the currently logged in User.
FileBasedAuthenticator.login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- This method should be called for every HTTP request, to login the current user either from the session of HTTP
- request.
Validator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns canonicalized and validated input as a String.
-
-
-
- java.util.Date
-
Validator.getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a valid date as a Date.
Validator.getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- java.lang.String
-
Validator.getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- java.lang.String
-
Validator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.Double
-
Validator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a validated number as a double within the range of minValue to maxValue.
-
-
-
- java.lang.Integer
-
Validator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a validated integer.
-
-
-
- java.lang.Double
-
Validator.getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a validated real number as a double.
-
-
-
- byte[]
-
Validator.getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns validated file content as a byte array.
-
-
-
- void
-
Validator.assertValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- java.lang.String
-
Validator.getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list,
- ValidationErrorList errorList)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- void
-
Validator.assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional,
- ValidationErrorList errorList)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- byte[]
-
Validator.getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns canonicalized and validated printable characters as a byte array.
-
-
-
- java.lang.String
-
Validator.getValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns canonicalized and validated printable characters as a String.
-
-
-
- java.lang.String
-
Validator.getValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated redirect location as a String.
DefaultValidator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Validates data received from the browser and returns a safe version.
DefaultValidator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.Double
-
DefaultValidator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull,
- ValidationErrorList errors)
-
-
-
HTTPUtilities.safeAddHeader(java.lang.String name,
- java.lang.String value)
-
-
- Adds a header to an HttpServletResponse after checking for special characters (such as CRLF injection) that could enable
- attacks like response splitting and other header-based attacks that nobody has thought of yet.
-
-
-
- void
-
HTTPUtilities.safeSetHeader(java.lang.String name,
- java.lang.String value)
-
-
- Sets a header in an HttpServletResponse after checking for special characters (such as CRLF injection) that could enable
- attacks like response splitting and other header-based attacks that nobody has thought of yet.
-
-
-
- java.util.List
-
HTTPUtilities.getSafeFileUploads(java.io.File tempDir,
- java.io.File finalDir)
-
-
- Extract uploaded files from a multipart HTTP requests.
-
-
-
- java.lang.String
-
Validator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated input as a String.
-
-
-
- java.util.Date
-
Validator.getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns a valid date as a Date.
-
-
-
- java.lang.String
-
Validator.getValidSafeHTML(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated "safe" HTML.
-
-
-
- java.lang.String
-
Validator.getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- java.lang.String
-
Validator.getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- java.lang.String
-
Validator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.Double
-
Validator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- java.lang.Integer
-
Validator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated integer as an int.
-
-
-
- java.lang.Double
-
Validator.getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns a validated real number as a double.
-
-
-
- byte[]
-
Validator.getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
-
-
-
- void
-
Validator.assertValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- void
-
Validator.assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- java.lang.String
-
Validator.getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- void
-
Validator.assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- byte[]
-
Validator.getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a byte array.
-
-
-
- java.lang.String
-
Validator.getValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a String.
-
-
-
- java.lang.String
-
Validator.getValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated redirect location as a String.
-
-
-
- java.lang.String
-
Validator.safeReadLine(java.io.InputStream inputStream,
- int maxLength)
-
-
- Reads from an input stream until end-of-line or a maximum number of
- characters.
DefaultValidator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Validates data received from the browser and returns a safe version.
DefaultValidator.getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- java.lang.String
-
DefaultValidator.getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- java.lang.String
-
DefaultValidator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.Double
-
DefaultValidator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- java.lang.Double
-
DefaultValidator.getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- java.lang.Integer
-
DefaultValidator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- byte[]
-
DefaultValidator.getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
-
-
-
- void
-
DefaultValidator.assertValidFileUpload(java.lang.String context,
- java.lang.String directorypath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- void
-
DefaultValidator.assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- void
-
DefaultValidator.assertIsValidHTTPRequest(javax.servlet.http.HttpServletRequest request)
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- java.lang.String
-
DefaultValidator.getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- void
-
DefaultValidator.assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- byte[]
-
DefaultValidator.getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a byte array.
-
-
-
- java.lang.String
-
DefaultValidator.getValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a String.
-
-
-
- java.lang.String
-
DefaultValidator.getValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated redirect location as a String.
-
-
-
- java.lang.String
-
DefaultValidator.safeReadLine(java.io.InputStream in,
- int max)
-
-
- This implementation reads until a newline or the specified number of
- characters.
DefaultHTTPUtilities.getSafeFileUploads(java.io.File tempDir,
- java.io.File finalDir)
-
-
- Uses the Apache Commons FileUploader to parse the multipart HTTP request
- and extract any files therein.
-A Base64.InputStream will read data from another
- java.io.InputStream, given in the constructor,
- and encode/decode to/from Base64 notation on the fly.
-
- ENCODE or DECODE: Encode or Decode as data is read.
- DONT_BREAK_LINES: don't break lines at 76 characters
- (only meaningful when encoding)
- Note: Technically, this makes your encoding non-compliant.
-
-
- Example: new Base64.InputStream( in, Base64.DECODE )
-
-
Parameters:
in - the java.io.InputStream from which to read data.
Reads enough of the input stream to convert
- to/from Base64 and returns the next byte.
-
-
-
-
Returns:
next byte
-
Throws:
-
java.io.IOException
Since:
-
1.3
-
-
-
-
-
-
-read
-
-public int read(byte[] dest,
- int off,
- int len)
- throws java.io.IOException
-
-
Calls read() repeatedly until the end of stream
- is reached or len bytes are read.
- Returns number of bytes read into array or -1 if
- end of stream is encountered.
-
-
-
Parameters:
dest - array to hold values
off - offset for array
len - max number of bytes to read into array
-
Returns:
bytes read into array or -1 if end of stream is encountered.
-
-A Base64.OutputStream will write data to another
- java.io.OutputStream, given in the constructor,
- and encode/decode to/from Base64 notation on the fly.
-
- ENCODE or DECODE: Encode or Decode as data is read.
- DONT_BREAK_LINES: don't break lines at 76 characters
- (only meaningful when encoding)
- Note: Technically, this makes your encoding non-compliant.
-
-
- Example: new Base64.OutputStream( out, Base64.ENCODE )
-
-
Parameters:
out - the java.io.OutputStream to which data will be written.
Writes the byte to the output stream after
- converting to/from Base64 notation.
- When encoding, bytes are buffered three
- at a time before the output stream actually
- gets a write() call.
- When decoding, bytes are buffered four
- at a time.
-
-
-
Parameters:
theByte - the byte to write
-
Throws:
-
java.io.IOException
Since:
-
1.3
-
-
-
-
-
-
-write
-
-public void write(byte[] theBytes,
- int off,
- int len)
- throws java.io.IOException
-
-
Calls write(int) repeatedly until len
- bytes are written.
-
The options parameter, which appears in a few places, is used to pass
- several pieces of information to the encoder. In the "higher level" methods such as
- encodeBytes( bytes, options ) the options parameter can be used to indicate such
- things as first gzipping the bytes before encoding them, not inserting linefeeds
- (though that breaks strict Base64 compatibility), and encoding using the URL-safe
- and Ordered dialects.
-
-
The constants defined in Base64 can be OR-ed together to combine options, so you
- might make a call like this:
to compress the data before encoding it and then making the output have no newline characters.
-
-
-
- Change Log:
-
-
-
v2.2.2 - Fixed encodeFileToFile and decodeFileToFile to use the
- Base64.InputStream class to encode and decode on the fly which uses
- less memory than encoding/decoding an entire file into memory before writing.
-
v2.2.1 - Fixed bug using URL_SAFE and ORDERED encodings. Fixed bug
- when using very small files (~< 40 bytes).
-
v2.2 - Added some helper methods for encoding/decoding directly from
- one file to the next. Also added a main() method to support command line
- encoding/decoding from one file to the next. Also added these Base64 dialects:
-
-
The default is RFC3548 format.
-
Calling Base64.setFormat(Base64.BASE64_FORMAT.URLSAFE_FORMAT) generates
- URL and file name friendly format as described in Section 4 of RFC3548.
- http://www.faqs.org/rfcs/rfc3548.html
-
Calling Base64.setFormat(Base64.BASE64_FORMAT.ORDERED_FORMAT) generates
- URL and file name friendly format that preserves lexical ordering as described
- in http://www.faqs.org/qa/rfcc-1940.html
-
- Special thanks to Jim Kellerman at http://www.powerset.com/
- for contributing the new Base64 dialects.
-
-
-
v2.1 - Cleaned up javadoc comments and unused variables and methods. Added
- some convenience methods for reading and writing to and from files.
-
v2.0.2 - Now specifies UTF-8 encoding in places where the code fails on systems
- with other encodings (like EBCDIC).
-
v2.0.1 - Fixed an error when decoding a single byte, that is, when the
- encoded data was a single byte.
-
v2.0 - I got rid of methods that used booleans to set options.
- Now everything is more consolidated and cleaner. The code now detects
- when data that's being decoded is gzip-compressed and will decompress it
- automatically. Generally things are cleaner. You'll probably have to
- change some method calls that you were making to support the new
- options format (ints that you "OR" together).
-
v1.5.1 - Fixed bug when decompressing and decoding to a
- byte[] using decode( String s, boolean gzipCompressed ).
- Added the ability to "suspend" encoding in the Output Stream so
- you can turn on and off the encoding if you need to embed base64
- data in an otherwise "normal" stream (like an XML file).
-
v1.5 - Output stream pases on flush() command but doesn't do anything itself.
- This helps when using GZIP streams.
- Added the ability to GZip-compress objects before encoding them.
-
v1.4 - Added helper methods to read/write files.
-
v1.3.6 - Fixed OutputStream.flush() so that 'position' is reset.
-
v1.3.5 - Added flag to turn on and off line breaks. Fixed bug in input stream
- where last buffer being read, if not completely full, was not returned.
-
v1.3.4 - Fixed when "improperly padded stream" error was thrown at the wrong time.
-
v1.3.3 - Fixed I/O streams which were totally messed up.
-
-
-
- I am placing this code in the Public Domain. Do with it as you will.
- This software comes with no guarantees or warranties but with
- plenty of well-wishing instead!
- Please visit http://iharder.net/base64
- periodically to check for updates or to contribute improvements.
-
-
-
-
-
-
Version:
-
2.2.2
-
Author:
-
Robert Harder, rob@iharder.net
-
-
-
-
-
-
-
-
-
-
-Nested Class Summary
-
-
-
-static class
-
Base64.InputStream
-
-
- A Base64.InputStream will read data from another
- java.io.InputStream, given in the constructor,
- and encode/decode to/from Base64 notation on the fly.
-
-
-
-static class
-
Base64.OutputStream
-
-
- A Base64.OutputStream will write data to another
- java.io.OutputStream, given in the constructor,
- and encode/decode to/from Base64 notation on the fly.
decode(byte[] source,
- int off,
- int len,
- int options)
-
-
- Very low-level access to decoding ASCII characters in
- the form of a byte array.
-
-
-
-static byte[]
-
decode(java.lang.String s)
-
-
- Decodes data from Base64 notation, automatically
- detecting gzip-compressed data and decompressing it.
-
-
-
-static byte[]
-
decode(java.lang.String s,
- int options)
-
-
- Decodes data from Base64 notation, automatically
- detecting gzip-compressed data and decompressing it.
-
-
-
-static boolean
-
decodeFileToFile(java.lang.String infile,
- java.lang.String outfile)
-
-
- Reads infile and decodes it to outfile.
-
-
-
-static byte[]
-
decodeFromFile(java.lang.String filename)
-
-
- Convenience method for reading a base64-encoded
- file and decoding it.
-
-
-
-static boolean
-
decodeToFile(java.lang.String dataToDecode,
- java.lang.String filename)
-
-
- Convenience method for decoding data to a file.
-
-
-
-static java.lang.Object
-
decodeToObject(java.lang.String encodedObject)
-
-
- Attempts to decode Base64 data and deserialize a Java
- Object within.
-
-
-
-static java.lang.String
-
encodeBytes(byte[] source)
-
-
- Encodes a byte array into Base64 notation.
-
-
-
-static java.lang.String
-
encodeBytes(byte[] source,
- int options)
-
-
- Encodes a byte array into Base64 notation.
-
-
-
-static java.lang.String
-
encodeBytes(byte[] source,
- int off,
- int len)
-
-
- Encodes a byte array into Base64 notation.
-
-
-
-static java.lang.String
-
encodeBytes(byte[] source,
- int off,
- int len,
- int options)
-
-
- Encodes a byte array into Base64 notation.
-
-
-
-static boolean
-
encodeFileToFile(java.lang.String infile,
- java.lang.String outfile)
-
-
- Reads infile and encodes it to outfile.
-
-
-
-static java.lang.String
-
encodeFromFile(java.lang.String filename)
-
-
- Convenience method for reading a binary file
- and base64-encoding it.
-
-
-
-static java.lang.String
-
encodeObject(java.io.Serializable serializableObject)
-
-
- Serializes an object and returns the Base64-encoded
- version of that serialized object.
-
-
-
-static java.lang.String
-
encodeObject(java.io.Serializable serializableObject,
- int options)
-
-
- Serializes an object and returns the Base64-encoded
- version of that serialized object.
-
-
-
-static boolean
-
encodeToFile(byte[] dataToEncode,
- java.lang.String filename)
-
-
- Convenience method for encoding data to a file.
-
-
-
-static void
-
main(java.lang.String[] args)
-
-
- Encodes or decodes two files from the command line;
- feel free to delete this method (in fact you probably should)
- if you're embedding this code into a larger program.
Encode using Base64-like encoding that is URL- and Filename-safe as described
- in Section 4 of RFC3548:
- http://www.faqs.org/rfcs/rfc3548.html.
- It is important to note that data encoded this way is not officially valid Base64,
- or at the very least should not be called Base64 without also specifying that is
- was encoded using the URL- and Filename-safe dialect.
-
-public static final void main(java.lang.String[] args)
-
-
Encodes or decodes two files from the command line;
- feel free to delete this method (in fact you probably should)
- if you're embedding this code into a larger program.
-
Serializes an object and returns the Base64-encoded
- version of that serialized object. If the object
- cannot be serialized or there is another error,
- the method will return null.
- The object is not GZip-compressed before being encoded.
-
-
-
Parameters:
serializableObject - The object to encode
-
Returns:
The Base64-encoded object
Since:
-
1.4
-
-
-
-
-
-
-encodeObject
-
-public static java.lang.String encodeObject(java.io.Serializable serializableObject,
- int options)
-
-
Serializes an object and returns the Base64-encoded
- version of that serialized object. If the object
- cannot be serialized or there is another error,
- the method will return null.
-
- Valid options:
- GZIP: gzip-compresses object before encoding it.
- DONT_BREAK_LINES: don't break lines at 76 characters
- Note: Technically, this makes your encoding non-compliant.
-
-
- Example: encodeObject( myObj, Base64.GZIP ) or
-
Encodes a byte array into Base64 notation.
- Does not GZip-compress data.
-
-
-
Parameters:
source - The data to convert
Since:
-
1.4
-
-
-
-
-
-
-encodeBytes
-
-public static java.lang.String encodeBytes(byte[] source,
- int options)
-
-
Encodes a byte array into Base64 notation.
-
- Valid options:
- GZIP: gzip-compresses object before encoding it.
- DONT_BREAK_LINES: don't break lines at 76 characters
- Note: Technically, this makes your encoding non-compliant.
-
-
- Example: encodeBytes( myData, Base64.GZIP ) or
-
-public static java.lang.String encodeBytes(byte[] source,
- int off,
- int len)
-
-
Encodes a byte array into Base64 notation.
- Does not GZip-compress data.
-
-
-
Parameters:
source - The data to convert
off - Offset in array where conversion should begin
len - Length of data to convert
Since:
-
1.4
-
-
-
-
-
-
-encodeBytes
-
-public static java.lang.String encodeBytes(byte[] source,
- int off,
- int len,
- int options)
-
-
Encodes a byte array into Base64 notation.
-
- Valid options:
- GZIP: gzip-compresses object before encoding it.
- DONT_BREAK_LINES: don't break lines at 76 characters
- Note: Technically, this makes your encoding non-compliant.
-
-
- Example: encodeBytes( myData, Base64.GZIP ) or
-
-public static byte[] decode(byte[] source,
- int off,
- int len,
- int options)
-
-
Very low-level access to decoding ASCII characters in
- the form of a byte array. Does not support automatically
- gunzipping or any other "fancy" features.
-
-
-
Parameters:
source - The Base64 encoded data
off - The offset of where to begin decoding
len - The length of characters to decode
-
Returns:
decoded data
Since:
-
1.3
-
-
-
-
-
-
-decode
-
-public static byte[] decode(java.lang.String s)
-
-
Decodes data from Base64 notation, automatically
- detecting gzip-compressed data and decompressing it.
-
-
-
Parameters:
s - the string to decode
-
Returns:
the decoded data
Since:
-
1.4
-
-
-
-
-
-
-decode
-
-public static byte[] decode(java.lang.String s,
- int options)
-
-
Decodes data from Base64 notation, automatically
- detecting gzip-compressed data and decompressing it.
-
Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
- Formats all are legal both upper/lower case:
- \\x - special characters
- \\HHHH
-
-The Codec interface defines a set of methods for encoding and decoding application level encoding schemes,
- such as HTML entity encoding and percent encoding (aka URL encoding). Codecs are used in output encoding
- and canonicalization. The design of these codecs allows for character-by-character decoding, which is
- necessary to detect double-encoding and the use of multiple encoding schemes, both of which are techniques
- used by attackers to bypass validation and bury encoded attacks in data.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
decodeCharacter(PushbackString input)
-
-
- Returns the decoded version of the next character from the input string and advances the
- current character in the PushbackString.
Returns the decoded version of the next character from the input string and advances the
- current character in the PushbackString. If the current character is not encoded, this
- method MUST reset the PushbackString.
-
Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
- Formats all are legal both with and without semi-colon, upper/lower case:
- dddd;
- hhhh;
- &name;
-
Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
- Formats all are legal both upper/lower case:
- \\a - special characters
- \\xHH
- \\uHHHH
-
-Implementation of the Codec interface for MySQL strings. See http://mirror.yandex.ru/mirrors/ftp.mysql.com/doc/refman/5.0/en/string-syntax.html
- for more information.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
- Formats all are legal (case sensitive)
- In ANSI_MODE '' decodes to '
- In MYSQL_MODE \x decodes to x (or a small list of specials)
-
-Implementation of the Codec interface for Oracle strings. See http://download-uk.oracle.com/docs/cd/B10501_01/text.920/a96518/cqspcl.htm
- for more information.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
- Formats all are legal both upper/lower case:
- %hh;
-
-The pushback string is used by Codecs to allow them to push decoded characters back onto a string
- for further decoding. This is necessary to detect double-encoding.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
- Formats all are legal both upper/lower case:
- "x - all special characters
- " + chr(x) + " - not supported yet
-
VBScriptCodec.decodeCharacter(PushbackString input)
-
-
- Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
-
-
- java.lang.Character
-
PercentCodec.decodeCharacter(PushbackString input)
-
-
- Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
-
-
- java.lang.Character
-
OracleCodec.decodeCharacter(PushbackString input)
-
-
- Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
-
-
- java.lang.Character
-
MySQLCodec.decodeCharacter(PushbackString input)
-
-
- Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
-
-
- java.lang.Character
-
JavaScriptCodec.decodeCharacter(PushbackString input)
-
-
- Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
-
-
- java.lang.Character
-
HTMLEntityCodec.decodeCharacter(PushbackString input)
-
-
- Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
-
-
- java.lang.Character
-
CSSCodec.decodeCharacter(PushbackString input)
-
-
- Returns the decoded version of the character starting at index, or
- null if no decoding is possible.
-
-
-
- java.lang.Character
-
Codec.decodeCharacter(PushbackString input)
-
-
- Returns the decoded version of the next character from the input string and advances the
- current character in the PushbackString.
The Codec interface defines a set of methods for encoding and decoding application level encoding schemes,
- such as HTML entity encoding and percent encoding (aka URL encoding).
A Base64.InputStream will read data from another
- java.io.InputStream, given in the constructor,
- and encode/decode to/from Base64 notation on the fly.
A Base64.OutputStream will write data to another
- java.io.OutputStream, given in the constructor,
- and encode/decode to/from Base64 notation on the fly.
Codec
-
-
- The Codec interface defines a set of methods for encoding and decoding application level encoding schemes,
- such as HTML entity encoding and percent encoding (aka URL encoding).
Codec
-
-
- The Codec interface defines a set of methods for encoding and decoding application level encoding schemes,
- such as HTML entity encoding and percent encoding (aka URL encoding).
-
-
-
PushbackString
-
-
- The pushback string is used by Codecs to allow them to push decoded characters back onto a string
- for further decoding.
Codec
-
-
- The Codec interface defines a set of methods for encoding and decoding application level encoding schemes,
- such as HTML entity encoding and percent encoding (aka URL encoding).
-An AuthenticationException should be thrown when anything goes wrong during
- login or logout. They are also appropriate for any problems related to
- identity management.
-
AuthenticationAccountsException(java.lang.String userMessage,
- java.lang.String logMessage)
-
-
- Creates a new instance of EnterpriseSecurityException.
-
-
-
AuthenticationAccountsException(java.lang.String userMessage,
- java.lang.String logMessage,
- java.lang.Throwable cause)
-
-
- Instantiates a new authentication exception.
-An AuthenticationException should be thrown when anything goes wrong during
- login or logout. They are also appropriate for any problems related to
- identity management.
-
AuthenticationCredentialsException(java.lang.String userMessage,
- java.lang.String logMessage)
-
-
- Creates a new instance of EnterpriseSecurityException.
-
-
-
AuthenticationCredentialsException(java.lang.String userMessage,
- java.lang.String logMessage,
- java.lang.Throwable cause)
-
-
- Instantiates a new authentication exception.
-An AuthenticationException should be thrown when anything goes wrong during
- login or logout. They are also appropriate for any problems related to
- identity management.
-
-An AuthenticationHostException should be thrown when there is a problem with
- the host involved with authentication, particularly if the host changes unexpectedly.
-
-An AuthenticationException should be thrown when anything goes wrong during
- login or logout. They are also appropriate for any problems related to
- identity management.
-
-An AvailabilityException should be thrown when the availability of a limited
- resource is in jeopardy. For example, if a database connection pool runs out
- of connections, an availability exception should be thrown.
-
-EnterpriseSecurityException is the base class for all security related exceptions. You should pass in the root cause
- exception where possible. Constructors for classes extending EnterpriseSecurityException should be sure to call the
- appropriate super() method in order to ensure that logging and intrusion detection occur properly.
-
- All EnterpriseSecurityExceptions have two messages, one for the user and one for the log file. This way, a message
- can be shown to the user that doesn't contain sensitive information or unnecessary implementation details. Meanwhile,
- all the critical information can be included in the exception so that it gets logged.
-
- Note that the "logMessage" for ALL EnterpriseSecurityExceptions is logged in the log file. This feature should be
- used extensively throughout ESAPI implementations and the result is a fairly complete set of security log records.
- ALL EnterpriseSecurityExceptions are also sent to the IntrusionDetector for use in detecting anomolous patterns of
- application usage.
-
EnterpriseSecurityException(java.lang.String userMessage,
- java.lang.String logMessage)
-
-
- Creates a new instance of EnterpriseSecurityException.
-
-
-
EnterpriseSecurityException(java.lang.String userMessage,
- java.lang.String logMessage,
- java.lang.Throwable cause)
-
-
- Creates a new instance of EnterpriseSecurityException that includes a root cause Throwable.
Creates a new instance of EnterpriseSecurityException. This exception is automatically logged, so that simply by
- using this API, applications will generate an extensive security log. In addition, this exception is
- automatically registered with the IntrusionDetector, so that quotas can be checked.
-
-An AvailabilityException should be thrown when the availability of a limited
- resource is in jeopardy. For example, if a database connection pool runs out
- of connections, an availability exception should be thrown.
-
-An IntrusionException should be thrown anytime an error condition arises that is likely to be the result of an attack
- in progress. IntrusionExceptions are handled specially by the IntrusionDetector, which is equipped to respond by
- either specially logging the event, logging out the current user, or invalidating the current user's account.
-
- Unlike other exceptions in the ESAPI, the IntrusionException is a RuntimeException so that it can be thrown from
- anywhere and will not require a lot of special exception handling.
-
-A ValidationException should be thrown to indicate that the data provided by
- the user or from some other external source does not match the validation
- rules that have been specified for that data.
-
HTTPUtilities.assertSecureRequest(javax.servlet.http.HttpServletRequest request)
-
-
- Ensures that the current request uses SSL and POST to protect any sensitive parameters
- in the querystring from being sniffed or logged.
-
-
-
- void
-
HTTPUtilities.safeSendForward(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response,
- java.lang.String context,
- java.lang.String location)
-
-
- This method perform a forward to any resource located inside the WEB-INF directory.
-
-
-
- java.lang.Object
-
AccessReferenceMap.getDirectReference(java.lang.String indirectReference)
-
-
- Get the original direct object reference from an indirect reference.
-
-
-
- java.lang.String
-
AccessReferenceMap.removeDirectReference(java.lang.Object direct)
-
-
- Removes a direct reference and its associated indirect reference from the AccessReferenceMap.
-
-
-
- void
-
AccessController.assertAuthorizedForURL(java.lang.String url)
-
-
- Checks if an account is authorized to access the referenced URL.
-
-
-
- void
-
AccessController.assertAuthorizedForFunction(java.lang.String functionName)
-
-
- Checks if an account is authorized to access the referenced function.
-
-
-
- void
-
AccessController.assertAuthorizedForData(java.lang.String key)
-
-
- Checks if an account is authorized to access the referenced data.
-
-
-
- void
-
AccessController.assertAuthorizedForFile(java.lang.String filepath)
-
-
- Checks if an account is authorized to access the referenced file.
-
-
-
- void
-
AccessController.assertAuthorizedForService(java.lang.String serviceName)
-
-
- Checks if an account is authorized to access the referenced service.
DefaultHTTPUtilities.assertSecureRequest(javax.servlet.http.HttpServletRequest request)
-
-
- Verifies that the request is "secure" by checking that the method is a POST and
- that SSL has been used.
User.addRole(java.lang.String role)
-
-
- Adds a role to an account.
-
-
-
- void
-
User.addRoles(java.util.Set newRoles)
-
-
- Adds a set of roles to an account.
-
-
-
- void
-
User.changePassword(java.lang.String oldPassword,
- java.lang.String newPassword1,
- java.lang.String newPassword2)
-
-
- Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
-
-
-
- java.util.Date
-
User.getLastFailedLoginTime()
-
-
- Returns the date of the last failed login time for a user.
-
-
-
- void
-
User.loginWithPassword(java.lang.String password)
-
-
- Login with password.
-
-
-
- void
-
User.removeRole(java.lang.String role)
-
-
- Removes a role from an account.
-
-
-
- java.lang.String
-
User.resetCSRFToken()
-
-
- Returns a token to be used as a prevention against CSRF attacks.
-
-
-
- void
-
User.setRoles(java.util.Set roles)
-
-
- Sets the roles of this account.
-
-
-
- javax.servlet.http.HttpSession
-
HTTPUtilities.changeSessionIdentifier(javax.servlet.http.HttpServletRequest request)
-
-
- Invalidate the old session after copying all of its contents to a newly created session with a new session id.
Authenticator.login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Authenticates the user's credentials from the HttpServletRequest if
- necessary, creates a session if necessary, and sets the user as the
- current user.
Authenticator.createUser(java.lang.String accountName,
- java.lang.String password1,
- java.lang.String password2)
-
-
- Creates a new User with the information provided.
-
-
-
- void
-
Authenticator.changePassword(User user,
- java.lang.String currentPassword,
- java.lang.String newPassword,
- java.lang.String newPassword2)
-
-
- Changes the password for the specified user.
-
-
-
- void
-
Authenticator.removeUser(java.lang.String accountName)
-
-
- Removes the account.
-
-
-
- void
-
Authenticator.verifyAccountNameStrength(java.lang.String accountName)
-
-
- Ensures that the account name passes site-specific complexity requirements, like minimum length.
-
-
-
- void
-
Authenticator.verifyPasswordStrength(java.lang.String oldPassword,
- java.lang.String newPassword)
-
-
- Ensures that the password meets site-specific complexity requirements.
AuthenticationHostException
-
-
- An AuthenticationHostException should be thrown when there is a problem with
- the host involved with authentication, particularly if the host changes unexpectedly.
-
-
-
- class
-
AuthenticationLoginException
-
-
- An AuthenticationException should be thrown when anything goes wrong during
- login or logout.
FileBasedAuthenticator.login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- This method should be called for every HTTP request, to login the current user either from the session of HTTP
- request.
Encoder.canonicalize(java.lang.String input)
-
-
- This method performs canonicalization on data received to ensure that it
- has been reduced to its most basic form before validation.
User.changePassword(java.lang.String oldPassword,
- java.lang.String newPassword1,
- java.lang.String newPassword2)
-
-
- Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
-
-
-
- boolean
-
User.verifyPassword(java.lang.String password)
-
-
- Verify that the supplied password matches the password for this user.
-
-
-
- java.lang.String
-
Randomizer.getRandomGUID()
-
-
- Generates a random GUID.
-
-
-
- java.lang.String
-
HTTPUtilities.encryptHiddenField(java.lang.String value)
-
-
- Encrypts a hidden field value for use in HTML.
-
-
-
- java.lang.String
-
HTTPUtilities.encryptQueryString(java.lang.String query)
-
-
- Takes a querystring (i.e.
-
-
-
- java.util.Map
-
HTTPUtilities.decryptQueryString(java.lang.String encrypted)
-
-
- Takes an encrypted querystring and returns a Map containing the original parameters.
-
-
-
- java.util.Map
-
HTTPUtilities.decryptStateFromCookie(javax.servlet.http.HttpServletRequest request)
-
-
- Retrieves a map of data from a cookie encrypted with encryptStateInCookie().
-
-
-
- void
-
HTTPUtilities.encryptStateInCookie(javax.servlet.http.HttpServletResponse response,
- java.util.Map cleartext)
-
-
- Stores a Map of data in an encrypted cookie.
-
-
-
- java.lang.String
-
Encryptor.hash(java.lang.String plaintext,
- java.lang.String salt)
-
-
- Returns a string representation of the hash of the provided plaintext and
- salt.
-
-
-
- java.lang.String
-
Encryptor.encrypt(java.lang.String plaintext)
-
-
- Encrypts the provided plaintext and returns a ciphertext string.
-
-
-
- java.lang.String
-
Encryptor.decrypt(java.lang.String ciphertext)
-
-
- Decrypts the provided ciphertext string (encrypted with the encrypt
- method) and returns a plaintext string.
-
-
-
- java.lang.String
-
Encryptor.sign(java.lang.String data)
-
-
- Create a digital signature for the provided data and return it in a
- string.
-
-
-
- java.lang.String
-
Encryptor.unseal(java.lang.String seal)
-
-
- Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
-
-
-
- java.lang.String
-
EncryptedProperties.getProperty(java.lang.String key)
-
-
- Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller.
-
-
-
- java.lang.String
-
EncryptedProperties.setProperty(java.lang.String key,
- java.lang.String value)
-
-
- Encrypts the plaintext property value and stores the ciphertext value in the encrypted store.
-
-
-
- java.lang.String
-
Authenticator.hashPassword(java.lang.String password,
- java.lang.String accountName)
-
-
- Returns a string representation of the hashed password, using the
- accountName as the salt.
JavaEncryptor.hash(java.lang.String plaintext,
- java.lang.String salt)
-
-
- Hashes the data using the specified algorithm and the Java MessageDigest class.
AuthenticationException
-
-
- An AuthenticationException should be thrown when anything goes wrong during
- login or logout.
-
-
-
- class
-
AuthenticationHostException
-
-
- An AuthenticationHostException should be thrown when there is a problem with
- the host involved with authentication, particularly if the host changes unexpectedly.
-
-
-
- class
-
AuthenticationLoginException
-
-
- An AuthenticationException should be thrown when anything goes wrong during
- login or logout.
-
-
-
- class
-
AvailabilityException
-
-
- An AvailabilityException should be thrown when the availability of a limited
- resource is in jeopardy.
-
-
-
- class
-
CertificateException
-
-
- A CertificateException should be thrown for any problems that arise during
- processing of digital certificates.
-
-
-
- class
-
EncodingException
-
-
- An ExecutorException should be thrown for any problems that occur when
- encoding or decoding data.
-
-
-
- class
-
EncryptionException
-
-
- An EncryptionException should be thrown for any problems related to
- encryption, hashing, or digital signatures.
-
-
-
- class
-
ExecutorException
-
-
- An ExecutorException should be thrown for any problems that arise during the
- execution of a system executable.
-
-
-
- class
-
IntegrityException
-
-
- An AvailabilityException should be thrown when the availability of a limited
- resource is in jeopardy.
ValidationException
-
-
- A ValidationException should be thrown to indicate that the data provided by
- the user or from some other external source does not match the validation
- rules that have been specified for that data.
Executor.executeSystemCommand(java.io.File executable,
- java.util.List params,
- java.io.File workdir,
- int timeoutSeconds)
-
-
- Executes a system command after checking that the executable exists and
- that the parameters have not been subject to injection with untrusted
- user data.
Validator.isValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is valid according to the specified type.
-
-
-
- java.lang.String
-
Validator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated input as a String.
-
-
-
- java.lang.String
-
Validator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns canonicalized and validated input as a String.
-
-
-
- boolean
-
Validator.isValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns true if input is a valid date according to the specified date format.
-
-
-
- java.util.Date
-
Validator.getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns a valid date as a Date.
-
-
-
- java.util.Date
-
Validator.getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a valid date as a Date.
-
-
-
- boolean
-
Validator.isValidSafeHTML(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is "safe" HTML.
-
-
-
- java.lang.String
-
Validator.getValidSafeHTML(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated "safe" HTML.
Validator.isValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid credit card.
-
-
-
- java.lang.String
-
Validator.getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- java.lang.String
-
Validator.getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- boolean
-
Validator.isValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid directory path.
-
-
-
- java.lang.String
-
Validator.getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- java.lang.String
-
Validator.getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- boolean
-
Validator.isValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid file name.
-
-
-
- java.lang.String
-
Validator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.String
-
Validator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- boolean
-
Validator.isValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid number within the range of minValue to maxValue.
-
-
-
- java.lang.Double
-
Validator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double within the range of minValue to maxValue.
-
-
-
- java.lang.Double
-
Validator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a validated number as a double within the range of minValue to maxValue.
-
-
-
- boolean
-
Validator.isValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid integer within the range of minValue to maxValue.
-
-
-
- java.lang.Integer
-
Validator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated integer.
-
-
-
- java.lang.Integer
-
Validator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a validated integer.
-
-
-
- boolean
-
Validator.isValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid double within the range of minValue to maxValue.
-
-
-
- java.lang.Double
-
Validator.getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns a validated real number as a double.
-
-
-
- java.lang.Double
-
Validator.getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a validated real number as a double.
-
-
-
- boolean
-
Validator.isValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if input is valid file content.
-
-
-
- byte[]
-
Validator.getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
-
-
-
- byte[]
-
Validator.getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns validated file content as a byte array.
-
-
-
- boolean
-
Validator.isValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if a file upload has a valid name, path, and content.
-
-
-
- void
-
Validator.assertValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- void
-
Validator.assertValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- boolean
-
Validator.isValidHTTPRequest()
-
-
- Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- void
-
Validator.assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- boolean
-
Validator.isValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns true if input is a valid list item.
-
-
-
- java.lang.String
-
Validator.getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- java.lang.String
-
Validator.getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list,
- ValidationErrorList errorList)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- boolean
-
Validator.isValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Returns true if the parameters in the current request contain all required parameters and only optional ones in addition.
-
-
-
- void
-
Validator.assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- void
-
Validator.assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional,
- ValidationErrorList errorList)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- boolean
-
Validator.isValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input contains only valid printable ASCII characters.
-
-
-
- byte[]
-
Validator.getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns canonicalized and validated printable characters as a byte array.
-
-
-
- boolean
-
Validator.isValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input contains only valid printable ASCII characters (32-126).
-
-
-
- java.lang.String
-
Validator.getValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns canonicalized and validated printable characters as a String.
-
-
-
- boolean
-
Validator.isValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid redirect location, as defined by "ESAPI.properties".
-
-
-
- java.lang.String
-
Validator.getValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated redirect location as a String.
-
-
-
- java.lang.String
-
Validator.getValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errorList)
-
-
- Returns a canonicalized and validated redirect location as a String.
-
-
-
- void
-
IntrusionDetector.addException(java.lang.Exception exception)
-
-
- Adds the exception to the IntrusionDetector.
-
-
-
- void
-
IntrusionDetector.addEvent(java.lang.String eventName,
- java.lang.String logMessage)
-
-
- Adds the event to the IntrusionDetector.
-
-
-
- void
-
HTTPUtilities.verifyCSRFToken(javax.servlet.http.HttpServletRequest request)
-
-
- Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and
- throws an IntrusionException if it is missing.
DefaultValidator.isValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if data received from browser is valid.
-
-
-
- java.lang.String
-
DefaultValidator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Validates data received from the browser and returns a safe version.
-
-
-
- java.lang.String
-
DefaultValidator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Validates data received from the browser and returns a safe version.
-
-
-
- boolean
-
DefaultValidator.isValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns true if input is a valid date according to the specified date format.
DefaultValidator.getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
DefaultValidator.isValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if the directory path (not including a filename) is valid.
-
-
-
- java.lang.String
-
DefaultValidator.getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
DefaultValidator.isValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid file name.
-
-
-
- java.lang.String
-
DefaultValidator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.String
-
DefaultValidator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- boolean
-
DefaultValidator.isValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
-
-
-
-
- java.lang.Double
-
DefaultValidator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- java.lang.Double
-
DefaultValidator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull,
- ValidationErrorList errors)
-
-
-
DefaultValidator.isValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
-
-
-
-
- java.lang.Integer
-
DefaultValidator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- java.lang.Integer
-
DefaultValidator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull,
- ValidationErrorList errors)
-
-
-
-
-
-
- boolean
-
DefaultValidator.isValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if input is valid file content.
-
-
-
- byte[]
-
DefaultValidator.getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
DefaultValidator.isValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- boolean
-
DefaultValidator.isValidHTTPRequest(javax.servlet.http.HttpServletRequest request)
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- void
-
DefaultValidator.assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- java.lang.String
-
DefaultValidator.getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
DefaultValidator.assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
Validator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated input as a String.
-
-
-
- java.util.Date
-
Validator.getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns a valid date as a Date.
-
-
-
- java.lang.String
-
Validator.getValidSafeHTML(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated "safe" HTML.
-
-
-
- java.lang.String
-
Validator.getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- java.lang.String
-
Validator.getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- java.lang.String
-
Validator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.Double
-
Validator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double within the range of minValue to maxValue.
-
-
-
- java.lang.Integer
-
Validator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated integer.
-
-
-
- java.lang.Double
-
Validator.getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns a validated real number as a double.
-
-
-
- byte[]
-
Validator.getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
-
-
-
- void
-
Validator.assertValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- void
-
Validator.assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- java.lang.String
-
Validator.getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- void
-
Validator.assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- byte[]
-
Validator.getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a byte array.
-
-
-
- java.lang.String
-
Validator.getValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a String.
-
-
-
- java.lang.String
-
Validator.getValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated redirect location as a String.
-
-
-
- java.lang.String
-
Validator.safeReadLine(java.io.InputStream inputStream,
- int maxLength)
-
-
- Reads from an input stream until end-of-line or a maximum number of
- characters.
-
-
-
- java.util.List
-
HTTPUtilities.getSafeFileUploads(javax.servlet.http.HttpServletRequest request,
- java.io.File tempDir,
- java.io.File finalDir)
-
-
- Extract uploaded files from a multipart HTTP requests.
DefaultValidator.getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Validates data received from the browser and returns a safe version.
DefaultValidator.getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- java.lang.String
-
DefaultValidator.getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- java.lang.String
-
DefaultValidator.getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.Double
-
DefaultValidator.getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- java.lang.Double
-
DefaultValidator.getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- java.lang.Integer
-
DefaultValidator.getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- byte[]
-
DefaultValidator.getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
-
-
-
- void
-
DefaultValidator.assertValidFileUpload(java.lang.String context,
- java.lang.String directorypath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- void
-
DefaultValidator.assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- java.lang.String
-
DefaultValidator.getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- void
-
DefaultValidator.assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- byte[]
-
DefaultValidator.getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a byte array.
-
-
-
- java.lang.String
-
DefaultValidator.getValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a String.
-
-
-
- java.lang.String
-
DefaultValidator.getValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated redirect location as a String.
-
-
-
- java.lang.String
-
DefaultValidator.safeReadLine(java.io.InputStream in,
- int max)
-
-
- This implementation reads until a newline or the specified number of
- characters.
-
-
-
- java.util.List
-
DefaultHTTPUtilities.getSafeFileUploads(javax.servlet.http.HttpServletRequest request,
- java.io.File tempDir,
- java.io.File finalDir)
-
-
- Uses the Apache Commons FileUploader to parse the multipart HTTP request
- and extract any files therein.
-
-
-
- void
-
LoggerTest.testLogHTTPRequest()
-
-
- Test of logHTTPRequest method, of class org.owasp.esapi.Logger.
-
-
-
- void
-
HTTPUtilitiesTest.testSendSafeRedirect()
-
-
- Test of sendRedirect method, of class org.owasp.esapi.HTTPUtilities.
-
-
-
- void
-
EncoderTest.testNormalize()
-
-
- Test of normalize method, of class org.owasp.esapi.Validator.
An AuthenticationHostException should be thrown when there is a problem with
- the host involved with authentication, particularly if the host changes unexpectedly.
A ValidationException should be thrown to indicate that the data provided by
- the user or from some other external source does not match the validation
- rules that have been specified for that data.
-A set of exception classes designed to model the error conditions that
-frequently arise in enterprise web applications and web services. The
-root class is the EnterpriseSecurityException and all the other
-exception classes extend this basic class. The
-EnterpriseSecurityException automatically logs a message in the
-constructor so that a full set of security events are captured in the
-logs.
-
AccessControlException
-
-
- An AccessControlException should be thrown when a user attempts to access a
- resource that they are not authorized for.
-
-
-
AuthenticationException
-
-
- An AuthenticationException should be thrown when anything goes wrong during
- login or logout.
-
-
-
EncodingException
-
-
- An ExecutorException should be thrown for any problems that occur when
- encoding or decoding data.
-
-
-
EncryptionException
-
-
- An EncryptionException should be thrown for any problems related to
- encryption, hashing, or digital signatures.
-
-
-
ExecutorException
-
-
- An ExecutorException should be thrown for any problems that arise during the
- execution of a system executable.
-
-
-
IntegrityException
-
-
- An AvailabilityException should be thrown when the availability of a limited
- resource is in jeopardy.
-
-
-
IntrusionException
-
-
- An IntrusionException should be thrown anytime an error condition arises that is likely to be the result of an attack
- in progress.
-
-
-
ValidationException
-
-
- A ValidationException should be thrown to indicate that the data provided by
- the user or from some other external source does not match the validation
- rules that have been specified for that data.
AuthenticationException
-
-
- An AuthenticationException should be thrown when anything goes wrong during
- login or logout.
-
-
-
EnterpriseSecurityException
-
-
- EnterpriseSecurityException is the base class for all security related exceptions.
-
-
-
ValidationException
-
-
- A ValidationException should be thrown to indicate that the data provided by
- the user or from some other external source does not match the validation
- rules that have been specified for that data.
AccessControlException
-
-
- An AccessControlException should be thrown when a user attempts to access a
- resource that they are not authorized for.
-
-
-
AuthenticationException
-
-
- An AuthenticationException should be thrown when anything goes wrong during
- login or logout.
-
-
-
EncodingException
-
-
- An ExecutorException should be thrown for any problems that occur when
- encoding or decoding data.
-
-
-
EncryptionException
-
-
- An EncryptionException should be thrown for any problems related to
- encryption, hashing, or digital signatures.
-
-
-
EnterpriseSecurityException
-
-
- EnterpriseSecurityException is the base class for all security related exceptions.
-
-
-
ExecutorException
-
-
- An ExecutorException should be thrown for any problems that arise during the
- execution of a system executable.
-
-
-
IntegrityException
-
-
- An AvailabilityException should be thrown when the availability of a limited
- resource is in jeopardy.
-
-
-
IntrusionException
-
-
- An IntrusionException should be thrown anytime an error condition arises that is likely to be the result of an attack
- in progress.
-
-
-
ValidationException
-
-
- A ValidationException should be thrown to indicate that the data provided by
- the user or from some other external source does not match the validation
- rules that have been specified for that data.
destroy()
-
-
- Called by the web container to indicate to a filter that it is being
- taken out of service.
-
-
-
- void
-
doFilter(javax.servlet.ServletRequest req,
- javax.servlet.ServletResponse resp,
- javax.servlet.FilterChain chain)
-
-
- The doFilter method of the Filter is called by the container each time a
- request/response pair is passed through the chain due to a client request
- for a resource at the end of the chain.
-
-
-
- void
-
init(javax.servlet.FilterConfig filterConfig)
-
-
- Called by the web container to indicate to a filter that it is being
- placed into service.
Called by the web container to indicate to a filter that it is being
- placed into service. The servlet container calls the init method exactly
- once after instantiating the filter. The init method must complete
- successfully before the filter is asked to do any filtering work.
-
The doFilter method of the Filter is called by the container each time a
- request/response pair is passed through the chain due to a client request
- for a resource at the end of the chain. The FilterChain passed in to this
- method allows the Filter to pass on the request and response to the next
- entity in the chain.
-
-
-
Specified by:
doFilter in interface javax.servlet.Filter
-
-
-
Parameters:
chain - current FilterChain
-
Throws:
-
java.io.IOException - if any occurs
-
javax.servlet.ServletException
-
-
-
-
-
-destroy
-
-public void destroy()
-
-
Called by the web container to indicate to a filter that it is being
- taken out of service. This method is only called once all threads within
- the filter's doFilter method have exited or after a timeout period has
- passed. After the web container calls this method, it will not call the
- doFilter method again on this instance of the filter.
-
-This filter wraps the incoming request and outgoing response and overrides
- many methods with safer versions. Many of the safer versions simply validate
- parts of the request or response for unwanted characters before allowing the
- call to complete. Some examples of attacks that use these
- vectors include request splitting, response splitting, and file download
- injection. Attackers use techniques like CRLF injection and null byte injection
- to confuse the parsing of requests and responses.
-
-This filter wraps the incoming request and outgoing response and overrides
- several of the methods with versions that protect against unsafe characters
- in request and response headers. Some examples of attacks that use these
- vectors include request splitting, response splitting, and file download
- injection. Attackers use techniques like CRLF injection and null byte injection
- to confuse the parsing of requests and responses.
-
-This request wrapper simply overrides unsafe methods in the HttpServletRequest
- API with safe versions that return canonicalized data where possible. The wrapper
- returns a safe value when a validation error is detected, including stripped or
- empty strings.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Field Summary
-
-
-
-
-
-
Fields inherited from interface javax.servlet.http.HttpServletRequest
SafeRequest(javax.servlet.http.HttpServletRequest request)
-
-
- Construct a safe request that overrides the default request methods with safer versions.
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.Object
-
getAttribute(java.lang.String name)
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.util.Enumeration
-
getAttributeNames()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getAuthType()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getCharacterEncoding()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- int
-
getContentLength()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getContentType()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getContextPath()
-
-
- Returns the context path from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- javax.servlet.http.Cookie[]
-
getCookies()
-
-
- Returns the array of Cookies from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- long
-
getDateHeader(java.lang.String name)
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getHeader(java.lang.String name)
-
-
- Returns the named header from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.util.Enumeration
-
getHeaderNames()
-
-
- Returns the enumeration of header names from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.util.Enumeration
-
getHeaders(java.lang.String name)
-
-
- Returns the enumeration of headers from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- javax.servlet.ServletInputStream
-
getInputStream()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- int
-
getIntHeader(java.lang.String name)
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getLocalAddr()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.util.Locale
-
getLocale()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.util.Enumeration
-
getLocales()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getLocalName()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- int
-
getLocalPort()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getMethod()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getParameter(java.lang.String name)
-
-
- Returns the named parameter from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.util.Map
-
getParameterMap()
-
-
- Returns the parameter map from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.util.Enumeration
-
getParameterNames()
-
-
- Returns the enumeration of parameter names from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.lang.String[]
-
getParameterValues(java.lang.String name)
-
-
- Returns the array of matching parameter values from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.lang.String
-
getPathInfo()
-
-
- Returns the path info from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.lang.String
-
getPathTranslated()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getProtocol()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getQueryString()
-
-
- Returns the query string from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.io.BufferedReader
-
getReader()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getRealPath(java.lang.String path)
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getRemoteAddr()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getRemoteHost()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- int
-
getRemotePort()
-
-
- Same as HttpServletRequest, no security changes required.
-
-
-
- java.lang.String
-
getRemoteUser()
-
-
- Returns the name of the ESAPI user associated with this request.
-
-
-
- javax.servlet.RequestDispatcher
-
getRequestDispatcher(java.lang.String path)
-
-
- Checks to make sure the path to forward to is within the WEB-INF directory
- and then returns the dispatcher.
-
-
-
- java.lang.String
-
getRequestedSessionId()
-
-
- Returns the URI from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.lang.String
-
getRequestURI()
-
-
- Returns the URI from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.lang.StringBuffer
-
getRequestURL()
-
-
- Returns the URL from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.lang.String
-
getScheme()
-
-
- Returns the scheme from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- java.lang.String
-
getServerName()
-
-
- Returns the server name (host header) from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- int
-
getServerPort()
-
-
- Returns the server port (after the : in the host header) from the HttpServletRequest after
- parsing and checking the range 0-65536.
-
-
-
- java.lang.String
-
getServletPath()
-
-
- Returns the server path from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
- javax.servlet.http.HttpSession
-
getSession()
-
-
- Returns a session, creating it if necessary, and sets the HttpOnly flag on the JSESSIONID cookie.
-
-
-
- javax.servlet.http.HttpSession
-
getSession(boolean create)
-
-
- Returns a session, creating it if necessary, and sets the HttpOnly flag on the JSESSIONID cookie.
-
-
-
- java.security.Principal
-
getUserPrincipal()
-
-
- Returns the ESAPI User associated with this request.
Same as HttpServletRequest, no security changes required.
- Note that this input stream may contain attacks and the
- developer is responsible for canonicalizing, validating,
- and encoding any data from this stream.
-
-
-
Specified by:
getInputStream in interface javax.servlet.ServletRequest
-
-
-
-
Throws:
-
java.io.IOException
-
-
-
-
-
-getIntHeader
-
-public int getIntHeader(java.lang.String name)
-
-
Same as HttpServletRequest, no security changes required.
-
-
-
Specified by:
getIntHeader in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
-
-
-getLocalAddr
-
-public java.lang.String getLocalAddr()
-
-
Same as HttpServletRequest, no security changes required.
-
-
-
Specified by:
getLocalAddr in interface javax.servlet.ServletRequest
-
-
-
-
-
-
-
-
-getLocale
-
-public java.util.Locale getLocale()
-
-
Same as HttpServletRequest, no security changes required.
-
-
-
Specified by:
getLocale in interface javax.servlet.ServletRequest
-
-
-
-
-
-
-
-
-getLocales
-
-public java.util.Enumeration getLocales()
-
-
Same as HttpServletRequest, no security changes required.
-
-
-
Specified by:
getLocales in interface javax.servlet.ServletRequest
-
-
-
-
-
-
-
-
-getLocalName
-
-public java.lang.String getLocalName()
-
-
Same as HttpServletRequest, no security changes required.
-
-
-
Specified by:
getLocalName in interface javax.servlet.ServletRequest
-
-
-
-
-
-
-
-
-getLocalPort
-
-public int getLocalPort()
-
-
Same as HttpServletRequest, no security changes required.
-
-
-
Specified by:
getLocalPort in interface javax.servlet.ServletRequest
-
-
-
-
-
-
-
-
-getMethod
-
-public java.lang.String getMethod()
-
-
Same as HttpServletRequest, no security changes required.
-
-
-
Specified by:
getMethod in interface javax.servlet.http.HttpServletRequest
Same as HttpServletRequest, no security changes required.
- Note that this reader may contain attacks and the
- developer is responsible for canonicalizing, validating,
- and encoding any data from this stream.
-
-
-
Specified by:
getReader in interface javax.servlet.ServletRequest
Checks to make sure the path to forward to is within the WEB-INF directory
- and then returns the dispatcher. Otherwise returns null.
-
-
-
Specified by:
getRequestDispatcher in interface javax.servlet.ServletRequest
-
-
-
-
-
-
-
-
-getRequestedSessionId
-
-public java.lang.String getRequestedSessionId()
-
-
Returns the URI from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
- Code must be very careful not to depend on the value of a requested session id
- reported by the user.
-
-
-
Specified by:
getRequestedSessionId in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
-
-
-getRequestURI
-
-public java.lang.String getRequestURI()
-
-
Returns the URI from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
Specified by:
getRequestURI in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
-
-
-getRequestURL
-
-public java.lang.StringBuffer getRequestURL()
-
-
Returns the URL from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
Specified by:
getRequestURL in interface javax.servlet.http.HttpServletRequest
-
-
-
-
-
-
-
-
-getScheme
-
-public java.lang.String getScheme()
-
-
Returns the scheme from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
Specified by:
getScheme in interface javax.servlet.ServletRequest
-
-
-
-
-
-
-
-
-getServerName
-
-public java.lang.String getServerName()
-
-
Returns the server name (host header) from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
Specified by:
getServerName in interface javax.servlet.ServletRequest
-
-
-
-
-
-
-
-
-getServerPort
-
-public int getServerPort()
-
-
Returns the server port (after the : in the host header) from the HttpServletRequest after
- parsing and checking the range 0-65536.
-
-
-
Specified by:
getServerPort in interface javax.servlet.ServletRequest
-
-
-
-
-
-
-
-
-getServletPath
-
-public java.lang.String getServletPath()
-
-
Returns the server path from the HttpServletRequest after
- canonicalizing and filtering out any dangerous characters.
-
-
-
Specified by:
getServletPath in interface javax.servlet.http.HttpServletRequest
SafeResponse(javax.servlet.http.HttpServletResponse response)
-
-
- Construct a safe response that overrides the default response methods
- with safer versions.
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- void
-
addCookie(javax.servlet.http.Cookie cookie)
-
-
- Add a cookie to the response after ensuring that there are no encoded or
- illegal characters in the name and name and value.
-
-
-
- void
-
addCookie(java.lang.String name,
- java.lang.String value,
- int maxAge,
- java.lang.String domain,
- java.lang.String path)
-
-
- Add a cookie to the response after ensuring that there are no encoded or
- illegal characters in the name and name and value.
-
-
-
- void
-
addDateHeader(java.lang.String name,
- long date)
-
-
- Add a cookie to the response after ensuring that there are no encoded or
- illegal characters in the name.
-
-
-
- void
-
addHeader(java.lang.String name,
- java.lang.String value)
-
-
- Add a header to the response after ensuring that there are no encoded or
- illegal characters in the name and name and value.
-
-
-
- void
-
addIntHeader(java.lang.String name,
- int value)
-
-
- Add an int header to the response after ensuring that there are no
- encoded or illegal characters in the name and name.
-
-
-
- boolean
-
containsHeader(java.lang.String name)
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- java.lang.String
-
encodeRedirectUrl(java.lang.String url)
-
-
- Return the URL without any changes, to prevent disclosure of the
- JSESSIONID.
-
-
-
- java.lang.String
-
encodeRedirectURL(java.lang.String url)
-
-
- Return the URL without any changes, to prevent disclosure of the
- JSESSIONID The default implementation of this method can add the
- JSESSIONID to the URL if support for cookies is not detected.
-
-
-
- java.lang.String
-
encodeUrl(java.lang.String url)
-
-
- Return the URL without any changes, to prevent disclosure of the
- JSESSIONID The default implementation of this method can add the
- JSESSIONID to the URL if support for cookies is not detected.
-
-
-
- java.lang.String
-
encodeURL(java.lang.String url)
-
-
- Return the URL without any changes, to prevent disclosure of the
- JSESSIONID The default implementation of this method can add the
- JSESSIONID to the URL if support for cookies is not detected.
-
-
-
- void
-
flushBuffer()
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- int
-
getBufferSize()
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- java.lang.String
-
getCharacterEncoding()
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- java.lang.String
-
getContentType()
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- java.util.Locale
-
getLocale()
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- javax.servlet.ServletOutputStream
-
getOutputStream()
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- java.io.PrintWriter
-
getWriter()
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- boolean
-
isCommitted()
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- void
-
reset()
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- void
-
resetBuffer()
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- void
-
sendError(int sc)
-
-
- Override the error code with a 200 in order to confound attackers using
- automated scanners.
-
-
-
- void
-
sendError(int sc,
- java.lang.String msg)
-
-
- Override the error code with a 200 in order to confound attackers using
- automated scanners.
-
-
-
- void
-
sendRedirect(java.lang.String location)
-
-
- This method generates a redirect response that can only be used to redirect the browser to safe locations,
- as configured in the ESAPI security configuration.
-
-
-
- void
-
setBufferSize(int size)
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- void
-
setCharacterEncoding(java.lang.String charset)
-
-
- Sets the character encoding to the ESAPI configured encoding.
-
-
-
- void
-
setContentLength(int len)
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- void
-
setContentType(java.lang.String type)
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- void
-
setDateHeader(java.lang.String name,
- long date)
-
-
- Add a date header to the response after ensuring that there are no
- encoded or illegal characters in the name.
-
-
-
- void
-
setHeader(java.lang.String name,
- java.lang.String value)
-
-
- Add a header to the response after ensuring that there are no encoded or
- illegal characters in the name and value.
-
-
-
- void
-
setIntHeader(java.lang.String name,
- int value)
-
-
- Add an int header to the response after ensuring that there are no
- encoded or illegal characters in the name.
-
-
-
- void
-
setLocale(java.util.Locale loc)
-
-
- Same as HttpServletResponse, no security changes required.
-
-
-
- void
-
setStatus(int sc)
-
-
- Override the status code with a 200 in order to confound attackers using
- automated scanners.
-
-
-
- void
-
setStatus(int sc,
- java.lang.String sm)
-
-
- Override the status code with a 200 in order to confound attackers using
- automated scanners.
Add a cookie to the response after ensuring that there are no encoded or
- illegal characters in the name and name and value. This method also sets
- the secure and HttpOnly flags on the cookie.
-
-
-
Specified by:
addCookie in interface javax.servlet.http.HttpServletResponse
Add a cookie to the response after ensuring that there are no encoded or
- illegal characters in the name and name and value. This method also sets
- the secure and HttpOnly flags on the cookie.
-
-
-
-
-
-
-
-
-
-
-
-addDateHeader
-
-public void addDateHeader(java.lang.String name,
- long date)
-
-
Add a cookie to the response after ensuring that there are no encoded or
- illegal characters in the name.
-
-
-
Specified by:
addDateHeader in interface javax.servlet.http.HttpServletResponse
Add a header to the response after ensuring that there are no encoded or
- illegal characters in the name and name and value. This implementation
- follows the following recommendation: "A recipient MAY replace any linear
- white space with a single SP before interpreting the field value or
- forwarding the message downstream."
- http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
-
-
-
Specified by:
addHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
-
-
-addIntHeader
-
-public void addIntHeader(java.lang.String name,
- int value)
-
-
Add an int header to the response after ensuring that there are no
- encoded or illegal characters in the name and name.
-
-
-
Specified by:
addIntHeader in interface javax.servlet.http.HttpServletResponse
Return the URL without any changes, to prevent disclosure of the
- JSESSIONID. The default implementation of this method can add the
- JSESSIONID to the URL if support for cookies is not detected. This
- exposes the JSESSIONID credential in bookmarks, referer headers, server
- logs, and more.
-
-
-
Specified by:
encodeRedirectUrl in interface javax.servlet.http.HttpServletResponse
Return the URL without any changes, to prevent disclosure of the
- JSESSIONID The default implementation of this method can add the
- JSESSIONID to the URL if support for cookies is not detected. This
- exposes the JSESSIONID credential in bookmarks, referer headers, server
- logs, and more.
-
-
-
Specified by:
encodeRedirectURL in interface javax.servlet.http.HttpServletResponse
Return the URL without any changes, to prevent disclosure of the
- JSESSIONID The default implementation of this method can add the
- JSESSIONID to the URL if support for cookies is not detected. This
- exposes the JSESSIONID credential in bookmarks, referer headers, server
- logs, and more.
-
-
-
Specified by:
encodeUrl in interface javax.servlet.http.HttpServletResponse
Return the URL without any changes, to prevent disclosure of the
- JSESSIONID The default implementation of this method can add the
- JSESSIONID to the URL if support for cookies is not detected. This
- exposes the JSESSIONID credential in bookmarks, referer headers, server
- logs, and more.
-
-
-
Specified by:
encodeURL in interface javax.servlet.http.HttpServletResponse
Override the error code with a 200 in order to confound attackers using
- automated scanners. The message is canonicalized and filtered for
- dangerous characters.
-
-
-
Specified by:
sendError in interface javax.servlet.http.HttpServletResponse
This method generates a redirect response that can only be used to redirect the browser to safe locations,
- as configured in the ESAPI security configuration. This method does not that redirect requests can be modified by
- attackers, so do not rely information contained within redirect requests, and do not include sensitive
- information in a redirect.
-
-
-
Specified by:
sendRedirect in interface javax.servlet.http.HttpServletResponse
-
-
-
-
Throws:
-
java.io.IOException
-
-
-
-
-
-setBufferSize
-
-public void setBufferSize(int size)
-
-
Same as HttpServletResponse, no security changes required.
-
-
-
Specified by:
setBufferSize in interface javax.servlet.ServletResponse
Add a header to the response after ensuring that there are no encoded or
- illegal characters in the name and value.
- "A recipient MAY replace any linear white space with a single SP before
- interpreting the field value or forwarding the message downstream."
- http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
-
-
-
Specified by:
setHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
-
-
-setIntHeader
-
-public void setIntHeader(java.lang.String name,
- int value)
-
-
Add an int header to the response after ensuring that there are no
- encoded or illegal characters in the name.
-
-
-
Specified by:
setIntHeader in interface javax.servlet.http.HttpServletResponse
-
-
-
-
-
-
-
-
-setLocale
-
-public void setLocale(java.util.Locale loc)
-
-
Same as HttpServletResponse, no security changes required.
-
-
-
Specified by:
setLocale in interface javax.servlet.ServletResponse
-
-
-
-
-
-
-
-
-setStatus
-
-public void setStatus(int sc)
-
-
Override the status code with a 200 in order to confound attackers using
- automated scanners.
-
-
-
Specified by:
setStatus in interface javax.servlet.http.HttpServletResponse
Override the status code with a 200 in order to confound attackers using
- automated scanners. The message is canonicalized and filtered for
- dangerous characters.
-
-
-
Specified by:
setStatus in interface javax.servlet.http.HttpServletResponse
SafeRequest
-
-
- This request wrapper simply overrides unsafe methods in the HttpServletRequest
- API with safe versions that return canonicalized data where possible.
-
-
-
SafeResponse
-
-
- This response wrapper simply overrides unsafe methods in the
- HttpServletResponse API with safe versions.
SafeRequest
-
-
- This request wrapper simply overrides unsafe methods in the HttpServletRequest
- API with safe versions that return canonicalized data where possible.
-
-
-
SafeResponse
-
-
- This response wrapper simply overrides unsafe methods in the
- HttpServletResponse API with safe versions.
-A few simple mock classes to help test the ESAPI reference
-implementation. These classes are not fully functional and only
-implement the functions required to test the library. These
-implementations are not fully accurate and may not behave like the real
-Java EE classes.
-
-The IAccessController interface defines a set of methods that can be used in a wide variety of applications to
- enforce access control. In most applications, access control must be performed in multiple different locations across
- the various applicaton layers. This class provides access control for URLs, business functions, data, services, and
- files.
-
-
-
- The implementation of this interface will need to access some sort of user information repository to determine what
- roles or permissions are assigned to the accountName passed into the various methods. In addition, the implementation
- will also need information about the resources that are being accessed. Using the user information and the resource
- information, the implementation should return an access control decision.
-
- Implementers are encouraged to build on existing access control mechanisms, such as methods like isUserInRole() or
- hasPrivilege(). While powerful, these methods can be confusing, as users may be in multiple roles or possess multiple
- overlapping privileges. These methods encourage the use of complex boolean tests throughout the code. The point of
- this interface is to centralize access control logic so that it is easy to use and easy to verify.
-
-
- if ( ESAPI.accessController().isAuthorizedForFunction( BUSINESS_FUNCTION ) ) {
- ... access is allowed
- } else {
- ... attack in progress
- }
-
-
- Note that in the user interface layer, access control checks can be used to control whether particular controls are
- rendered or not. These checks are supposed to fail when an unauthorized user is logged in, and do not represent
- attacks. Remember that regardless of how the user interface appears, an attacker can attempt to invoke any business
- function or access any data in your application. Therefore, access control checks in the user interface should be
- repeated in both the business logic and data layers.
-
-
Checks if an account is authorized to access the referenced URL. The implementation should allow
- access to be granted to any part of the URI. Generally, this method should be invoked in the
- application's controller or a filter as follows:
-
Checks if an account is authorized to access the referenced function. The implementation should define the
- function "namespace" to be enforced. Choosing something simple like the classname of action classes or menu item
- names will make this implementation easier to use.
-
Checks if an account is authorized to access the referenced service. This can be used in applications that
- provide access to a variety of backend services.
-
-The IAccessReferenceMap interface is used to map from a set of internal
- direct object references to a set of indirect references that are safe to
- disclose publically. This can be used to help protect database keys,
- filenames, and other types of direct object references. As a rule, developers
- should not expose their direct object references as it enables attackers to
- attempt to manipulate them.
-
-
-
-
- Indirect references are handled as strings, to facilitate their use in HTML.
- Implementations can generate simple integers or more complicated random
- character strings as indirect references. Implementations should probably add
- a constructor that takes a list of direct references.
-
- Note that in addition to defeating all forms of parameter tampering attacks,
- there is a side benefit of the AccessReferenceMap. Using random strings as indirect object
- references, as opposed to simple integers makes it impossible for an attacker to
- guess valid identifiers. So if per-user AccessReferenceMaps are used, then request
- forgery (CSRF) attacks will also be prevented.
-
-
- Set fileSet = new HashSet();
- fileSet.addAll(...);
- AccessReferenceMap map = new AccessReferenceMap( fileSet );
- // store the map somewhere safe - like the session!
- String indRef = map.getIndirectReference( file1 );
- String href = "http://www.aspectsecurity.com/esapi?file=" + indRef );
- ...
- String indref = request.getParameter( "file" );
- File file = (File)map.getDirectReference( indref );
-
-
-
-
-
-
-
-
Author:
-
Jeff Williams (jeff.williams@aspectsecurity.com)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
addDirectReference(java.lang.Object direct)
-
-
- Adds a direct reference to the AccessReferenceMap and generates an associated indirect reference.
-
-
-
- java.lang.Object
-
getDirectReference(java.lang.String indirectReference)
-
-
- Get the original direct object reference from an indirect reference.
-
-
-
- java.lang.String
-
getIndirectReference(java.lang.Object directReference)
-
-
- Get a safe indirect reference to use in place of a potentially sensitive
- direct object reference.
-
-
-
- java.util.Iterator
-
iterator()
-
-
- Get an iterator through the direct object references.
-
-
-
- java.lang.String
-
removeDirectReference(java.lang.Object direct)
-
-
- Removes a direct reference and its associated indirect reference from the AccessReferenceMap.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Detail
-
-
-
-
-iterator
-
-public java.util.Iterator iterator()
-
-
Get an iterator through the direct object references.
-
Get a safe indirect reference to use in place of a potentially sensitive
- direct object reference. Developers should use this call when building
- URL's, form fields, hidden fields, etc... to help protect their private
- implementation information.
-
Get the original direct object reference from an indirect reference.
- Developers should use this when they get an indirect reference from an
- HTTP request to translate it back into the real direct reference. If an
- invalid indirectReference is requested, then an AccessControlException is
- thrown.
-
-The IAuthenticator interface defines a set of methods for generating and
- handling account credentials and session identifiers. The goal of this
- interface is to encourage developers to protect credentials from disclosure
- to the maximum extent possible.
-
-
-
- Once possible implementation relies on the use of a thread local variable to
- store the current user's identity. The application is responsible for calling
- setCurrentUser() as soon as possible after each HTTP request is received. The
- value of getCurrentUser() is used in several other places in this API. This
- eliminates the need to pass a user object to methods throughout the library.
- For example, all of the logging, access control, and exception calls need
- access to the currently logged in user.
-
- The goal is to minimize the responsibility of the developer for
- authentication. In this example, the user simply calls authenticate with the
- current request and the name of the parameters containing the username and
- password. The implementation should verify the password if necessary, create
- a session if necessary, and set the user as the current user.
-
-
- public void doPost(ServletRequest request, ServletResponse response) {
- try {
- ESAPI.authenticator().authenticate(request, response, "username","password");
- // continue with authenticated user
- } catch (AuthenticationException e) {
- // handle failed authentication (it's already been logged)
- }
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- void
-
clearCurrent()
-
-
- Clear the current user, request, and response.
generateStrongPassword(java.lang.String oldPassword,
- IUser user)
-
-
- Generate strong password that takes into account the user's information and old password.
hashPassword(java.lang.String password,
- java.lang.String accountName)
-
-
- Returns a string representation of the hashed password, using the
- accountName as the salt.
login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Authenticates the user's credentials from the HttpServletRequest if
- necessary, creates a session if necessary, and sets the user as the
- current user.
Authenticates the user's credentials from the HttpServletRequest if
- necessary, creates a session if necessary, and sets the user as the
- current user.
-
Returns a string representation of the hashed password, using the
- accountName as the salt. The salt helps to prevent against "rainbow"
- table attacks where the attacker pre-calculates hashes for known strings.
-
-The IEncoder interface contains a number of methods related to encoding input
- so that it will be safe for a variety of interpreters. To prevent
- double-encoding, all encoding methods should first check to see that the
- input does not already contain encoded characters. There are a few methods
- related to decoding that are used for canonicalization purposes. See the
- Validator class for more information.
-
-
-
- All of the methods here must use a "whitelist" or "positive" security model,
- meaning that all characters should be encoded, except for a specific list of
- "immune" characters that are known to be safe.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
canonicalize(java.lang.String input)
-
-
- This method performs canonicalization on data received to ensure that it
- has been reduced to its most basic form before validation.
-
-
-
- byte[]
-
decodeFromBase64(java.lang.String input)
-
-
- Decode data encoded with BASE-64 encoding.
-
-
-
- java.lang.String
-
decodeFromURL(java.lang.String input)
-
-
- Decode from URL.
This method performs canonicalization on data received to ensure that it
- has been reduced to its most basic form before validation. For example,
- URL-encoded data received from ordinary "application/x-www-url-encoded"
- forms so that it may be validated properly.
-
- Canonicalization is simply the operation of reducing a possibly encoded
- string down to its simplest form. This is important, because attackers
- frequently use encoding to change their input in a way that will bypass
- validation filters, but still be interpreted properly by the target of
- the attack. Note that data encoded more than once is not something that a
- normal user would generate and should be regarded as an attack.
-
- For input that comes from an HTTP servlet request, there are generally
- two types of encoding to be concerned with. The first is
- "applicaton/x-www-url-encoded" which is what is typically used in most
- forms and URI's where characters are encoded in a %xy format. The other
- type of common character encoding is HTML entity encoding, which uses
- several formats:
-
-
<
,
-
u
, and
-
:
.
-
- Note that all of these formats may possibly render properly in a
- browser without the trailing semi-colon.
-
- Double-encoding is a particularly thorny problem, as applying ordinary decoders
- may introduce encoded characters, even characters encoded with a different
- encoding scheme. For example %26lt; is a < character which has been entity encoded
- and then the first character has been url-encoded. Implementations should
- throw an IntrusionException when double-encoded characters are detected.
-
- Note that there is also "multipart/form" encoding, which allows files and
- other binary data to be transmitted. Each part of a multipart form can
- itself be encoded according to a "Content-Transfer-Encoding" header. See
- the HTTPUtilties.getSafeFileUploads() method.
-
- For more information on form encoding, please refer to the W3C
- specifications.
-
Reduce all non-ascii characters to their ASCII form so that simpler
- validation rules can be applied. For example, an accented-e character
- will be changed into a regular ASCII e character.
-
Encode data for use in HTML content. This method first canonicalizes and
- detects any double-encoding. If this check passes, then the data is
- entity-encoded using a whitelist.
-
Encode data for use in HTML attributes. This method first canonicalizes
- and detects any double-encoding. If this check passes, then the data is
- entity-encoded using a whitelist.
-
Encode for javascript. This method first canonicalizes and detects any
- double-encoding. If this check passes, then the data is encoded using a
- whitelist.
-
Encode data for use in visual basic script. This method first
- canonicalizes and detects any double-encoding. If this check passes, then
- the data is encoded using a whitelist.
-
Encode for SQL. This method first canonicalizes and detects any
- double-encoding. If this check passes, then the data is encoded using a
- whitelist.
-
Encode data for use in LDAP queries. This method first canonicalizes and
- detects any double-encoding. If this check passes, then the data is
- encoded using a whitelist.
-
Encode data for use in an LDAP distinguished name. This method first
- canonicalizes and detects any double-encoding. If this check passes, then
- the data is encoded using a whitelist.
-
Encode data for use in an XPath query. This method first canonicalizes
- and detects any double-encoding. If this check passes, then the data is
- encoded using a whitelist.
-
Encode data for use in an XML element. This method first canonicalizes
- and detects any double-encoding. If this check passes, then the data is
- encoded using a whitelist. The implementation should follow the XML Encoding
- Standard from the W3C.
-
- The use of a real XML parser is strongly encouraged. However, in the
- hopefully rare case that you need to make sure that data is safe for
- inclusion in an XML document and cannot use a parse, this method provides
- a safe mechanism to do so.
-
Encode data for use in an XML attribute. The implementation should follow
- the XML Encoding
- Standard from the W3C. This method first canonicalizes and detects
- any double-encoding. If this check passes, then the data is encoded using
- a whitelist.
-
- The use of a real XML parser is highly encouraged. However, in the
- hopefully rare case that you need to make sure that data is safe for
- inclusion in an XML document and cannot use a parse, this method provides
- a safe mechanism to do so.
-
Encode for use in a URL. This method performs URL encoding"
- on the entire string. This method first canonicalizes and detects any
- double-encoding. If this check passes, then the data is encoded using a
- whitelist.
-
Decode from URL. This method first canonicalizes and detects any
- double-encoding. If this check passes, then the data is decoded using URL
- decoding.
-
-
-
Parameters:
input - the input
-
Returns:
the string
-
Throws:
-
java.io.IOException - Signals that an I/O exception has occurred.
-
-The IEncryptedProperties interface is a properties file where all the data is
- encrypted before it is added, and decrypted when it retrieved.
-
-
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
getProperty(java.lang.String key)
-
-
- Gets the property value from the encrypted store, decrypts it, and returns the plaintext value to the caller.
-
-
-
- java.lang.String
-
setProperty(java.lang.String key,
- java.lang.String value)
-
-
- Encrypts the plaintext property value and stores the ciphertext value in the encrypted store.
-The IEncryptor interface provides a set of methods for performing common
- encryption, random number, and hashing operations. Implementations should
- rely on a strong cryptographic implementation, such as JCE or BouncyCastle.
- Implementors should take care to ensure that they initialize their
- implementation with a strong "master key", and that they protect this secret
- as much as possible.
-
-
-
- Possible future enhancements (depending on feedback) might include:
-
-
encryptFile
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
decrypt(java.lang.String ciphertext)
-
-
- Decrypts the provided ciphertext string (encrypted with the encrypt
- method) and returns a plaintext string.
-
-
-
- java.lang.String
-
encrypt(java.lang.String plaintext)
-
-
- Encrypts the provided plaintext and returns a ciphertext string.
-
-
-
- long
-
getRelativeTimeStamp(long offset)
-
-
- Gets a timestamp representing an offset from the current time to be used by
- other functions in the library.
-
-
-
- long
-
getTimeStamp()
-
-
- Gets a timestamp representing the current date and time to be used by
- other functions in the library.
-
-
-
- java.lang.String
-
hash(java.lang.String plaintext,
- java.lang.String salt)
-
-
- Returns a string representation of the hash of the provided plaintext and
- salt.
-
-
-
- java.lang.String
-
seal(java.lang.String data,
- long timestamp)
-
-
- Creates a seal that binds a set of data and an expiration timestamp.
-
-
-
- java.lang.String
-
sign(java.lang.String data)
-
-
- Create a digital signature for the provided data and return it in a
- string.
-
-
-
- java.lang.String
-
unseal(java.lang.String seal)
-
-
- Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
-
-
-
- boolean
-
verifySeal(java.lang.String seal)
-
-
- Verifies a seal (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or data mismatch.
-
-
-
- boolean
-
verifySignature(java.lang.String signature,
- java.lang.String data)
-
-
- Verifies a digital signature (created with the sign method) and returns
- the boolean result.
Returns a string representation of the hash of the provided plaintext and
- salt. The salt helps to protect against a rainbow table attack by mixing
- in some extra data with the plaintext. Some good choices for a salt might
- be an account name or some other string that is known to the application
- but not to an attacker. See this article for
- more information about hashing as it pertains to password schemes.
-
Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
-
Verifies a seal (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or data mismatch.
-
-
-
Parameters:
seal - the seal
-
-
-
-
-
-getRelativeTimeStamp
-
-public long getRelativeTimeStamp(long offset)
-
-
Gets a timestamp representing an offset from the current time to be used by
- other functions in the library.
-
-
-
-
Returns:
the timestamp
-
-
-
-
-
-getTimeStamp
-
-public long getTimeStamp()
-
-
Gets a timestamp representing the current date and time to be used by
- other functions in the library.
-
-The Executor interface is used to run an OS command with less security risk.
- Implementations should do as much as possible to minimize the risk of
- injection into either the command or parameters. In addition, implementations
- should timeout after a specified time period in order to help prevent denial
- of service attacks. The class should perform logging and error handling as
- well. Finally, implementation should handle errors and generate an
- ExecutorException with all the necessary information.
-
-
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
executeSystemCommand(java.io.File executable,
- java.util.List params,
- java.io.File workdir,
- int timeoutSeconds)
-
-
- Executes a system command after checking that the executable exists and
- that the parameters have not been subject to injection with untrusted
- user data.
Executes a system command after checking that the executable exists and
- that the parameters have not been subject to injection with untrusted
- user data. Implementations shall change to the specified working
- directory before invoking the command. Also, processes should be
- interrupted after the specified timeout period has elapsed.
-
-The IHTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests,
- responses, sessions, cookies, headers, and logging.
-
-
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
addCSRFToken(java.lang.String href)
-
-
- Adds the current user's CSRF token (see User.getCSRFToken()) to the URL for purposes of preventing CSRF attacks.
-
-
-
- javax.servlet.http.HttpSession
-
changeSessionIdentifier()
-
-
- Invalidate the old session after copying all of its contents to a newly created session with a new session id.
-
-
-
- java.lang.String
-
decryptHiddenField(java.lang.String encrypted)
-
-
- Decrypts an encrypted hidden field value and returns the cleartest.
-
-
-
- java.util.Map
-
decryptQueryString(java.lang.String encrypted)
-
-
- Takes an encrypted querystring and returns a Map containing the original parameters.
enableRememberToken(int maxAge,
- java.lang.String domain,
- java.lang.String path)
-
-
- Set a cookie containing the current User's remember token for automatic authentication.
-
-
-
- java.lang.String
-
encryptHiddenField(java.lang.String value)
-
-
- Encrypts a hidden field value for use in HTML.
-
-
-
- java.lang.String
-
encryptQueryString(java.lang.String query)
-
-
- Takes a querystring (i.e.
-
-
-
- void
-
encryptStateInCookie(java.util.Map cleartext)
-
-
- Stores a Map of data in an encrypted cookie.
-
-
-
- java.lang.String
-
getCookie(java.lang.String name)
-
-
- Returns the first cookie matching the given name.
getSafeFileUploads(java.io.File tempDir,
- java.io.File finalDir)
-
-
- Extract uploaded files from a multipart HTTP requests.
-
-
-
- boolean
-
isSecureChannel()
-
-
- Returns true if the request and response are using an SSL-enabled connection.
-
-
-
- void
-
killAllCookies()
-
-
- Kill all cookies received in the last request from the browser.
-
-
-
- void
-
killCookie(java.lang.String name)
-
-
- Kills the specified cookie by setting a new cookie that expires immediately.
-
-
-
- void
-
logHTTPRequest(ILogger logger)
-
-
- Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file.
-
-
-
- void
-
logHTTPRequest(ILogger logger,
- java.util.List parameterNamesToObfuscate)
-
-
- Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file.
-
-
-
- void
-
safeAddCookie(java.lang.String name,
- java.lang.String value,
- int maxAge,
- java.lang.String domain,
- java.lang.String path)
-
-
- Adds a cookie to the specified HttpServletResponse and adds the Http-Only flag.
-
-
-
- void
-
safeAddHeader(java.lang.String name,
- java.lang.String value)
-
-
- Adds a header to an HttpServletResponse after checking for special characters (such as CRLF injection) that could enable
- attacks like response splitting and other header-based attacks that nobody has thought of yet.
-
-
-
- void
-
safeSendForward(java.lang.String context,
- java.lang.String location)
-
-
- This method perform a forward to any resource located inside the WEB-INF directory.
-
-
-
- void
-
safeSendRedirect(java.lang.String context,
- java.lang.String location)
-
-
- This method generates a redirect response that can only be used to redirect the browser to safe locations.
-
-
-
- void
-
safeSetContentType()
-
-
- Sets the content type on each HTTP response, to help protect against cross-site scripting attacks and other types
- of injection into HTML documents.
-
-
-
- void
-
safeSetHeader(java.lang.String name,
- java.lang.String value)
-
-
- Sets a header in an HttpServletResponse after checking for special characters (such as CRLF injection) that could enable
- attacks like response splitting and other header-based attacks that nobody has thought of yet.
-
-
-
- void
-
setCurrentHTTP(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Stores the current HttpRequest and HttpResponse so that they may be readily accessed throughout
- ESAPI (and elsewhere)
-
-
-
- void
-
setNoCacheHeaders()
-
-
- Set headers to protect sensitive information against being cached in the browser.
-
-
-
- void
-
verifyCSRFToken()
-
-
- Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and
- throws an IntrusionException if it is missing.
Adds the current user's CSRF token (see User.getCSRFToken()) to the URL for purposes of preventing CSRF attacks.
- This method should be used on all URLs to be put into all links and forms the application generates.
-
Adds a header to an HttpServletResponse after checking for special characters (such as CRLF injection) that could enable
- attacks like response splitting and other header-based attacks that nobody has thought of yet.
-
Sets a header in an HttpServletResponse after checking for special characters (such as CRLF injection) that could enable
- attacks like response splitting and other header-based attacks that nobody has thought of yet.
-
Invalidate the old session after copying all of its contents to a newly created session with a new session id.
- Note that this is different from logging out and creating a new session identifier that does not contain the
- existing session contents. Care should be taken to use this only when the existing session does not contain
- hazardous contents.
-
Decrypts an encrypted hidden field value and returns the cleartest. If the field does not decrypt properly,
- an IntrusionException is thrown to indicate tampering.
-
Set a cookie containing the current User's remember token for automatic authentication. The use of remember tokens
- is not recommended, but this method will help do it as safely as possible. The user interface should strongly warn
- the user that this should only be enabled on computers where no other users will have access.
-
Extract uploaded files from a multipart HTTP requests. Implementations must check the content to ensure that it
- is safe before making a permanent copy on the local filesystem. Checks should include length and content checks,
- possibly virus checking, and path and name checks. Refer to the file checking methods in IValidator for more
- information.
-
Returns true if the request and response are using an SSL-enabled connection. This check should be made on
- every request from the login page through the logout confirmation page. Essentially, any page that uses the
- Authenticator.login() call should call this. Implementers should consider calling this method directly in
- their Authenticator.login() method. If this method returns true for a page that requires SSL, there must be a
- misconfiguration, an AuthenticationException is warranted.
-
-
-
-
Returns:
-
-
-
-
-
-killAllCookies
-
-public void killAllCookies()
-
-
Kill all cookies received in the last request from the browser. Note that new cookies set by the application in
- this response may not be killed by this method.
-
-
-
-
-
-
-
-
-killCookie
-
-public void killCookie(java.lang.String name)
-
-
Kills the specified cookie by setting a new cookie that expires immediately.
-
This method generates a redirect response that can only be used to redirect the browser to safe locations.
- Importantly, redirect requests can be modified by attackers, so do not rely information contained within redirect
- requests, and do not include sensitive information in a redirect.
-
-
-
Parameters:
location - the URL to redirect to
-
Throws:
-
java.io.IOException - Signals that an I/O exception has occurred.
This method perform a forward to any resource located inside the WEB-INF directory. Forwarding to
- publically accessible resources can be dangerous, as the request will have already passed the URL
- based access control check. This method ensures that you can only forward to non-publically
- accessible resources.
-
Sets the content type on each HTTP response, to help protect against cross-site scripting attacks and other types
- of injection into HTML documents.
-
-
-
-
-
-
-
-
-setNoCacheHeaders
-
-public void setNoCacheHeaders()
-
-
Set headers to protect sensitive information against being cached in the browser. Developers should make this
- call for any HTTP responses that contain any sensitive data that should not be cached within the browser or any
- intermediate proxies or caches. Implementations should set headers for the expected browsers. The safest approach
- is to set all relevant headers to their most restrictive setting. These include:
-
-
-
- Note that the header "pragma: no-cache" is only useful in HTTP requests, not HTTP responses. So even though there
- are many articles recommending the use of this header, it is not helpful for preventing browser caching. For more
- information, please refer to the relevant standards:
-
Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file. Be careful not
- to log sensitive information, and consider masking with the
- logHTTPRequest( List parameterNamesToObfuscate ) method.
-
Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file. The list of parameters to
- obfuscate should be specified in order to prevent sensitive information
- from being logged. If a null list is provided, then all parameters will
- be logged.
-
-The IIntrusionDetector interface is intended to track security relevant events and identify attack behavior. The
- implementation can use as much state as necessary to detect attacks, but note that storing too much state will burden
- your system.
-
-
-
-
- The interface is currently designed to accept exceptions as well as custom events. Implementations can use this
- stream of information to detect both normal and abnormal behavior.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- void
-
addEvent(java.lang.String eventName)
-
-
- Adds the event to the IntrusionDetector.
-
-
-
- void
-
addException(java.lang.Exception exception)
-
-
- Adds the exception to the IntrusionDetector.
-The ILogger interface defines a set of methods that can be used to log
- security events. Implementors should use a well established logging library
- as it is quite difficult to create a high-performance logger.
-
-
-
-
- The order of logging levels is:
-
-
trace
-
debug
-
info
-
warn
-
error
-
fatal (the most serious)
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-The IRandomizer interface defines a set of methods for creating
- cryptographically random numbers and strings. Implementers should be sure to
- use a strong cryptographic implementation, such as the JCE or BouncyCastle.
- Weak sources of randomness can undermine a wide variety of security
- mechanisms.
-
-
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-The ISecurityConfiguration interface stores all configuration information
- that directs the behavior of the ESAPI implementation.
-
-
-
- Protection of this configuration information is critical to the secure
- operation of the application using the ESAPI. You should use operating system
- access controls to limit access to wherever the configuration information is
- stored. Please note that adding another layer of encryption does not make the
- attackers job much more difficult. Somewhere there must be a master "secret"
- that is stored unencrypted on the application platform. Creating another
- layer of indirection doesn't provide any real additional security.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-The IUser interface represents an application user or user account. There is quite a lot of information that an
- application must store for each user in order to enforce security properly. There are also many rules that govern
- authentication and identity management.
-
-
-
- A user account can be in one of several states. When first created, a User should be disabled, not expired, and
- unlocked. To start using the account, an administrator should enable the account. The account can be locked for a
- number of reasons, most commonly because they have failed login for too many times. Finally, the account can expire
- after the expiration date has been reached. The User must be enabled, not expired, and unlocked in order to pass
- authentication.
-
addRole(java.lang.String role)
-
-
- Adds a role to an account.
-
-
-
- void
-
addRoles(java.util.Set newRoles)
-
-
- Adds the roles.
-
-
-
- void
-
changePassword(java.lang.String oldPassword,
- java.lang.String newPassword1,
- java.lang.String newPassword2)
-
-
- Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
-
Returns the number of failed login attempts since the last successful login for an account. This method is
- intended to be used as a part of the account lockout feature, to help protect against brute force attacks.
- However, the implementor should be aware that lockouts can be used to prevent access to an application by a
- legitimate user, and should consider the risk of denial of service.
-
-
-
-
Returns:
the number of failed login attempts since the last successful login
-
-
-
-
-
-getLastHostAddress
-
-public java.lang.String getLastHostAddress()
-
-
Returns the last host address used by the user. This will be used in any log messages generated by the processing
- of this request.
-
Returns the date of the last failed login time for a user. This date should be used in a message to users after a
- successful login, to notify them of potential attack activity on their account.
-
Returns the date of the last successful login time for a user. This date should be used in a message to users
- after a successful login, to notify them of potential attack activity on their account.
-
Returns a token to be used as a prevention against CSRF attacks. This token should be added to all links and
- forms. The application should verify that all requests contain the token, or they may have been generated by a
- CSRF attack. It is generally best to perform the check in a centralized location, either a filter or controller.
- See the verifyCSRFToken method.
-
Returns a token to be used as a "remember me" cookie. The cookie is not seen by the user and can be fairly long,
- at least 20 digits is suggested to prevent brute force attacks. See loginWithRememberToken.
-
Verify that the supplied password matches the password for this user. This method
- is typically used for "reauthentication" for the most sensitive functions, such
- as transactions, changing email address, and changing other account information.
-
-The IValidator interface defines a set of methods for canonicalizing and
- validating untrusted input. Implementors should feel free to extend this
- interface to accomodate their own data formats. Rather than throw exceptions,
- this interface returns boolean results because not all validation problems
- are security issues. Boolean returns allow developers to handle both valid
- and invalid results more cleanly than exceptions.
-
-
-
- Implementations must adopt a "whitelist" approach to validation where a
- specific pattern or character set is matched. "Blacklist" approaches that
- attempt to identify the invalid or disallowed characters are much more likely
- to allow a bypass with encoding or other tricks.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- void
-
assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- void
-
assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
-
-
-
- void
-
assertValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Validates the filepath, filename, and content of a file.
-
-
-
- java.lang.String
-
getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
-
-
-
- java.util.Date
-
getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns a valid date as a Date.
-
-
-
- java.lang.String
-
getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
-
-
-
- java.lang.Double
-
getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns a validated real number as a double.
-
-
-
- byte[]
-
getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
-
-
-
- java.lang.String
-
getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.String
-
getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated input as a String.
-
-
-
- java.lang.Integer
-
getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated integer as an int.
-
-
-
- java.lang.String
-
getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
-
-
-
- java.lang.Double
-
getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- byte[]
-
getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a byte array.
-
-
-
- java.lang.String
-
getValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a String.
-
-
-
- java.lang.String
-
getValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated redirect location as a String.
-
-
-
- java.lang.String
-
getValidSafeHTML(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated "safe" HTML.
-
-
-
- boolean
-
isValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid credit card.
-
-
-
- boolean
-
isValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns true if input is a valid date according to the specified date format.
-
-
-
- boolean
-
isValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid directory path.
-
-
-
- boolean
-
isValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid double.
-
-
-
- boolean
-
isValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if input is valid file content.
-
-
-
- boolean
-
isValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid file name.
-
-
-
- boolean
-
isValidFileUpload(java.lang.String context,
- java.lang.String filepath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if a file upload has a valid name, path, and content.
-
-
-
- boolean
-
isValidHTTPRequest()
-
-
- Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- boolean
-
isValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Returns true if the parameters in the current request contain all required parameters and only optional ones in addition.
-
-
-
- boolean
-
isValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is valid according to the specified type.
-
-
-
- boolean
-
isValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid integer.
-
-
-
- boolean
-
isValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns true if input is a valid list item.
-
-
-
- boolean
-
isValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid number.
-
-
-
- boolean
-
isValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is valid printable ASCII characters.
-
-
-
- boolean
-
isValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is valid printable ASCII characters (32-126).
-
-
-
- boolean
-
isValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid redirect location.
-
-
-
- boolean
-
isValidSafeHTML(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is "safe" HTML.
-
-
-
- java.lang.String
-
safeReadLine(java.io.InputStream inputStream,
- int maxLength)
-
-
- Reads from an input stream until end-of-line or a maximum number of
- characters.
Returns true if input is valid according to the specified type. The type parameter must be the name
- of a defined type in the ESAPI configuration or a valid regular expression. Implementers should take
- care to make the type storage simple to understand and configure.
-
-
-
Parameters:
context - A descriptive name for the field to validate. This is used for error facing validation messages and element identification.
input - The actual user input data to validate.
type - The regular expression name while maps to the actual regular expression from "ESAPI.properties".
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then a input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns canonicalized and validated input as a String. Invalid input will generate a descriptive ValidationException,
- and input that is clearly an attack will generate a descriptive IntrusionException.
-
-
-
Parameters:
context - A descriptive name for the field to validate. This is used for error facing validation messages and element identification.
input - The actual user input data to validate.
type - The regular expression name while maps to the actual regular expression from "ESAPI.properties".
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then a input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a valid date as a Date. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns true if input is "safe" HTML. Implementors should reference the OWASP AntiSamy project for ideas
- on how to do HTML validation in a whitelist way, as this is an extremely difficult problem.
-
Returns canonicalized and validated "safe" HTML. Implementors should reference the OWASP AntiSamy project for ideas
- on how to do HTML validation in a whitelist way, as this is an extremely difficult problem.
-
Returns a canonicalized and validated credit card number as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns a canonicalized and validated directory path as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns a canonicalized and validated file name as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns a validated number as a double. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns a validated integer as an int. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns a validated real number as a double. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns validated file content as a byte array. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Validates the filepath, filename, and content of a file. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Validate the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters. See the SecurityConfiguration class for the methods to retrieve the whitelists.
-
Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns the list item that exactly matches the canonicalized input. Invalid or non-matching input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns canonicalized and validated printable characters as a byte array. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns canonicalized and validated printable characters as a String. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Returns a canonicalized and validated redirect location as a String. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
-public java.lang.String safeReadLine(java.io.InputStream inputStream,
- int maxLength)
- throws ValidationException
-
-
Reads from an input stream until end-of-line or a maximum number of
- characters. This method protects against the inherent denial of service
- attack in reading until the end of a line. If an attacker doesn't ever
- send a newline character, then a normal input stream reader will read
- until all memory is exhausted and the platform throws an OutOfMemoryError
- and probably terminates.
-
IHTTPUtilities.logHTTPRequest(ILogger logger)
-
-
- Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file.
-
-
-
- void
-
IHTTPUtilities.logHTTPRequest(ILogger logger,
- java.util.List parameterNamesToObfuscate)
-
-
- Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file.
Authenticator.login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- This method should be called for every HTTP request, to login the current user either from the session of HTTP
- request.
IAuthenticator.login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Authenticates the user's credentials from the HttpServletRequest if
- necessary, creates a session if necessary, and sets the user as the
- current user.
IAuthenticator.generateStrongPassword(java.lang.String oldPassword,
- IUser user)
-
-
- Generate strong password that takes into account the user's information and old password.
-
-
-
- void
-
IAuthenticator.setCurrentUser(IUser user)
-
-
- Sets the currently logged in User.
The IAccessReferenceMap interface is used to map from a set of internal
- direct object references to a set of indirect references that are safe to
- disclose publically.
The IHTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests,
- responses, sessions, cookies, headers, and logging.
The IValidator interface defines a set of methods for canonicalizing and
- validating untrusted input.
-
-
-
-
-
-
-Package org.owasp.esapi.interfaces Description
-
-
-
-A set of interfaces modeling the most important security functions to
-enterprise web applications. The interfaces in this package are intended
-to be extended and customized within an enterprise to match their custom
-data, security services, and application environment. A reference
-implementation of this interface is provided as an example of how this
-library can be implemented successfully.
-
IAccessController
-
-
- The IAccessController interface defines a set of methods that can be used in a wide variety of applications to
- enforce access control.
-
-
-
IAccessReferenceMap
-
-
- The IAccessReferenceMap interface is used to map from a set of internal
- direct object references to a set of indirect references that are safe to
- disclose publically.
-
-
-
IAuthenticator
-
-
- The IAuthenticator interface defines a set of methods for generating and
- handling account credentials and session identifiers.
-
-
-
IEncoder
-
-
- The IEncoder interface contains a number of methods related to encoding input
- so that it will be safe for a variety of interpreters.
-
-
-
IEncryptedProperties
-
-
- The IEncryptedProperties interface is a properties file where all the data is
- encrypted before it is added, and decrypted when it retrieved.
-
-
-
IEncryptor
-
-
- The IEncryptor interface provides a set of methods for performing common
- encryption, random number, and hashing operations.
-
-
-
IExecutor
-
-
- The Executor interface is used to run an OS command with less security risk.
-
-
-
IHTTPUtilities
-
-
- The IHTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests,
- responses, sessions, cookies, headers, and logging.
-
-
-
IIntrusionDetector
-
-
- The IIntrusionDetector interface is intended to track security relevant events and identify attack behavior.
ILogger
-
-
- The ILogger interface defines a set of methods that can be used to log
- security events.
-
-
-
IRandomizer
-
-
- The IRandomizer interface defines a set of methods for creating
- cryptographically random numbers and strings.
-
-
-
ISecurityConfiguration
-
-
- The ISecurityConfiguration interface stores all configuration information
- that directs the behavior of the ESAPI implementation.
-
-
-
IUser
-
-
- The IUser interface represents an application user or user account.
-
-
-
IValidator
-
-
- The IValidator interface defines a set of methods for canonicalizing and
- validating untrusted input.
The AccessReferenceMap interface is used to map from a set of internal
- direct object references to a set of indirect references that are safe to
- disclose publicly.
The HTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests,
- responses, sessions, cookies, headers, and logging.
Extension to java.io.File to prevent against null byte injections and
- other unforeseen problems resulting from unprintable characters
- causing problems in path lookups.
The ValidationErrorList class defines a well-formed collection of
- ValidationExceptions so that groups of validation functions can be
- called in a non-blocking fashion.
-
-
-
-
-
-
-Package org.owasp.esapi Description
-
-
-
-The ESAPI interfaces and Exception classes model the most important security
-functions to enterprise web applications. The interfaces in this package are
-intended to be extended and customized within an enterprise to match their
-custom data, security services, and application environment. A reference
-implementation of this interface is provided as an example of how this
-library can be implemented successfully.
-
-
References
-
-This library builds on some of the ideas found in:
-
AccessController
-
-
- The IAccessController interface defines a set of methods that can be used in a wide variety of applications to
- enforce access control.
-
-
-
Authenticator
-
-
- The Authenticator interface defines a set of methods for generating and
- handling account credentials and session identifiers.
-
-
-
Encoder
-
-
- The Encoder interface contains a number of methods related to encoding input
- so that it will be safe for a variety of interpreters.
-
-
-
Encryptor
-
-
- The Encryptor interface provides a set of methods for performing common
- encryption, random number, and hashing operations.
-
-
-
Executor
-
-
- The Executor interface is used to run an OS command with reduced security risk.
-
-
-
HTTPUtilities
-
-
- The HTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests,
- responses, sessions, cookies, headers, and logging.
-
-
-
IntrusionDetector
-
-
- The IntrusionDetector interface is intended to track security relevant events and identify attack behavior.
-
-
-
LogFactory
-
-
- The LogFactory interface is intended to allow substitution of various logging packages, while providing
- a common interface to access them.
-
-
-
Logger
-
-
- The Logger interface defines a set of methods that can be used to log
- security events.
-
-
-
Randomizer
-
-
- The IRandomizer interface defines a set of methods for creating
- cryptographically random numbers and strings.
-
-
-
SecurityConfiguration
-
-
- The ISecurityConfiguration interface stores all configuration information
- that directs the behavior of the ESAPI implementation.
-
-
-
SecurityConfiguration.Threshold
-
-
- Models a simple threshold as a count and an interval, along with a set of actions to take if the threshold is exceeded.
-
-
-
User
-
-
- The User interface represents an application user or user account.
-
-
-
ValidationErrorList
-
-
- The ValidationErrorList class defines a well-formed collection of
- ValidationExceptions so that groups of validation functions can be
- called in a non-blocking fashion.
-
-
-
Validator
-
-
- The Validator interface defines a set of methods for canonicalizing and
- validating untrusted input.
AccessController
-
-
- The IAccessController interface defines a set of methods that can be used in a wide variety of applications to
- enforce access control.
-
-
-
AccessReferenceMap
-
-
- The AccessReferenceMap interface is used to map from a set of internal
- direct object references to a set of indirect references that are safe to
- disclose publicly.
-
-
-
Authenticator
-
-
- The Authenticator interface defines a set of methods for generating and
- handling account credentials and session identifiers.
-
-
-
Encoder
-
-
- The Encoder interface contains a number of methods related to encoding input
- so that it will be safe for a variety of interpreters.
-
-
-
EncryptedProperties
-
-
- The EncryptedProperties interface represents a properties file where all the data is
- encrypted before it is added, and decrypted when it retrieved.
-
-
-
Encryptor
-
-
- The Encryptor interface provides a set of methods for performing common
- encryption, random number, and hashing operations.
-
-
-
Executor
-
-
- The Executor interface is used to run an OS command with reduced security risk.
-
-
-
HTTPUtilities
-
-
- The HTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests,
- responses, sessions, cookies, headers, and logging.
-
-
-
IntrusionDetector
-
-
- The IntrusionDetector interface is intended to track security relevant events and identify attack behavior.
-
-
-
LogFactory
-
-
- The LogFactory interface is intended to allow substitution of various logging packages, while providing
- a common interface to access them.
-
-
-
Logger
-
-
- The Logger interface defines a set of methods that can be used to log
- security events.
-
-
-
Randomizer
-
-
- The IRandomizer interface defines a set of methods for creating
- cryptographically random numbers and strings.
-
-
-
SecurityConfiguration
-
-
- The ISecurityConfiguration interface stores all configuration information
- that directs the behavior of the ESAPI implementation.
-
-
-
SecurityConfiguration.Threshold
-
-
- Models a simple threshold as a count and an interval, along with a set of actions to take if the threshold is exceeded.
-
-
-
User
-
-
- The User interface represents an application user or user account.
-
-
-
ValidationErrorList
-
-
- The ValidationErrorList class defines a well-formed collection of
- ValidationExceptions so that groups of validation functions can be
- called in a non-blocking fashion.
-
-
-
Validator
-
-
- The Validator interface defines a set of methods for canonicalizing and
- validating untrusted input.
-Reference implementation of the Encoder interface. This implementation takes
- a whitelist approach to encoding, meaning that everything not specifically identified in a
- list of "immune" characters is encoded. Several methods follow the approach in the Microsoft
- AntiXSS Library.
-
- The Encoder performs two key functions
- The canonicalization algorithm is complex, as it has to be able to recognize
- encoded characters that might affect downstream interpreters without being
- told what encodings are possible. The stream is read one character at a time.
- If an encoded character is encountered, it is canonicalized and pushed back
- onto the stream. If the next character is encoded, then a intrusion exception
- is thrown for the double-encoding which is assumed to be an attack.
-
- The encoding methods also attempt to prevent double encoding, by canonicalizing strings
- that are passed to them for encoding.
-
- Currently the implementation supports:
-
-
HTML Entity Encoding (including non-terminated)
-
Percent Encoding
-
Backslash Encoding
-
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
Simplifies encoded characters to their
- simplest form so that they can be properly validated. Attackers
- frequently use encoding schemes to disguise their attacks and bypass
- validation routines.
-
- Handling multiple encoding schemes simultaneously is difficult, and
- requires some special consideration. In particular, the problem of
- double-encoding is difficult for parsers, and combining several encoding
- schemes in double-encoding makes it even harder. Consider decoding
-
-
- <
-
-
- or
-
-
- %26lt;
-
-
- or
-
-
- <
-
.
-
- This implementation disallows ALL double-encoded characters and throws an
- IntrusionException when they are detected. Also, named entities that are
- not known are simply removed.
-
- Note that most data from the browser is likely to be encoded with URL
- encoding (RFC 3986). The web server will decode the URL and form data
- once, so most encoded data received in the application must have been
- double-encoded by the attacker. However, some HTTP inputs are not decoded
- by the browser, so this routine allows a single level of decoding.
-
Normalizes special characters down to ASCII using the Normalizer built
- into Java. Note that this method may introduce security issues if
- characters are normalized into special characters that have meaning
- to the destination of the data.
-
Encode the input string using HTML entity encoding. Note that the following characters:
- 00–08, 0B–0C, 0E–1F, and 7F–9F Cannot be used in HTML. See http://en.wikipedia.org/wiki/Character_encodings_in_HTML
- for more information.
- See the SGML declaration - http://www.w3.org/TR/html4/sgml/sgmldecl.html
- See the XML specification - see http://www.w3.org/TR/REC-xml/#charsets
-
Encode data for insertion inside a data value in JavaScript. Putting user data directly
- inside a script is quite dangerous. Great care must be taken to prevent putting user data
- directly into script code itself, as no amount of encoding will prevent attacks there.
-
Encode data for insertion inside a data value in a visual basic script. Putting user data directly
- inside a script is quite dangerous. Great care must be taken to prevent putting user data
- directly into script code itself, as no amount of encoding will prevent attacks there.
-
This method is not recommended. The use PreparedStatement is the normal
- and preferred approach. However, if for some reason this is impossible,
- then this method is provided as a weaker alternative. The best approach
- is to make sure any single-quotes are double-quoted. Another possible
- approach is to use the {escape} syntax described in the JDBC
- specification in section 1.5.6 (see
- http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/statement.html).
- However, this syntax does not work with all drivers, and requires
- modification of all queries.
-
This implementation encodes almost everything and may overencode. The
- difficulty is that XPath has no built in mechanism for escaping
- characters. It is possible to use XQuery in a parameterized way to
- prevent injection. For more information, refer to this
- article which specifies the following list of characters as the most
- dangerous: ^&"*';<>(). This
- paper suggests disallowing ' and " in queries.
-
Encode data for use in an XML element. The implementation should follow the XML Encoding
- Standard from the W3C.
-
- The use of a real XML parser is strongly encouraged. However, in the
- hopefully rare case that you need to make sure that data is safe for
- inclusion in an XML document and cannot use a parse, this method provides
- a safe mechanism to do so.
-
Encode data for use in an XML attribute. The implementation should follow
- the XML Encoding
- Standard from the W3C.
-
- The use of a real XML parser is highly encouraged. However, in the
- hopefully rare case that you need to make sure that data is safe for
- inclusion in an XML document and cannot use a parse, this method provides
- a safe mechanism to do so.
-
Decode from URL. Implementations should first canonicalize and
- detect any double-encoding. If this check passes, then the data is decoded using URL
- decoding.
-
-Reference implementation of the EncryptedProperties interface. This
- implementation wraps a normal properties file, and creates surrogates for the
- getProperty and setProperty methods that perform encryption and decryption based on the Encryptor.
- A very simple main program is provided that can be used to create an
- encrypted properties file. A better approach would be to allow unencrypted
- properties in the file and to encrypt them the first time the file is
- accessed.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
main(java.lang.String[] args)
-
-
- The main method.
-
-
-
- java.lang.String
-
setProperty(java.lang.String key,
- java.lang.String value)
-
-
- Encrypts the plaintext property value and stores the ciphertext value in the encrypted store.
-Reference implementation of the Executor interface. This implementation is very restrictive. Commands must exactly
- equal the canonical path to an executable on the system. Valid characters for parameters are alphanumeric,
- forward-slash, and dash.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
executeSystemCommand(java.io.File executable,
- java.util.List params,
- java.io.File workdir,
- int timeoutSeconds)
-
-
- Executes a system command after checking that the executable exists and
- that the parameters have not been subject to injection with untrusted
- user data.
Executes a system command after checking that the executable exists and
- that the parameters have not been subject to injection with untrusted
- user data. Implementations shall change to the specified working
- directory before invoking the command. Also, processes should be
- interrupted after the specified timeout period has elapsed.
-
-Reference implementation of the HTTPUtilities interface. This implementation
- uses the Apache Commons FileUploader library, which in turn uses the Apache
- Commons IO library.
-
- To simplify the interface, this class uses the current request and response that
- are tracked by ThreadLocal variables in the Authenticator. This means that you
- must have called ESAPI.authenticator().setCurrentHTTP(request, response) before
- calling these methods.
-
- Typically, this is done by calling the Authenticator.login() method, which
- calls setCurrentHTTP() automatically. However if you want to use these methods
- in another application, you should explicitly call setCurrentHTTP() in your
- own code.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
addCSRFToken(java.lang.String href)
-
-
- Adds the current user's CSRF token (see User.getCSRFToken()) to the URL for purposes of preventing CSRF attacks.
-
-
-
- void
-
assertSecureRequest(javax.servlet.http.HttpServletRequest request)
-
-
- Verifies that the request is "secure" by checking that the method is a POST and
- that SSL has been used.
-
-
-
- javax.servlet.http.HttpSession
-
changeSessionIdentifier(javax.servlet.http.HttpServletRequest request)
-
-
- Invalidate the old session after copying all of its contents to a newly created session with a new session id.
-
-
-
- java.lang.String
-
decryptHiddenField(java.lang.String encrypted)
-
-
- Decrypts an encrypted hidden field value and returns the cleartext.
-
-
-
- java.util.Map
-
decryptQueryString(java.lang.String encrypted)
-
-
- Takes an encrypted querystring and returns a Map containing the original parameters.
-
-
-
- java.util.Map
-
decryptStateFromCookie(javax.servlet.http.HttpServletRequest request)
-
-
- Retrieves a map of data from a cookie encrypted with encryptStateInCookie().
-
-
-
- java.lang.String
-
encryptHiddenField(java.lang.String value)
-
-
- Encrypts a hidden field value for use in HTML.
-
-
-
- java.lang.String
-
encryptQueryString(java.lang.String query)
-
-
- Takes a querystring (i.e.
-
-
-
- void
-
encryptStateInCookie(javax.servlet.http.HttpServletResponse response,
- java.util.Map cleartext)
-
-
- Stores a Map of data in an encrypted cookie.
-
-
-
- javax.servlet.http.Cookie
-
getCookie(javax.servlet.http.HttpServletRequest request,
- java.lang.String name)
-
-
- Returns the first cookie matching the provided name.
-
-
-
- java.lang.String
-
getCSRFToken()
-
-
- Returns the current user's CSRF token.
getSafeFileUploads(javax.servlet.http.HttpServletRequest request,
- java.io.File tempDir,
- java.io.File finalDir)
-
-
- Uses the Apache Commons FileUploader to parse the multipart HTTP request
- and extract any files therein.
-
-
-
- boolean
-
isSecureChannel(javax.servlet.http.HttpServletRequest request)
-
-
- Returns true if the request was transmitted over an SSL enabled
- connection.
-
-
-
- void
-
killAllCookies(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Kill all cookies received in the last request from the browser.
-
-
-
- void
-
killCookie(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response,
- java.lang.String name)
-
-
- Kills the specified cookie by setting a new cookie that expires immediately.
-
-
-
- void
-
logHTTPRequest(javax.servlet.http.HttpServletRequest request,
- Logger logger)
-
-
- Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file.
-
-
-
- void
-
logHTTPRequest(javax.servlet.http.HttpServletRequest request,
- Logger logger,
- java.util.List parameterNamesToObfuscate)
-
-
- Formats an HTTP request into a log suitable string.
-
-
-
- void
-
safeSendForward(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response,
- java.lang.String context,
- java.lang.String location)
-
-
- This method perform a forward to any resource located inside the WEB-INF directory.
-
-
-
- void
-
safeSetContentType(javax.servlet.http.HttpServletResponse response)
-
-
- Set the character encoding on every HttpServletResponse in order to limit
- the ways in which the input data can be represented.
-
-
-
- void
-
setCurrentHTTP(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- Stores the current HttpRequest and HttpResponse so that they may be readily accessed throughout
- ESAPI (and elsewhere)
-
-
-
- void
-
setNoCacheHeaders(javax.servlet.http.HttpServletResponse response)
-
-
- Set headers to protect sensitive information against being cached in the
- browser.
-
-
-
- java.lang.String
-
setRememberToken(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response,
- java.lang.String password,
- int maxAge,
- java.lang.String domain,
- java.lang.String path)
-
-
- Save the user's remember me token in a cookie.
-
-
-
- void
-
verifyCSRFToken(javax.servlet.http.HttpServletRequest request)
-
-
- Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and
- throws an IntrusionException if it is missing.
Adds the current user's CSRF token (see User.getCSRFToken()) to the URL for purposes of preventing CSRF attacks.
- This method should be used on all URLs to be put into all links and forms the application generates.
-
Save the user's remember me token in a cookie. Old remember me cookies should be
- destroyed first. Setting this cookie will keep the user logged in until the
- maxAge passes, the password is changed, or the cookie is deleted.
-
Verifies that the request is "secure" by checking that the method is a POST and
- that SSL has been used. The POST ensures that the data does not end up in bookmarks,
- web logs, referer headers, and other exposed sources. The SSL ensures that data
- has not been exposed in transit.
-
Invalidate the old session after copying all of its contents to a newly created session with a new session id.
- Note that this is different from logging out and creating a new session identifier that does not contain the
- existing session contents. Care should be taken to use this only when the existing session does not contain
- hazardous contents.
-
- This method uses HTTPUtilities.getCurrentRequest() to obtain the current HttpSession object
-
Decrypts an encrypted hidden field value and returns the cleartext. If the field does not decrypt properly,
- an IntrusionException is thrown to indicate tampering.
-
Stores a Map of data in an encrypted cookie. Generally the session is a better
- place to store state information, as it does not expose it to the user at all.
- If there is a requirement not to use sessions, or the data should be stored
- across sessions (for a long time), the use of encrypted cookies is an effective
- way to prevent the exposure.
-
Uses the Apache Commons FileUploader to parse the multipart HTTP request
- and extract any files therein. Note that the progress of any uploads is
- put into a session attribute, where it can be retrieved with a simple
- JSP.
-
Returns true if the request was transmitted over an SSL enabled
- connection. This implementation ignores the built-in isSecure() method
- and uses the URL to determine if the request was transmitted over SSL.
-
Kill all cookies received in the last request from the browser. Note that new cookies set by the application in
- this response may not be killed by this method.
-
Kills the specified cookie by setting a new cookie that expires immediately. Note that this
- method does not delete new cookies that are being set by the application for this response.
-
This method perform a forward to any resource located inside the WEB-INF directory. Forwarding to
- publicly accessible resources can be dangerous, as the request will have already passed the URL
- based access control check. This method ensures that you can only forward to non-publicly
- accessible resources.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
Set the character encoding on every HttpServletResponse in order to limit
- the ways in which the input data can be represented. This prevents
- malicious users from using encoding and multi-byte escape sequences to
- bypass input validation routines. The default is text/html; charset=UTF-8
- character encoding, which is the default in early versions of HTML and
- HTTP. See RFC 2047 (http://ds.internic.net/rfc/rfc2045.txt) for more
- information about character encoding and MIME.
-
Format the Source IP address, URL, URL parameters, and all form
- parameters into a string suitable for the log file. Be careful not
- to log sensitive information, and consider masking with the
- logHTTPRequest( List parameterNamesToObfuscate ) method.
-
Formats an HTTP request into a log suitable string. This implementation logs the remote host IP address (or
- hostname if available), the request method (GET/POST), the URL, and all the querystring and form parameters. All
- the parameters are presented as though they were in the URL even if they were in a form. Any parameters that
- match items in the parameterNamesToObfuscate are shown as eight asterisks.
-
-Reference implementation of the IntrusionDetector interface. This
- implementation monitors EnterpriseSecurityExceptions to see if any user
- exceeds a configurable threshold in a configurable time period. For example,
- it can monitor to see if a user exceeds 10 input validation issues in a 1
- minute period. Or if there are more than 3 authentication problems in a 10
- second period. More complex implementations are certainly possible, such as
- one that establishes a baseline of expected behavior, and then detects
- deviations from that baseline.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-Reference implementation of the Randomizer interface. This implementation builds on the JCE provider to provide a
- cryptographically strong source of entropy. The specific algorithm used is configurable in ESAPI.properties.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams, Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-Extension to java.io.File to prevent against null byte injections and
- other unforeseen problems resulting from unprintable characters
- causing problems in path lookups. This does _not_ prevent against
- directory traversal attacks.
-
-The SecurityConfiguration manages all the settings used by the ESAPI in a single place. Initializing the
- Configuration is critically important to getting the ESAPI working properly. You must set a system property before
- invoking any part of the ESAPI. Here is how to do it:
-
-
-
- You may have to add this to the batch script that starts your web server. For example, in the "catalina" script that
- starts Tomcat, you can set the JAVA_OPTS variable to the -D string above. Once the Configuration is initialized with
- a resource directory, you can edit it to set things like master keys and passwords, logging locations, error
- thresholds, and allowed file extensions.
-
addRole(java.lang.String role)
-
-
- Adds a role to an account.
-
-
-
- void
-
addRoles(java.util.Set newRoles)
-
-
- Adds a set of roles to an account.
-
-
-
- void
-
changePassword(java.lang.String oldPassword,
- java.lang.String newPassword1,
- java.lang.String newPassword2)
-
-
- Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
-
-
-
- java.lang.Object
-
clone()
-
-
- Override clone and make final to prevent duplicate user objects.
Sets the user's password, performing a verification of the user's old password, the equality of the two new
- passwords, and the strength of the new password.
-
AuthenticationException - if newPassword1 does not match newPassword2, if oldPassword does not match the stored old password, or if the new password does not meet complexity requirements
In this implementation, we have chosen to use a random token that is
- stored in the User object. Note that it is possible to avoid the use of
- server side state by using either the hash of the users's session id or
- an encrypted token that includes a timestamp and the user's IP address.
- user's IP address. A relatively short 8 character string has been chosen
- because this token will appear in all links and forms.
-
Verify that the supplied password matches the password for this user. This method
- is typically used for "reauthentication" for the most sensitive functions, such
- as transactions, changing email address, and changing other account information.
-
-Reference implementation of the Validator interface. This implementation
- relies on the ESAPI Encoder, Java Pattern (regex), Date,
- and several other classes to provide basic validation functions. This library
- has a heavy emphasis on whitelist validation and canonicalization. All double-encoded
- characters, even in multiple encoding schemes, such as
<
or
-
%26lt;
or even
%25%26lt;
are disallowed.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security, Jim Manico (jim.manico .at. aspectsecurity.com) Aspect Security
assertIsValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- void
-
assertIsValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set required,
- java.util.Set optional)
-
-
- Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition.
getValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated credit card number as a String.
getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns a valid date as a Date.
-
-
-
- java.util.Date
-
getValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Returns a valid date as a Date.
-
-
-
- java.lang.String
-
getValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated directory path as a String.
getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- java.lang.Double
-
getValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Returns a validated real number as a double.
-
-
-
- byte[]
-
getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns validated file content as a byte array.
-
-
-
- byte[]
-
getValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Returns validated file content as a byte array.
-
-
-
- java.lang.String
-
getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.String
-
getValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Returns a canonicalized and validated file name as a String.
-
-
-
- java.lang.String
-
getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Validates data received from the browser and returns a safe version.
-
-
-
- java.lang.String
-
getValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Validates data received from the browser and returns a safe version.
-
-
-
- java.lang.Integer
-
getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- java.lang.Integer
-
getValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Returns a validated integer.
-
-
-
- java.lang.String
-
getValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns the list item that exactly matches the canonicalized input.
getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns a validated number as a double.
-
-
-
- java.lang.Double
-
getValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull,
- ValidationErrorList errors)
-
-
- Returns a validated number as a double within the range of minValue to maxValue.
-
-
-
- byte[]
-
getValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Returns canonicalized and validated printable characters as a byte array.
isValidCreditCard(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid credit card.
-
-
-
- boolean
-
isValidDate(java.lang.String context,
- java.lang.String input,
- java.text.DateFormat format,
- boolean allowNull)
-
-
- Returns true if input is a valid date according to the specified date format.
-
-
-
- boolean
-
isValidDirectoryPath(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if the directory path (not including a filename) is valid.
-
-
-
- boolean
-
isValidDouble(java.lang.String context,
- java.lang.String input,
- double minValue,
- double maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid double within the range of minValue to maxValue.
-
-
-
- boolean
-
isValidFileContent(java.lang.String context,
- byte[] input,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if input is valid file content.
-
-
-
- boolean
-
isValidFileName(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid file name.
-
-
-
- boolean
-
isValidFileUpload(java.lang.String context,
- java.lang.String directorypath,
- java.lang.String filename,
- byte[] content,
- int maxBytes,
- boolean allowNull)
-
-
- Returns true if a file upload has a valid name, path, and content.
-
-
-
- boolean
-
isValidHTTPRequest()
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- boolean
-
isValidHTTPRequest(javax.servlet.http.HttpServletRequest request)
-
-
- Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters.
-
-
-
- boolean
-
isValidHTTPRequestParameterSet(java.lang.String context,
- java.util.Set requiredNames,
- java.util.Set optionalNames)
-
-
- Returns true if the parameters in the current request contain all required parameters and only optional ones in addition.
-
-
-
- boolean
-
isValidInput(java.lang.String context,
- java.lang.String input,
- java.lang.String type,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if data received from browser is valid.
-
-
-
- boolean
-
isValidInteger(java.lang.String context,
- java.lang.String input,
- int minValue,
- int maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid integer within the range of minValue to maxValue.
-
-
-
- boolean
-
isValidListItem(java.lang.String context,
- java.lang.String input,
- java.util.List list)
-
-
- Returns true if input is a valid list item.
-
-
-
- boolean
-
isValidNumber(java.lang.String context,
- java.lang.String input,
- long minValue,
- long maxValue,
- boolean allowNull)
-
-
- Returns true if input is a valid number within the range of minValue to maxValue.
-
-
-
- boolean
-
isValidPrintable(java.lang.String context,
- byte[] input,
- int maxLength,
- boolean allowNull)
-
-
- Checks that all bytes are valid ASCII characters (between 33 and 126
- inclusive).
-
-
-
- boolean
-
isValidPrintable(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input contains only valid printable ASCII characters (32-126).
-
-
-
- boolean
-
isValidRedirectLocation(java.lang.String context,
- java.lang.String input,
- boolean allowNull)
-
-
- Returns true if input is a valid redirect location.
-
-
-
- boolean
-
isValidSafeHTML(java.lang.String context,
- java.lang.String input,
- int maxLength,
- boolean allowNull)
-
-
- Returns true if input is "safe" HTML.
-
-
-
- java.lang.String
-
safeReadLine(java.io.InputStream in,
- int max)
-
-
- This implementation reads until a newline or the specified number of
- characters.
context - A descriptive name for the field to validate. This is used for error facing validation messages and element identification.
input - The actual user input data to validate.
type - The regular expression name while maps to the actual regular expression from "ESAPI.properties".
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then a input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
context - A descriptive name for the field to validate. This is used for error facing validation messages and element identification.
input - The actual user input data to validate.
type - The regular expression name while maps to the actual regular expression from "ESAPI.properties".
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then a input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
context - A descriptive name for the field to validate. This is used for error facing validation messages and element identification.
input - The actual user input data to validate.
type - The regular expression name while maps to the actual regular expression from "ESAPI.properties".
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then a input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If ValidationException is thrown, then add to error list instead of throwing out to caller
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
format - Required formatting of date inputted.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if input is a valid date according to the format specified by 'format'
-
Returns a valid date as a Date. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
format - Required formatting of date inputted.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a valid date as a Date. Invalid input will generate a descriptive ValidationException and store it inside of
- the errorList argument, and input that is clearly an attack will generate a descriptive IntrusionException. Instead of
- throwing a ValidationException on error, this variant will store the exception inside of the ValidationErrorList.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
format - Required formatting of date inputted.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
Returns true if input is "safe" HTML. Implementors should reference the OWASP AntiSamy project for ideas
- on how to do HTML validation in a whitelist way, as this is an extremely difficult problem.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns canonicalized and validated "safe" HTML. Implementors should reference the OWASP AntiSamy project for ideas
- on how to do HTML validation in a whitelist way, as this is an extremely difficult problem.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
maxLength - The maximum post-canonicalized String length allowed.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a canonicalized and validated credit card number as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual user input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a canonicalized and validated directory path as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a canonicalized and validated file name as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a canonicalized and validated file name as a String. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a validated number as a double. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
Returns a validated number as a double within the range of minValue to maxValue. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a validated number as a double. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
Returns a validated real number as a double. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns a validated number as a double. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
Returns a validated integer. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
minValue - Lowest legal value for input.
maxValue - Highest legal value for input.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
maxBytes - The maximum number of bytes allowed in a legal file.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns validated file content as a byte array. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
maxBytes - The maximum number of bytes allowed in a legal file.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns validated file content as a byte array. This is a good place to check for max file size, allowed character sets, and do virus scans. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException. Instead of throwing a ValidationException
- on error, this variant will store the exception inside of the ValidationErrorList.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The actual input data to validate.
maxBytes - The maximum number of bytes allowed in a legal file.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
directorypath - The file path of the uploaded file.
filename - The filename of the uploaded file
content - A byte array containing the content of the uploaded file.
maxBytes - The max number of bytes allowed for a legal file upload.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if a file upload has a valid name, path, and content.
-
Validates the filepath, filename, and content of a file. Invalid input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
directorypath - The file path of the uploaded file.
filename - The filename of the uploaded file
content - A byte array containing the content of the uploaded file.
maxBytes - The max number of bytes allowed for a legal file upload.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
filepath - The file path of the uploaded file.
filename - The filename of the uploaded file
content - A byte array containing the content of the uploaded file.
maxBytes - The max number of bytes allowed for a legal file upload.
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
- Uses current HTTPRequest saved in EASPI Authenticator
-
Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
Validates the current HTTP request by comparing parameters, headers, and cookies to a predefined whitelist of allowed
- characters. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
- Uses current HTTPRequest saved in EASPI Authenticator
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
Returns the list item that exactly matches the canonicalized input. Invalid or non-matching input
- will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The value to search 'list' for.
list - The list to search for 'input'.
-
Returns:
The list item that exactly matches the canonicalized input.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - The value to search 'list' for.
list - The list to search for 'input'.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
Returns:
The list item that exactly matches the canonicalized input.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
requiredNames - parameters that are required to be in HTTP request
optionalNames - additional parameters that may be in HTTP request
-
Returns:
true, if all required parameters are in HTTP request and only optional parameters in addition. Returns false if parameters are found in HTTP request that are not in either set (required or optional), or if any required parameters are missing from request.
Validates that the parameters in the current request contain all required parameters and only optional ones in
- addition. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
required - parameters that are required to be in HTTP request
optional - additional parameters that may be in HTTP request
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
required - parameters that are required to be in HTTP request
optional - additional parameters that may be in HTTP request
errors - If validation is in error, resulting error will be stored in the errorList by context
-
Checks that all bytes are valid ASCII characters (between 33 and 126
- inclusive). This implementation does no decoding. http://en.wikipedia.org/wiki/ASCII. (non-Javadoc)
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be checked for validity
maxLength - Maximum number of bytes stored in 'input'
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if 'input' is less than maxLength and contains only valid, printable characters
-
Returns canonicalized and validated printable characters as a byte array. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be returned as valid and printable
maxLength - Maximum number of bytes stored in 'input'
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
a byte array containing only printable characters, made up of data from 'input'
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be returned as valid and printable
maxLength - Maximum number of bytes stored in 'input'
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
Returns:
a byte array containing only printable characters, made up of data from 'input'
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be checked for validity
maxLength - Maximum number of bytes stored in 'input' after canonicalization
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if 'input' is less than maxLength after canonicalization and contains only valid, printable characters
-
Returns canonicalized and validated printable characters as a String. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be returned as valid and printable
maxLength - Maximum number of bytes stored in 'input' after canonicalization
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
a String containing only printable characters, made up of data from 'input'
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - data to be returned as valid and printable
maxLength - Maximum number of bytes stored in 'input' after canonicalization
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
Returns:
a String containing only printable characters, made up of data from 'input'
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - redirect location to be checked for validity, according to rules set in "ESAPI.properties"
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
true, if 'input' is a valid redirect location, as defined by "ESAPI.properties", false otherwise.
-
Returns a canonicalized and validated redirect location as a String. Invalid input will generate a descriptive ValidationException, and input that is clearly an attack
- will generate a descriptive IntrusionException.
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - redirect location to be returned as valid, according to encoding rules set in "ESAPI.properties"
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
-
Returns:
A canonicalized and validated redirect location, as defined in "ESAPI.properties"
-
context - A descriptive name of the parameter that you are validating (e.g., LoginPage_UsernameField). This value is used by any logging or error handling that is done with respect to the value passed in.
input - redirect location to be returned as valid, according to encoding rules set in "ESAPI.properties"
allowNull - If allowNull is true then an input that is NULL or an empty string will be legal. If allowNull is false then NULL or an empty String will throw a ValidationException.
errors - If validation is in error, resulting error will be stored in the errorList by context
-
Returns:
A canonicalized and validated redirect location, as defined in "ESAPI.properties"
-
-Reference implementation of the AccessController interface. This reference
- implementation uses a simple model for specifying a set of access control
- rules. Many organizations will want to create their own implementation of the
- methods provided in the IAccessController interface.
-
- This reference implementation uses a simple scheme for specifying the rules.
- The first step is to create a namespace for the resources being accessed. For
- files and URL's, this is easy as they already have a namespace. Be extremely
- careful about canonicalizing when relying on information from the user in an
- access ctnrol decision.
-
- For functions, data, and services, you will have to come up with your own
- namespace for the resources being accessed. You might simply define a flat
- namespace with a list of category names. For example, you might specify
- 'FunctionA', 'FunctionB', and 'FunctionC'. Or you can create a richer
- namespace with a hierarchical structure, such as:
-
- /functions
-
-
purchasing
-
shipping
-
inventory
-
- /admin
-
-
createUser
-
deleteUser
-
- Once you've defined your namespace, you have to work out the rules that
- govern access to the different parts of the namespace. This implementation
- allows you to attach a simple access control list (ACL) to any part of the
- namespace tree. The ACL lists a set of roles that are either allowed or
- denied access to a part of the tree. You specify these rules in a textfile
- with a simple format.
-
- There is a single configuration file supporting each of the five methods in
- the IAccessController interface. These files are located in the ESAPI
- resources directory as specified when the JVM was started. The use of a
- default deny rule is STRONGLY recommended. The file format is as follows:
-
-
- path | role,role | allow/deny | comment
- ------------------------------------------------------------------------------------
- /banking/* | user,admin | allow | authenticated users can access /banking
- /admin | admin | allow | only admin role can access /admin
- / | any | deny | default deny rule
-
-
- To find the matching rules, this implementation follows the general approach
- used in Java EE when matching HTTP requests to servlets in web.xml. The
- four mapping rules are used in the following order:
-
-
exact match, e.g. /access/login
-
longest path prefix match, beginning / and ending /*, e.g. /access/* or /*
-
extension match, beginning *., e.g. *.css
-
default rule, specified by the single character pattern /
Checks if an account is authorized to access the referenced URL. The implementation should allow
- access to be granted to any part of the URL. Generally, this method should be invoked in the
- application's controller or a filter as follows:
-
Checks if an account is authorized to access the referenced function. The implementation should define the
- function "namespace" to be enforced. Choosing something simple like the classname of action classes or menu item
- names will make this implementation easier to use.
-
Checks if an account is authorized to access the referenced service. This can be used in applications that
- provide access to a variety of backend services.
-
Checks if an account is authorized to access the referenced URL. The implementation should allow
- access to be granted to any part of the URL. Generally, this method should be invoked in the
- application's controller or a filter as follows:
-
Checks if an account is authorized to access the referenced function. The implementation should define the
- function "namespace" to be enforced. Choosing something simple like the classname of action classes or menu item
- names will make this implementation easier to use.
-
Checks if an account is authorized to access the referenced service. This can be used in applications that
- provide access to a variety of backend services.
-
-Reference implementation of the Authenticator interface. This reference implementation is backed by a simple text
- file that contains serialized information about users. Many organizations will want to create their own
- implementation of the methods provided in the IAuthenticator interface backed by their own user repository. This
- reference implementation captures information about users in a simple text file format that contains user information
- separated by the pipe "|" character. Here's an example of a single line from the users.txt file:
-
-
-
- account id | account name | hashed password | roles | lockout | status | old password hashes | last
- hostname | last change | last login | last failed | expiration | failed
- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- 1203123710837 | mitch | 44k/NAzQUlrCq9musTGGkcMNmdzEGJ8w8qZTLzpxLuQ= | admin,user | unlocked | enabled |
- u10dW4vTo3ZkoM5xP+blayWCz7KdPKyKUojOn9GJobg= | 192.168.1.255 | 1187201000926 | 1187200991568 | 1187200605330 |
- 2187200605330 | 1
-
-
createUser(java.lang.String accountName,
- java.lang.String password1,
- java.lang.String password2)
-
-
- Creates a new User with the information provided.
-
-
-
- boolean
-
exists(java.lang.String accountName)
-
-
- Determine if the account exists.
generateStrongPassword(User user,
- java.lang.String oldPassword)
-
-
- Generate strong password that takes into account the user's information and old password.
hashPassword(java.lang.String password,
- java.lang.String accountName)
-
-
- Returns a string representation of the hashed password, using the
- accountName as the salt.
login(javax.servlet.http.HttpServletRequest request,
- javax.servlet.http.HttpServletResponse response)
-
-
- This method should be called for every HTTP request, to login the current user either from the session of HTTP
- request.
verifyAccountNameStrength(java.lang.String newAccountName)
-
-
- Ensures that the account name passes site-specific complexity requirements, like minimum length.
-
-
-
- boolean
-
verifyPassword(User user,
- java.lang.String password)
-
-
- Verify that the supplied password matches the password for this user.
-
-
-
- void
-
verifyPasswordStrength(java.lang.String oldPassword,
- java.lang.String newPassword)
-
-
- Ensures that the password meets site-specific complexity requirements.
Fail safe main program to add or update an account in an emergency.
-
- Warning: this method does not perform the level of validation and checks
- generally required in ESAPI, and can therefore be used to create a username and password that do not comply
- with the username and password strength requirements.
-
- Example: Use this to add the alice account with the admin role to the users file:
-
Clears all threadlocal variables from the thread. This should ONLY be called after
- all possible ESAPI operations have concluded. If you clear too early, many calls will
- fail, including logging, which requires the user identity.
-
Creates a new User with the information provided. Implementations should check the
- accountName and password for proper format and strength against brute force attacks.
- Two copies of the new password are required to encourage user interface designers to
- include a "re-type password" field in their forms. Implementations should verify that both are the
- same.
-
Generate a strong password. Implementations should use a large character set that does not
- include confusing characters, such as i I 1 l 0 o and O. There are many algorithms to
- generate strong memorable passwords that have been studied in the past.
-
Changes the password for the specified user. This requires the current password, as well as
- the password to replace it with. This new password must be repeated to ensure that the user has
- typed it in correctly.
-
Verify that the supplied password matches the password for this user. This method
- is typically used for "reauthentication" for the most sensitive functions, such
- as transactions, changing email address, and changing other account information.
-
Generate strong password that takes into account the user's information and old password. Implementations
- should verify that the new password does not include information such as the username, fragments of the
- old password, and other information that could be used to weaken the strength of the password.
-
Returns a string representation of the hashed password, using the
- accountName as the salt. The salt helps to prevent against "rainbow"
- table attacks where the attacker pre-calculates hashes for known strings.
- This method specifies the use of the user's account name as the "salt"
- value. The Encryptor.hash method can be used if a different salt is
- required.
-
This method should be called for every HTTP request, to login the current user either from the session of HTTP
- request. This method will set the current user so that getCurrentUser() will work properly. This method also
- checks that the user's access is still enabled, unlocked, and unexpired before allowing login. For convenience
- this method also returns the current user.
-
Ensures that the password meets site-specific complexity requirements. This
- method takes the old password so that the algorithm can analyze the new password
- to see if it is too similar to the old password. Note that this has to be
- invoked when the user has entered the old password, as the list of old
- credentials stored by ESAPI is all hashed.
-
IntegerAccessReferenceMap()
-
-
- This AccessReferenceMap implementation uses integers to
- create a layer of indirection.
-
-
-
IntegerAccessReferenceMap(java.util.Set directReferences)
-
-
- Instantiates a new access reference map.
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
addDirectReference(java.lang.Object direct)
-
-
- Adds a direct reference and a new indirect reference, overwriting any existing values.
-
-
-
- java.lang.Object
-
getDirectReference(java.lang.String indirectReference)
-
-
- Get the original direct object reference from an indirect reference.
-
-
-
- java.lang.String
-
getIndirectReference(java.lang.Object directReference)
-
-
- Get a safe indirect reference to use in place of a potentially sensitive
- direct object reference.
-
-
-
- java.util.Iterator
-
iterator()
-
-
- Get an iterator through the direct object references.
-
-
-
- java.lang.String
-
removeDirectReference(java.lang.Object direct)
-
-
- Remove a direct reference and the corresponding indirect reference.
-
-
-
- void
-
update(java.util.Set directReferences)
-
-
- This preserves any existing mappings for items that are still in the new
- list.
-public final void update(java.util.Set directReferences)
-
-
This preserves any existing mappings for items that are still in the new
- list. You could regenerate new indirect references every time, but that
- might mess up anything that previously used an indirect reference, such
- as a URL parameter.
-
Get a safe indirect reference to use in place of a potentially sensitive
- direct object reference. Developers should use this call when building
- URL's, form fields, hidden fields, etc... to help protect their private
- implementation information.
-
Get the original direct object reference from an indirect reference.
- Developers should use this when they get an indirect reference from a
- request to translate it back into the real direct reference. If an
- invalid indirectReference is requested, then an AccessControlException is
- thrown.
-
-Reference implementation of the IEncryptor interface. This implementation
- layers on the JCE provided cryptographic package. Algorithms used are
- configurable in the ESAPI.properties file.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
decrypt(java.lang.String ciphertext)
-
-
- Decrypts the provided ciphertext string (encrypted with the encrypt
- method) and returns a plaintext string.
-
-
-
- java.lang.String
-
encrypt(java.lang.String plaintext)
-
-
- Encrypts the provided plaintext and returns a ciphertext string.
-
-
-
- long
-
getRelativeTimeStamp(long offset)
-
-
- Gets an absolute timestamp representing an offset from the current time to be used by
- other functions in the library.
-
-
-
- long
-
getTimeStamp()
-
-
- Gets a timestamp representing the current date and time to be used by
- other functions in the library.
-
-
-
- java.lang.String
-
hash(java.lang.String plaintext,
- java.lang.String salt)
-
-
- Hashes the data using the specified algorithm and the Java MessageDigest class.
-
-
-
- java.lang.String
-
seal(java.lang.String data,
- long expiration)
-
-
- Creates a seal that binds a set of data and includes an expiration timestamp.
-
-
-
- java.lang.String
-
sign(java.lang.String data)
-
-
- Create a digital signature for the provided data and return it in a
- string.
-
-
-
- java.lang.String
-
unseal(java.lang.String seal)
-
-
- Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
-
-
-
- boolean
-
verifySeal(java.lang.String seal)
-
-
- Verifies a seal (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or data mismatch.
-
-
-
- boolean
-
verifySignature(java.lang.String signature,
- java.lang.String data)
-
-
- Verifies a digital signature (created with the sign method) and returns
- the boolean result.
Hashes the data using the specified algorithm and the Java MessageDigest class. This method
- first adds the salt, a separator (":"), and the data, and then rehashes 1024 times to help strengthen weak passwords.
-
Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
-
Verifies a seal (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or data mismatch.
-
-Reference implementation of the Encryptor interface. This implementation
- layers on the JCE provided cryptographic package. Algorithms used are
- configurable in the ESAPI.properties file.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
decrypt(java.lang.String ciphertext)
-
-
- Decrypts the provided ciphertext string (encrypted with the encrypt
- method) and returns a plaintext string.
-
-
-
- java.lang.String
-
encrypt(java.lang.String plaintext)
-
-
- Encrypts the provided plaintext and returns a ciphertext string.
-
-
-
- long
-
getRelativeTimeStamp(long offset)
-
-
- Gets an absolute timestamp representing an offset from the current time to be used by
- other functions in the library.
-
-
-
- long
-
getTimeStamp()
-
-
- Gets a timestamp representing the current date and time to be used by
- other functions in the library.
-
-
-
- java.lang.String
-
hash(java.lang.String plaintext,
- java.lang.String salt)
-
-
- Hashes the data using the specified algorithm and the Java MessageDigest class.
-
-
-
- java.lang.String
-
seal(java.lang.String data,
- long expiration)
-
-
- Creates a seal that binds a set of data and includes an expiration timestamp.
-
-
-
- java.lang.String
-
sign(java.lang.String data)
-
-
- Create a digital signature for the provided data and return it in a
- string.
-
-
-
- java.lang.String
-
unseal(java.lang.String seal)
-
-
- Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
-
-
-
- boolean
-
verifySeal(java.lang.String seal)
-
-
- Verifies a seal (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or data mismatch.
-
-
-
- boolean
-
verifySignature(java.lang.String signature,
- java.lang.String data)
-
-
- Verifies a digital signature (created with the sign method) and returns
- the boolean result.
Hashes the data using the specified algorithm and the Java MessageDigest class. This method
- first adds the salt, a separator (":"), and the data, and then rehashes 1024 times to help strengthen weak passwords.
-
Unseals data (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or decryption error.
-
Verifies a seal (created with the seal method) and throws an exception
- describing any of the various problems that could exist with a seal, such
- as an invalid seal format, expired timestamp, or data mismatch.
-
-Reference implementation of the LogFactory and Logger interfaces. This implementation uses the Java logging package, and marks each
- log message with the currently logged in user and the word "SECURITY" for security related events.
-
-
-
-
-
Since:
-
June 1, 2007
-
Author:
-
Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
-Reference implementation of the AccessReferenceMap interface. This
- implementation generates random 6 character alphanumeric strings for indirect
- references. It is possible to use simple integers as indirect references, but
- the random string approach provides a certain level of protection from CSRF
- attacks, because an attacker would have difficulty guessing the indirect
- reference.
-
RandomAccessReferenceMap()
-
-
- This AccessReferenceMap implementation uses short random strings to
- create a layer of indirection.
-
-
-
RandomAccessReferenceMap(java.util.Set directReferences)
-
-
- Instantiates a new access reference map.
-
-
-
-
-
-
-
-
-
-Method Summary
-
-
-
- java.lang.String
-
addDirectReference(java.lang.Object direct)
-
-
- Adds a direct reference and a new random indirect reference, overwriting any existing values.
-
-
-
- java.lang.Object
-
getDirectReference(java.lang.String indirectReference)
-
-
- Get the original direct object reference from an indirect reference.
-
-
-
- java.lang.String
-
getIndirectReference(java.lang.Object directReference)
-
-
- Get a safe indirect reference to use in place of a potentially sensitive
- direct object reference.
-
-
-
- java.util.Iterator
-
iterator()
-
-
- Get an iterator through the direct object references.
-
-
-
- java.lang.String
-
removeDirectReference(java.lang.Object direct)
-
-
- Remove a direct reference and the corresponding indirect reference.
-
-
-
- void
-
update(java.util.Set directReferences)
-
-
- This preserves any existing mappings for items that are still in the new
- list.
This AccessReferenceMap implementation uses short random strings to
- create a layer of indirection. Other possible implementations would use
- simple integers as indirect references.
-
-public final void update(java.util.Set directReferences)
-
-
This preserves any existing mappings for items that are still in the new
- list. You could regenerate new indirect references every time, but that
- might mess up anything that previously used an indirect reference, such
- as a URL parameter.
-
Get a safe indirect reference to use in place of a potentially sensitive
- direct object reference. Developers should use this call when building
- URL's, form fields, hidden fields, etc... to help protect their private
- implementation information.
-
Get the original direct object reference from an indirect reference.
- Developers should use this when they get an indirect reference from a
- request to translate it back into the real direct reference. If an
- invalid indirectReference is requested, then an AccessControlException is
- thrown.
-
-This package contains reference implementations of the ESAPI interfaces. These are intended to
-serve as examples of how your enterprise might implement these functions. The reference implementations
-are high quality and pass all of the ESAPI test cases. Many of the reference implementations are
-likely to be useful in your enterprise without change (Validator, Encoder, Encryptor, etc...).
-Implementing other classes (Authenticator, User, AccessController, Logger, etc...) will likely need to
-be customized for your enterprise, to integrate with your backend systems and policies.
-
-
-The OWASP Enterprise Security API (ESAPI) is both a set of
-interfaces and a reference implementation of a library that provides
-enterprise web application developers the most important security
-functions they need in order to build web applications and web services
-that protect themselves against attacks.
-
The OWASP Enterprise Security API (ESAPI) is both a set of
-interfaces and a reference implementation of a library that provides
-enterprise web application developers the most important security
-functions they need in order to build web applications and web services
-that protect themselves against attacks.
-
-
The The Open Web Application
-Security Project (OWASP) is a worldwide free and open community focused
-on improving the security of application software. Our mission is to
-make application security "visible," so that people and organizations
-can make informed decisions about application security risks. Everyone
-is free to participate in OWASP and all of our materials are available
-under an open source license. The OWASP Foundation is a 501c3
-not-for-profit charitable organization that ensures the ongoing
-availability and support for our work.
-
-
The OWASP ESAPI Project is led by Jeff Williams, Aspect Security
-
-
You can find more information about the ESAPI project, or join
-the mailing list and help us make it better from the OWASP project page
-at http://www.owasp.org/index.php/ESAPI.
-
-
-
-
The library builds on the excellent security libraries available,
-such as Java Logging, JCE, and Adobe Commons FileUpload. It uses the
-concepts from many of the security packages out there, such as ACEGI,
-Apache Commons Validator, Microsoft's AntiXSS library, and many many
-more. This library provides a single consistent interface to security
-functions that is intuitive for enterprise developers.
-
-
-
-
Used properly, the ESAPI provides enough functions to protect
-against most of the OWASP Top Ten. The only real exception is the
-Insecure Communications category, which is generally outside the control
-of the software developer.
-
-
This project and all associated code is Copyright (c) 2007 - The OWASP Foundation
-
-
The ESAPI is published by OWASP under the LGPL. You should read and accept the LICENSE
-before you use, modify, and/or redistribute this software.
-
-
-
-
-
-
-
diff --git a/javadoc/stylesheet.css b/javadoc/stylesheet.css
deleted file mode 100644
index 14c3737e8..000000000
--- a/javadoc/stylesheet.css
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Javadoc style sheet */
-
-/* Define colors, fonts and other style attributes here to override the defaults */
-
-/* Page background color */
-body { background-color: #FFFFFF }
-
-/* Headings */
-h1 { font-size: 145% }
-
-/* Table colors */
-.TableHeadingColor { background: #CCCCFF } /* Dark mauve */
-.TableSubHeadingColor { background: #EEEEFF } /* Light mauve */
-.TableRowColor { background: #FFFFFF } /* White */
-
-/* Font used in left-hand frame lists */
-.FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif }
-.FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif }
-.FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif }
-
-/* Navigation bar fonts and colors */
-.NavBarCell1 { background-color:#EEEEFF;} /* Light mauve */
-.NavBarCell1Rev { background-color:#00008B;} /* Dark Blue */
-.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;}
-.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
-
-.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
-.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
-
diff --git a/lib/antisamy-bin.1.2.jar b/lib/antisamy-bin.1.2.jar
deleted file mode 100644
index 1189dcbfc..000000000
Binary files a/lib/antisamy-bin.1.2.jar and /dev/null differ
diff --git a/lib/batik-css.jar b/lib/batik-css.jar
deleted file mode 100644
index 33c6ff0e1..000000000
Binary files a/lib/batik-css.jar and /dev/null differ
diff --git a/lib/batik-util.jar b/lib/batik-util.jar
deleted file mode 100644
index 240e89394..000000000
Binary files a/lib/batik-util.jar and /dev/null differ
diff --git a/lib/commons-codec-1.3.jar b/lib/commons-codec-1.3.jar
deleted file mode 100644
index 957b6752a..000000000
Binary files a/lib/commons-codec-1.3.jar and /dev/null differ
diff --git a/lib/commons-fileupload-1.2-sources.jar b/lib/commons-fileupload-1.2-sources.jar
deleted file mode 100644
index a6ca5f79c..000000000
Binary files a/lib/commons-fileupload-1.2-sources.jar and /dev/null differ
diff --git a/lib/commons-fileupload-1.2.jar b/lib/commons-fileupload-1.2.jar
deleted file mode 100644
index 12539f5ed..000000000
Binary files a/lib/commons-fileupload-1.2.jar and /dev/null differ
diff --git a/lib/commons-httpclient-3.1.jar b/lib/commons-httpclient-3.1.jar
deleted file mode 100644
index 7c59774ae..000000000
Binary files a/lib/commons-httpclient-3.1.jar and /dev/null differ
diff --git a/lib/commons-io-1.3.2-sources.jar b/lib/commons-io-1.3.2-sources.jar
deleted file mode 100644
index b383cf381..000000000
Binary files a/lib/commons-io-1.3.2-sources.jar and /dev/null differ
diff --git a/lib/commons-io-1.3.2.jar b/lib/commons-io-1.3.2.jar
deleted file mode 100644
index 865c9e41c..000000000
Binary files a/lib/commons-io-1.3.2.jar and /dev/null differ
diff --git a/lib/commons-logging-1.1.1.jar b/lib/commons-logging-1.1.1.jar
deleted file mode 100644
index 8758a96b7..000000000
Binary files a/lib/commons-logging-1.1.1.jar and /dev/null differ
diff --git a/lib/jsp-api.jar b/lib/jsp-api.jar
deleted file mode 100644
index 6647cb571..000000000
Binary files a/lib/jsp-api.jar and /dev/null differ
diff --git a/lib/junit-4.4.jar b/lib/junit-4.4.jar
deleted file mode 100644
index 649b0b327..000000000
Binary files a/lib/junit-4.4.jar and /dev/null differ
diff --git a/lib/nekohtml.jar b/lib/nekohtml.jar
deleted file mode 100644
index 0be02315f..000000000
Binary files a/lib/nekohtml.jar and /dev/null differ
diff --git a/lib/proguard.jar b/lib/proguard.jar
deleted file mode 100644
index 248355cd0..000000000
Binary files a/lib/proguard.jar and /dev/null differ
diff --git a/lib/servlet-api.jar b/lib/servlet-api.jar
deleted file mode 100644
index 2fb91b486..000000000
Binary files a/lib/servlet-api.jar and /dev/null differ
diff --git a/lib/task.properties b/lib/task.properties
deleted file mode 100644
index b676db7c3..000000000
--- a/lib/task.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-proguard = proguard.ant.ProGuardTask
-proguardconfiguration = proguard.ant.ConfigurationTask
diff --git a/lib/xercesImpl.jar b/lib/xercesImpl.jar
deleted file mode 100644
index 8f762e1a8..000000000
Binary files a/lib/xercesImpl.jar and /dev/null differ
diff --git a/lib/xml-apis-ext.jar b/lib/xml-apis-ext.jar
deleted file mode 100644
index 8076110f7..000000000
Binary files a/lib/xml-apis-ext.jar and /dev/null differ
diff --git a/lib/xml-apis.jar b/lib/xml-apis.jar
deleted file mode 100644
index d42c0ea6c..000000000
Binary files a/lib/xml-apis.jar and /dev/null differ
diff --git a/local.properties b/local.properties
deleted file mode 100644
index 2af564f0e..000000000
--- a/local.properties
+++ /dev/null
@@ -1 +0,0 @@
-proguard.location=${basedir}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 000000000..6797acc2a
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,1030 @@
+
+
+ 4.0.0
+ org.owasp.esapi
+ esapi
+ 2.7.1.0-SNAPSHOT
+ jar
+
+
+
+ central
+ https://central.sonatype.org/publish/publish-portal-maven/
+
+
+ https://github.com/ESAPI/esapi-java-legacy/releases
+
+
+
+
+ BSD
+ https://www.opensource.org/licenses/bsd-license.php
+ Code License - New BSD License
+
+
+ Creative Commons 3.0 BY-SA
+ https://creativecommons.org/licenses/by-sa/3.0/
+ Content License - Create Commons 3.0 BY-SA
+
+
+
+ ESAPI
+ https://owasp.org/www-project-enterprise-security-api/
+ The Enterprise Security API (ESAPI) project is an OWASP project
+ to create simple strong security controls for every web platform.
+ Security controls are not simple to build. You can read about the
+ hundreds of pitfalls for unwary developers on the OWASP web site. By
+ providing developers with a set of strong controls, we aim to
+ eliminate some of the complexity of creating secure web applications.
+ This can result in significant cost savings across the SDLC.
+
+
+
+ The Open Worldwide Application Security Project (OWASP)
+ https://owasp.org/
+
+
+
+
+ ESAPI-Project-Users
+ https://groups.google.com/a/owasp.org/forum/#!forum/esapi-project-users/join
+ https://groups.google.com/a/owasp.org/forum/#!forum/esapi-project-users/unsubscribe
+ mailto:esapi-project-users@owasp.org
+ (Pre 3/25/2019) https://lists.owasp.org/pipermail/esapi-users/
+
+
+
+ ESAPI-Project-Dev
+ https://groups.google.com/a/owasp.org/forum/#!forum/esapi-project-dev/join
+ https://groups.google.com/a/owasp.org/forum/#!forum/esapi-project-dev/unsubscribe
+ mailto:esapi-project-dev@owasp.org
+ (Pre 3/25/2019) https://lists.owasp.org/pipermail/esapi-dev/
+
+
+
+ OWASP-ESAPI (Inactive! Archive only!)
+ https://lists.owasp.org/pipermail/owasp-esapi/
+
+
+
+
+
+ scm:git:git://github.com/ESAPI/esapi-java-legacy.git
+ scm:git:git@github.com:ESAPI/esapi-java-legacy.git
+ https://github.com/ESAPI/esapi-java-legacy
+
+
+
+ GitHub Issue Tracking
+ https://github.com/ESAPI/esapi-java-legacy/issues
+
+
+
+
+ Jeff Williams
+ Contrast Security
+
+ Project Founder
+
+
+
+ Kevin W. Wall
+ Verisign
+
+ Project Co-leader
+
+
+
+ Matt Seil
+ OWASP
+
+ Project Co-leader
+
+
+
+ Jeremiah J. Stacey
+
+ JUnit SME
+ Jack of all trades, master of many
+
+
+
+ Chris Schmidt
+ Fluid Truck
+
+ Former project co-leader
+
+
+
+
+
+
+ Dave Wichers
+
+
+ Jim Manico
+
+
+
+
+ UTF-8
+ 1.37
+ 2.0.0-M3
+ 2.0.0-M11
+ 2.0.9
+ 4.9.3
+ 4.9.3.1
+ 3.5.3
+ 1.8
+
+
+
+ 2025-06-02 00:00:00
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ provided
+
+
+ javax.servlet.jsp
+ javax.servlet.jsp-api
+ 2.3.3
+ provided
+
+
+
+ javax.servlet
+ javax.servlet-api
+
+
+
+
+ xom
+ xom
+ 1.3.9
+
+
+
+ xerces
+ xercesImpl
+
+
+
+
+ commons-beanutils
+ commons-beanutils
+
+ 1.11.0
+
+
+
+ commons-configuration
+ commons-configuration
+ 1.10
+
+
+
+ commons-logging
+ commons-logging
+
+
+
+ xml-apis
+ xml-apis
+
+
+
+
+ commons-lang
+ commons-lang
+ 2.6
+
+
+ commons-fileupload
+ commons-fileupload
+ 1.6.0
+
+
+
+ commons-io
+ commons-io
+
+
+
+
+ org.apache.commons
+ commons-collections4
+ 4.5.0-M2
+
+
+ org.apache-extras.beanshell
+ bsh
+ 2.0b6
+
+
+ org.owasp.antisamy
+ antisamy
+ 1.7.8
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ org.slf4j
+ slf4j-api
+ 2.0.16
+
+
+ xml-apis
+ xml-apis
+
+ 1.4.01
+
+
+
+
+ com.github.spotbugs
+ spotbugs-annotations
+ ${version.spotbugs}
+ true
+
+
+
+
+ commons-codec
+ commons-codec
+ 1.17.1
+ test
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+ org.bouncycastle
+ bcprov-jdk18on
+ 1.78.1
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+ 2.2
+ test
+
+
+
+ org.powermock
+ powermock-api-mockito2
+ ${version.powermock}
+ test
+
+
+ org.mockito
+ mockito-core
+
+
+
+
+
+ org.mockito
+ mockito-core
+
+ 3.12.4
+ test
+
+
+ org.powermock
+ powermock-core
+ ${version.powermock}
+ test
+
+
+ net.bytebuddy
+ byte-buddy
+
+
+ net.bytebuddy
+ byte-buddy-agent
+
+
+
+
+ org.powermock
+ powermock-module-junit4
+ ${version.powermock}
+ test
+
+
+ junit
+ junit
+
+
+ org.hamcrest
+ hamcrest-core
+
+
+
+
+ org.powermock
+ powermock-reflect
+ ${version.powermock}
+ test
+
+
+ org.objenesis
+ objenesis
+
+
+ net.bytebuddy
+ byte-buddy
+
+
+ net.bytebuddy
+ byte-buddy-agent
+
+
+
+
+ org.openjdk.jmh
+ jmh-core
+ ${version.jmh}
+ test
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.7.1
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.8.1
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 3.1.1
+
+
+ org.codehaus.mojo
+ versions-maven-plugin
+ 2.18.0
+
+ file:${project.basedir}/versionRuleset.xml
+
+
+
+
+
+
+
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.9.0
+ true
+
+ ${project.name}-${project.version}
+ central
+
+
+
+
+ org.cyclonedx
+ cyclonedx-maven-plugin
+ 2.9.1
+
+
+ package
+ makeBom
+
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ ${version.spotbugs.maven}
+
+
+
+ com.github.spotbugs
+ spotbugs
+ ${version.spotbugs}
+
+
+
+
+
+ com.h3xstream.findsecbugs
+ findsecbugs-plugin
+ ${version.findsecbugs}
+
+
+ io.github.weblegacy
+ taglib-maven-plugin
+ 2.6
+
+
+ org.apache.maven.plugins
+ maven-changelog-plugin
+
+ 3.0.0-M1
+
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+ 3.5.0
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.14.0
+
+ ${project.java.target}
+ ${project.java.target}
+ ${project.java.target}
+ ${project.java.target}
+ true
+ true
+ false
+
+
+ -Xmaxwarns
+ 2000
+
+
+ -Xlint:all,-deprecation,-rawtypes,-unchecked
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+ 2.10
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 3.5.0
+
+
+ org.codehaus.mojo
+ extra-enforcer-rules
+ 1.10.0
+
+
+ org.codehaus.mojo
+ animal-sniffer-enforcer-rule
+ 1.24
+
+
+
+
+
+ enforce-maven
+ enforce
+
+
+
+ [3.6.3,)
+ Building ESAPI 2.x now requires Maven 3.6.3 or later.
+
+
+
+
+
+ check-java-versions
+ compile
+ enforce
+
+
+
+
+ ${project.java.target}
+
+ ESAPI 2.x now uses the JDK1.8 for its baseline. Please make sure that your
+ JAVA_HOME environment variable is pointed to a JDK1.8 or later distribution.
+
+
+
+ ${project.java.target}
+ true
+
+ Dependencies shouldn't require Java 9+
+
+
+ true
+
+
+
+ check-java8API-signatures
+ compile
+ enforce
+
+
+
+
+ org.codehaus.mojo.signature
+
+ java18
+ 1.0
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 3.2.7
+
+
+ sign-artifacts
+ verify
+ sign
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-install-plugin
+ 3.1.4
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.4.2
+
+
+
+ true
+ true
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.11.2
+
+ 8
+ none
+
+
+
+
+ attach-javadocs
+ package
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jxr-plugin
+ 3.6.0
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 3.27.0
+
+
+
+ org.apache.maven.plugins
+ maven-project-info-reports-plugin
+ 3.9.0
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 3.3.1
+
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ 4.0.0-M16
+
+
+ org.apache.maven.skins
+ maven-fluido-skin
+ ${version.fluido}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.3.1
+
+
+ attach-sources
+ package
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${version.surefire}
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+ ${version.surefire}
+
+
+
+ org.codehaus.mojo
+ cobertura-maven-plugin
+ 2.7
+
+
+ html
+ xml
+
+
+
+
+
+ io.github.jiangxincode
+ jdepend-maven-plugin
+ 2.1
+
+
+ org.eluder.coveralls
+ coveralls-maven-plugin
+ 4.3.0
+
+
+
+ org.owasp
+ dependency-check-maven
+
+
+ 10.0.4
+
+ ${env.NVD_API_KEY}
+ 1.0
+ ./suppressions.xml
+
+
+
+
+ purge
+
+
+
+
+
+
+
+
+
+
+
+
+ io.github.weblegacy
+ taglib-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-changelog-plugin
+
+ [Ii]ssue[# ]*(\d)+
+ https://github.com/ESAPI/esapi-java-legacy/issues/%ISSUE%
+ date
+
+
+
+ ${date.prev_release}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ none
+ 8
+ true
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-jxr-plugin
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+
+ ${project.java.target}
+ utf-8
+
+
+
+
+ org.apache.maven.plugins
+ maven-project-info-reports-plugin
+
+
+
+ index
+ dependency-convergence
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+
+
+
+ io.github.jiangxincode
+ jdepend-maven-plugin
+
+
+
+ org.codehaus.mojo
+ versions-maven-plugin
+
+
+
+ dependency-updates-report
+ plugin-updates-report
+ property-updates-report
+
+
+
+
+
+
+
+
+
+
+
+ dist
+
+
+
+
+ performRelease
+ true
+
+
+
+
+
+
+
+ maven-jar-plugin
+
+
+
+
+
+ true
+ true
+
+
+ true
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ src/main/assembly/dist.xml
+
+
+
+
+ make-dist
+ package
+
+ single
+
+
+
+
+
+
+
+
+
+
+
+
+ jakarta
+
+ true
+
+
+
+
+ org.eclipse.transformer
+ transformer-maven-plugin
+ 0.5.0
+ true
+
+
+ true
+
+
+
+
+ default-jar
+
+ jar
+
+
+ jakarta
+
+ org.owasp.esapi
+ esapi
+ ${project.version}
+
+
+
+
+ javadoc-jar
+
+ jar
+
+
+ false
+ jakarta-javadoc
+
+ org.owasp.esapi
+ esapi
+ ${project.version}
+ javadoc
+
+
+
+
+ source-jar
+
+ jar
+
+
+ false
+ jakarta-sources
+
+ org.owasp.esapi
+ esapi
+ ${project.version}
+ sources
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/DataAccessRules.txt b/resources/DataAccessRules.txt
deleted file mode 100644
index da4a26914..000000000
--- a/resources/DataAccessRules.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Data Access Rules
-#
-
-/ | any | deny | default deny
-/Data1 | User | allow |
-/Data2 | Admin | allow |
diff --git a/resources/ESAPI.properties b/resources/ESAPI.properties
deleted file mode 100644
index f65c31d10..000000000
--- a/resources/ESAPI.properties
+++ /dev/null
@@ -1,128 +0,0 @@
-# Properties file for OWASP Enterprise Security API (ESAPI)
-# You can find more information about ESAPI at http://www.owasp.org/esapi
-#
-
-# Authentication
-RememberTokenDuration=14
-AllowedLoginAttempts=3
-MaxOldPasswordHashes=13
-UsernameParameterName=username
-PasswordParameterName=password
-
-
-# Encryption
-MasterPassword=owasp1
-MasterSalt=testtest
-
-
-# Validation
-#
-# The ESAPI validator does many security checks on input, such as canonicalization
-# and whitelist validation. Note that all of these validation rules are applied *after*
-# canonicalization. Double-encoded characters (even with different encodings involved,
-# are never allowed.
-#
-# To use:
-#
-# First set up a pattern below. You can choose any name you want, prefixed by the word
-# "Validation." For example:
-# Validaton.email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
-#
-# Then you can validate in your code against the pattern like this:
-# Validator.getInstance().getValidDataFromBrowser( "Email", input );
-# Validator.getInstance().isValidDataFromBrowser( "Email", input );
-#
-Validator.SafeString=^[\p{L}\p{N}.]{0,1024}$
-Validator.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
-Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
-Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&%\\$#_]*)?$
-Validator.CreditCard=^(\\d{4}[- ]?){3}\\d{4}$
-Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$
-
-# Validators used by ESAPI
-Validator.AccountName=^[a-zA-Z0-9]{3,20}$
-Validator.SystemCommand=^[a-zA-Z\\-\\/]{0,64}$
-Validator.RoleName=^[a-z]{1,20}$
-Validator.Redirect=^\\/test.*$
-
-# Global HTTP Validation Rules
-# Values with Base64 encoded data (e.g. encrypted state) will need at least [a-zA-Z0-9\/+=]
-Validator.HTTPParameterName=^[a-zA-Z0-9_]{0,32}$
-Validator.HTTPParameterValue=^[a-zA-Z0-9.\\-\\/+=_ ]*$
-Validator.HTTPCookieName=^[a-zA-Z0-9\\-_]{0,32}$
-Validator.HTTPCookieValue=^[a-zA-Z0-9\\-\\/+=_ ]*$
-Validator.HTTPHeaderName=^[a-zA-Z0-9\\-_]{0,32}$
-Validator.HTTPHeaderValue=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$
-
-# Validation of file related input
-Validator.FileName=^[a-zA-Z0-9.\\-_ ]{0,255}$
-Validator.DirectoryName=^[a-zA-Z0-9.-\\_ ]{0,255}$
-
-# File upload configuration
-ValidExtensions=.zip,.pdf,.doc,.docx,.ppt,.pptx,.tar,.gz,.tgz,.rar,.war,.jar,.ear,.xls,.rtf,.properties,.java,.class,.txt,.xml,.jsp,.jsf,.exe,.dll
-MaxUploadFileBytes=500000000
-
-
-# Content-Type header
-ResponseContentType=text/html; charset=UTF-8
-
-
-# Logging
-#
-# Logging level, values are ALL, SEVERE, WARNING, INFO, DEBUG?
-LogLevel=ALL
-LogEncodingRequired=false
-
-# Algorithms
-# WARNING: Changing these settings will invalidate all user passwords, hashes, and encrypted data
-# WARNING: Reasonable values for these algorithms will be tested and documented in a future release
-#
-CharacterEncoding=UTF-8
-HashAlgorithm=SHA-512
-HashIterations=1024
-#EncryptionAlgorithm=PBEWithMD5AndDES/CBC/PKCS5Padding
-EncryptionAlgorithm=PBEWithMD5AndDES
-RandomAlgorithm=SHA1PRNG
-DigitalSignatureAlgorithm=SHAwithDSA
-
-
-# Intrusion Detection
-#
-# Each event has a base to which .count, .interval, and .action are added
-# The IntrusionException will fire if we receive "count" events within "interval" seconds
-# The IntrusionDetector is configurable to take the following actions: log, logout, and disable
-# (multiple actions separated by commas are allowed e.g. event.test.actions=log,disable
-#
-# Custom Events
-# Names must start with "event." as the base
-# Use IntrusionDetector.addEvent( "test" ) in your code to trigger "event.test" here
-#
-event.test.count=2
-event.test.interval=10
-event.test.actions=disable,log
-
-# Exception Events
-# All EnterpriseSecurityExceptions are registered automatically
-# Call IntrusionDetector.getInstance().addException(e) for Exceptions that do not extend EnterpriseSecurityException
-# Use the fully qualified classname of the exception as the base
-
-# any intrusion is an attack
-org.owasp.esapi.errors.IntrusionException.count=1
-org.owasp.esapi.errors.IntrusionException.interval=1
-org.owasp.esapi.errors.IntrusionException.actions=log,disable,logout
-
-# for test purposes
-org.owasp.esapi.errors.IntegrityException.count=10
-org.owasp.esapi.errors.IntegrityException.interval=5
-org.owasp.esapi.errors.IntegrityException.actions=log,disable,logout
-
-# rapid validation errors indicate scans or attacks in progress
-# org.owasp.esapi.errors.ValidationException.count=10
-# org.owasp.esapi.errors.ValidationException.interval=10
-# org.owasp.esapi.errors.ValidationException.actions=log,logout
-
-# sessions jumping between hosts indicates a session hijacking
-org.owasp.esapi.errors.AuthenticationHostException.count=2
-org.owasp.esapi.errors.AuthenticationHostException.interval=10
-org.owasp.esapi.errors.AuthenticationHostException.actions=log,logout
-
diff --git a/resources/FileAccessRules.txt b/resources/FileAccessRules.txt
deleted file mode 100644
index 6f046cde5..000000000
--- a/resources/FileAccessRules.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Data Access Rules
-#
-
-/ | any | deny | default deny
-/Dir/File1 | User | allow |
-/Dir/File2 | Admin | allow |
diff --git a/resources/FunctionAccessRules.txt b/resources/FunctionAccessRules.txt
deleted file mode 100644
index cfcde79a7..000000000
--- a/resources/FunctionAccessRules.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Function Access Rules
-#
-
-/ | any | deny | default deny
-/FunctionA | User | allow |
-/FunctionAdeny | User | deny |
-/FunctionB | Admin | allow |
-/FunctionBdeny | Admin | deny |
diff --git a/resources/ServiceAccessRules.txt b/resources/ServiceAccessRules.txt
deleted file mode 100644
index cf145e3b8..000000000
--- a/resources/ServiceAccessRules.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# Service Access Rules
-#
-
-/ | any | deny | default deny
-/services | any | deny |
-/services/ServiceA | User | allow |
-/services/ServiceB | Admin | allow |
-
diff --git a/resources/URLAccessRules.txt b/resources/URLAccessRules.txt
deleted file mode 100644
index c9e9d9a03..000000000
--- a/resources/URLAccessRules.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-# URL Access Rules
-#
-
-/ | any | deny | default deny
-/nobody | any | deny |
-/ESAPITest | any | allow |
-/ESAPITest/admin | admin | allow |
-/AspectUpload/* | any | allow |
-/test/admin | admin | allow |
-/test/user | user | allow |
-/test/none | any | deny |
-/test/all | any | allow |
-*.gif | any | allow |
-*.exe | any | deny
diff --git a/resources/antisamy-esapi.xml b/resources/antisamy-esapi.xml
deleted file mode 100644
index 87919127e..000000000
--- a/resources/antisamy-esapi.xml
+++ /dev/null
@@ -1,492 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/esapi.tld b/resources/esapi.tld
deleted file mode 100644
index 7f59854ff..000000000
--- a/resources/esapi.tld
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
- 1.2
- 1.1
-
- esapi
- http://struts.apache.org/tags-html
-
-
- encodeForHTML
- org.owasp.esapi.tags.EncodeForHTMLTag
- JSP
-
- scope
- false
- false
-
-
- attribute
- false
- false
-
-
-
-
- encodeForJavaScript
- org.owasp.esapi.tags.EncodeForHTMLTag
- JSP
-
- scope
- false
- false
-
-
- attribute
- false
- false
-
-
-
-
- encodeForHTMLAttribute
- org.owasp.esapi.tags.EncodeForHTMLTag
- JSP
-
- scope
- false
- false
-
-
- attribute
- false
- false
-
-
-
-
- encodeForHTML
- org.owasp.esapi.tags.EncodeForHTMLTag
- JSP
-
- scope
- false
- false
-
-
- attribute
- false
- false
-
-
-
-
- encodeForVBScript
- org.owasp.esapi.tags.EncodeForVBScriptTag
- JSP
-
- scope
- false
- false
-
-
- attribute
- false
- false
-
-
-
-
\ No newline at end of file
diff --git a/resources/keystore b/resources/keystore
deleted file mode 100644
index 2a6bb23f7..000000000
Binary files a/resources/keystore and /dev/null differ
diff --git a/resources/owasp-esapi-dev.jks b/resources/owasp-esapi-dev.jks
new file mode 100644
index 000000000..6e71f9dcf
Binary files /dev/null and b/resources/owasp-esapi-dev.jks differ
diff --git a/resources/settings.xml b/resources/settings.xml
new file mode 100644
index 000000000..ba4fb8af3
--- /dev/null
+++ b/resources/settings.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ dist
+
+ ${basedir}/resources/owasp-esapi-dev.jks
+ owasp-esapi
+ changeme
+
+
+
+
\ No newline at end of file
diff --git a/resources/users.txt b/resources/users.txt
deleted file mode 100644
index 5a1c20b93..000000000
--- a/resources/users.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# This is the user file associated with the ESAPI library from http://www.owasp.org
-# accountName | hashedPassword | roles | locked | enabled | rememberToken | csrfToken | oldPasswordHashes | lastPasswordChangeTime | lastLoginTime | lastFailedLoginTime | expirationTime | failedLoginCount
-
diff --git a/scripts/README.txt b/scripts/README.txt
new file mode 100644
index 000000000..0e28bb29c
--- /dev/null
+++ b/scripts/README.txt
@@ -0,0 +1,16 @@
+This directory is for utilities used for building / packaging / releasing ESAPI.
+
+The scripts and configuration files in this directory are mostly used to create ESAPI release notes.
+(The 2 'mvnQuietTest' scripts are the major exceptions to that.)
+
+========================
+
+README.txt -- This readme file.
+mvnQuietTest.bat -- Run 'mvn test' from DOS cmd prompt with logSpecial output suppressed.
+mvnQuietTest.sh -- Run 'mvn test' from bash with logSpecial output suppressed.
+createVarsFile.sh -- Bash script to create a vars.2.x.y.z file that is 'sourced' by the 'newReleaseNotes.sh' script.
+esapi4java-core-TEMPLATE-release-notes.txt - Basic template used to create the new release notes file.
+newReleaseNotes.sh -- Bash script to create the release notes boillerplate from the provided release argument and the TEMPLATE file.
+vars.2.?.?.? -- File that is 'sourced' (as in "source ./filename") and used with newReleaseNotes.sh
+ and is associated with the release number associated with the file name.
+vars.template -- Template to construct the release specific vars files
diff --git a/scripts/createVarsFile.sh b/scripts/createVarsFile.sh
new file mode 100755
index 000000000..ad19a5747
--- /dev/null
+++ b/scripts/createVarsFile.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+# Purpose: Answer some questions and provide a new 'vars.' from 'vars.template' to use for creating release notes.
+
+prog="${0##*/}"
+
+function iprompt # prompt_message
+{
+ typeset ANS
+ read -p "$@ (y|n): " ANS
+ case "$ANS" in
+ [Yy]|[Yy][Ee][Ss]) return 0 ;;
+ *) return 1 ;;
+ esac
+}
+
+read -p "Enter release # for NEW ESAPI version you are doing release notes for: " VERSION
+if [[ -f "vars.$VERSION" ]]
+then
+ iprompt "File 'vars.$VERSION' already exists. Continuing will overwrite it. Continue?" || exit 1
+fi
+
+
+read -p "Enter release # for the PREVIOUS ESAPI version: " PREV_VERSION
+read -p "Enter (planned) release date of NEW / current version you are preparing in YYYY-MM-DD format: " YYYY_MM_DD_RELEASE_DATE
+read -p "Enter release date of PREVIOUS ESAPI version in YYYY-MM-DD format: " PREV_RELEASE_DATE
+
+echo You entered:
+echo =================================================
+echo VERSION=$VERSION
+echo PREV_VERSION=$PREV_VERSION
+echo YYYY_MM_DD_RELEASE_DATE=$YYYY_MM_DD_RELEASE_DATE
+echo PREV_RELEASE_DATE=$PREV_RELEASE_DATE
+echo =================================================
+echo
+
+if iprompt "Are ALL your previous answers correct?"
+then
+ # Create the new vars.${VERSION} file based on vars.template
+ sed -e "s/^VERSION/VERSION=$VERSION/" \
+ -e "s/^PREV_VERSION/PREV_VERSION=$PREV_VERSION/" \
+ -e "s/^YYYY_MM_DD_RELEASE_DATE/YYYY_MM_DD_RELEASE_DATE=$YYYY_MM_DD_RELEASE_DATE/" \
+ -e "s/^PREV_RELEASE_DATE/PREV_RELEASE_DATE=$PREV_RELEASE_DATE/" \
+ vars.template > "vars.$VERSION"
+else
+ echo "$prog: Aborting. Rerun the script to correct your answers." >&2
+ exit 1
+fi
diff --git a/scripts/esapi4java-core-TEMPLATE-release-notes.txt b/scripts/esapi4java-core-TEMPLATE-release-notes.txt
new file mode 100644
index 000000000..d03f64be6
--- /dev/null
+++ b/scripts/esapi4java-core-TEMPLATE-release-notes.txt
@@ -0,0 +1,151 @@
+@@@@ IMPORTANT: Be sure to 1) save in DOS text format, and 2) Delete this line and others starting with @@@@
+@@@@ Edit this file in vim with :set tw=0
+@@@@ Meant to be used with scripts/newReleaseNotes.sh and the 'vars.*' scripts there.
+@@@@ There are specific references to ESAPI 2.5.0.0 and other old releases in this file. Do NOT change the version #s. They are there for a reason.
+Release notes for ESAPI ${VERSION}
+ Release date: ${YYYY_MM_DD_RELEASE_DATE}
+ Project leaders:
+ -Kevin W. Wall
+ -Matt Seil
+
+Previous release: ESAPI ${PREV_VERSION}, ${PREV_RELEASE_DATE}
+
+
+Executive Summary: Important Things to Note for this Release
+------------------------------------------------------------
+@@@@ View previous release notes to see examples of what to put here. This is typical. YMMV.
+@@@@ Obviously, you should summarize any major changes / new features here.
+This is a patch release with the primary intent of updating some dependencies, some with known vulnerabilities. Details follow.
+@@@@ Provide a sentence or to
+
+Notes if you are not updating from the immediate previous release. release ${PREV_VERSION}:
+ * You need to read through the series of release notes FIRST, going in order.
+ * For example, if you were updating from an older ESAPI release (say, 2.3.0.0), you should go back and FIRST read all the subsequent release notes in turn. For instance, if you are currently on release 2.3.0.0 and upgrading to (say) release 2.x.y.z, you should MINIMALLY read the sections "Changes Requiring Special Attention" in each of the subsequent release notes. So, going from release 2.3.0.0 to 2.x.y.z, you should in turn, read:
+
+ esapi4java-core-2.4.0.0-release-notes.txt
+ esapi4java-core-2.5.0.0-release-notes.txt
+ esapi4java-core-2.5.1.0-release-notes.txt
+ esapi4java-core-2.5.2.0-release-notes.txt
+ ...etc., up through the current set of release notes...
+ esapi4java-core-2.x.y.z-release-notes.txt
+
+in that order. YOU HAVE BEEN WARNED!!! (These release notes are too large to put all this in a given document; very few read them thoroughly as it is.)
+
+If your SCA tool is reporting any CVE from a direct or transitive dependency in ESAPI, before reporting it as an GitHub issue, please make sure that you review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md. Please email us or contact us in our GitHub Discussions page if you have questions about this. See also the SECURITY.md file to report any security issues with ESAPI.
+
+You are encouraged to review the vulnerability analysis written up in https://github.com/ESAPI/esapi-java-legacy/blob/develop/Vulnerability-Summary.md and email us or contact us in our GitHub Discussions page if you have questions.
+
+
+=================================================================================================================
+
+Basic ESAPI facts
+-----------------
+
+ESAPI ${PREV_VERSION} release:
+@@@@ Look up the figures from the previous release notes.
+ #### Java source files
+ #### JUnit tests in #### Java test files
+
+ESAPI ${VERSION} release:
+@@@@ Count them and run 'mvn test' to get the # of tests.
+@@@@ Count Java source files by executing:
+@@@@ find src/main -type f -name '*.java' | wc -l
+ #### Java source files
+ #### JUnit tests in #### Java source files
+
+XXX GitHub Issues closed in this release, including those we've decided not to fix (marked 'wontfix' and 'falsepositive').
+(Reference: https://github.com/ESAPI/esapi-java-legacy/issues?q=is%3Aissue+state%3Aclosed+updated%3A%3E%3D${PREV_RELEASE_DATE})
+
+Issue # GitHub Issue Title
+----------------------------------------------------------------------------------------------
+@@@@ Capture issue #s and 1 line desription from above GitHub url
+@@@@ Insert here and massage until it looks pretty. Recommend alignment with spaces instead of tabs.
+
+-----------------------------------------------------------------------------
+
+ Changes Requiring Special Attention
+
+-----------------------------------------------------------------------------
+@@@@ NOTE any special notes here. Probably leave this one, but I would suggest noting additions BEFORE this.
+
+Important JDK Support Announcement
+* ESAPI 2.3.0.0 was the last Java release to support Java 7. ESAPI 2.4.0 requires using Java 8 or later. See the ESAPI 2.4.0.0 release notes (https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.4.0.0-release-notes.txt) for details as to the reason.
+ - This means if your project requires Java 7, you must use ESAPI 2.3.0.0 or earlier.
+
+Important ESAPI Logging Changes
+
+* Since ESAPI 2.5.0.0, support for logging directly via Log4J 1 has been removed. (This was two years after it haveing first been deprecated.) Thus, you only choice of ESAPI logging are
+ - java.util.logging (JUL), which as been the default since ESAPI 2.2.1.0.
+ * Set ESAPI.Logger=org.owasp.esapi.logging.java.JavaLogFactory in your ESAPI.properties file.
+ - SLF4J (which your choice of supported SLF4J logging implemmentation)
+ * Set ESAPI.Logger=org.owasp.esapi.logging.slf4j.Slf4JLogFactory in your ESAPI.properties file.
+* Logger configuration notes - If you are migrating from prior to ESAPI 2.2.1.1, you will need to update your ESAPI.properties file as logging-related configuration as per the ESAPI 2.2.1.1 release notes, which may be found at:
+ https://github.com/ESAPI/esapi-java-legacy/blob/develop/documentation/esapi4java-core-2.2.1.1-release-notes.txt#L39-L78
+
+If you use ESAPI 2.5.0.0 or later, you will get an ClassNotFoundException as the root cause if you still have your ESAPI.Logger property set to use Log4J because the org.owasp.esapi.logger.log4j.Log4JFactory class has been completely removed from the ESAPI jar. If you are dead set on continuing to use Log4J 1, you ought to be able to do so via SLF4J. The set up for Log4J 1 (which has not be tested), should be similar to configure ESAPI to use SLF4J with Log4J 2 as described here:
+ https://github.com/ESAPI/esapi-java-legacy/wiki/Using-ESAPI-with-SLF4J#slf4j-using-log4j-2x
+
+-----------------------------------------------------------------------------
+
+ Remaining Known Issues / Problems
+
+-----------------------------------------------------------------------------
+None known, other than the remaining open issues on GitHub.
+
+-----------------------------------------------------------------------------
+
+ Other changes in this release, some of which not tracked via GitHub issues
+
+-----------------------------------------------------------------------------
+
+* Changes since last release ${PREV_VERSION} and ${VERSION}, i.e., changes between ${PREV_RELEASE_DATE} and ${YYYY_MM_DD_RELEASE_DATE}).
+
+ Note: I am no longer going to provide the 'Developer Activity Report' that I used to this manually create in tabluar form. This is in part because I use to use 'mvn site' to assist with its creation, but neither the 'Developer Activiity' nor 'File Activity' sections of the 'mvn site' output is currently working.
+
+ That said, I don't care as this was always a major PITA and I think it had dubious value to start with.
+
+ Therefore, I am replacing it to a stock GitHub tag comparison of the current and previous release, which I can automate.
+
+ Please see,
+
+ https://github.com/ESAPI/esapi-java-legacy/compare/esapi-${PREVIOUS_VERSION}...esapi-${VERSION}
+
+ for details. It contains all the information that the previous 'Developer Activity Reports' did and then some.
+
+-----------------------------------------------------------------------------
+
+CHANGELOG: Create your own. May I suggest:
+
+ git log --stat --since=${PREV_RELEASE_DATE} --reverse --pretty=medium
+
+ which will show all the commits since just after the previous (${PREV_VERSION}) release.
+
+ Alternately, you can download the most recent ESAPI source and run
+
+ mvn site
+
+ which will create a CHANGELOG file named 'target/site/changelog.html'
+
+
+-----------------------------------------------------------------------------
+
+Direct and Transitive Runtime and Test Dependencies:
+
+ $ mvn -B dependency:tree
+@@@@ Include output from 'mvn -B dependency:tree' here
+@@@@ RECOMMENDATION: Run the above only after ensuring you are using the latest
+@@@@ plugins and dependencies so you only have to do this once.
+@@@@ Check via:
+@@@@ mvn -U versions:display-plugin-updates
+@@@@ mvn -U versions:display-dependency-updates
+@@@@ mvn -U versions:display-property-updates
+
+-----------------------------------------------------------------------------
+
+@@@@ Review these notes, especially the reference to the AntiSamy version information.
+Acknowledgments:
+ Another hat tip to Dave Wichers and the AntiSamy crew for promptly releasing AntiSamy 1.7.0. And thanks to Matt Seil, Jeremiah Stacey, and all the ESAPI users who make this worthwhile. This is for you.
+
+A special thanks to the ESAPI community from the ESAPI project co-leaders:
+ Kevin W. Wall (kwwall) <== The irresponsible party for these release notes!
+ Matt Seil (xeno6696)
diff --git a/scripts/mvnQuietTest.bat b/scripts/mvnQuietTest.bat
new file mode 100644
index 000000000..ccf76dcb1
--- /dev/null
+++ b/scripts/mvnQuietTest.bat
@@ -0,0 +1,8 @@
+@ECHO off
+rem Purpose: Run 'mvn test' with system property
+rem 'org.owasp.esapi.logSpecial.discard'
+rem set to true, so that all of the logSpecial output is suppressed.
+rem This reduces the total output of 'mvn test' by about 2000 or so
+rem lines.
+
+mvn -Dorg.owasp.esapi.logSpecial.discard=true test %*
diff --git a/scripts/mvnQuietTest.sh b/scripts/mvnQuietTest.sh
new file mode 100644
index 000000000..b66ca2913
--- /dev/null
+++ b/scripts/mvnQuietTest.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# Purpose: Run 'mvn test' with system property
+# 'org.owasp.esapi.logSpecial.discard'
+# set to true, so that all of the logSpecial output is suppressed.
+# This reduces the total output of 'mvn test' by about 2000 or so
+# lines.
+
+exec mvn -Dorg.owasp.esapi.logSpecial.discard=true test $@
diff --git a/scripts/newReleaseNotes.sh b/scripts/newReleaseNotes.sh
new file mode 100755
index 000000000..c9f3d351a
--- /dev/null
+++ b/scripts/newReleaseNotes.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Purpose: Provide an assistance towards writing new ESAPI release notes. Still a lot of manual editing though.
+#
+# Usage: ./newReleaseNotes.sh new_esapi_vers_#
+# Should be run from the 'scripts' directory.
+
+prog=${0##*/}
+template="esapi4java-core-TEMPLATE-release-notes.txt"
+
+newVers=${1?Missing new ESAPI version number}
+
+if [[ -r vars.${newVers} ]]
+then source vars.${newVers}
+else echo "$prog: Can't find vars.${newVers} to source. Did you forget to create it based on vars.template?" >&2
+ echo " Execute './createVarsFile.sh' from the 'scripts' directory to create vars.${newVers}." >&2
+ exit 1
+fi
+
+hereDocBanner="__________@@@@@___@@@@@__________"
+tmpfile="/tmp/relNotes.$$"
+trap "rm $tmpfile" EXIT
+
+if [[ -r $template ]]
+then
+ echo "#!/bin/bash" > $tmpfile
+ echo "source vars.${newVers}" >> $tmpfile
+ echo "set -o allexport" >> $tmpfile
+ echo "cat >esapi4java-core-${VERSION}-release-notes.txt <<${hereDocBanner}" >> $tmpfile
+ cat $template >> $tmpfile
+ echo "${hereDocBanner}" >> $tmpfile
+ echo "ls -l esapi4java-core-${VERSION}-release-notes.txt" >> $tmpfile
+ bash $tmpfile
+else echo "$prog: Can't find or read release notes template file $template" >&2
+ exit 1
+fi
+
+echo
+echo "Now move the file 'esapi4java-core-${VERSION}-release-notes.txt' to the 'documenation/' directory"
+echo "and finish editing it there. Be sure to remove all the instructional lines starting with @@@"
+echo "before committing it to GitHub."
diff --git a/scripts/vars.2.2.3.0 b/scripts/vars.2.2.3.0
new file mode 100644
index 000000000..7c43cccef
--- /dev/null
+++ b/scripts/vars.2.2.3.0
@@ -0,0 +1,13 @@
+# Do NOT edit this file directly. It will be created by the new newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.2.3.0
+
+# Previous ESAPI version
+PREV_VERSION=2.2.2.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2021-03-23
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2021-11-27
diff --git a/scripts/vars.2.2.3.1 b/scripts/vars.2.2.3.1
new file mode 100644
index 000000000..284e4f7fc
--- /dev/null
+++ b/scripts/vars.2.2.3.1
@@ -0,0 +1,13 @@
+# Do NOT edit this file directly. It will be created by the new newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.2.3.1
+
+# Previous ESAPI version
+PREV_VERSION=2.2.3.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2021-05-07
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2021-03-23
diff --git a/scripts/vars.2.3.0.0 b/scripts/vars.2.3.0.0
new file mode 100644
index 000000000..4695f1f6f
--- /dev/null
+++ b/scripts/vars.2.3.0.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.3.0.0
+
+# Previous ESAPI version
+PREV_VERSION=2.2.3.1
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2022-04-16
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2021-05-07
diff --git a/scripts/vars.2.4.0.0 b/scripts/vars.2.4.0.0
new file mode 100644
index 000000000..9e2f84ded
--- /dev/null
+++ b/scripts/vars.2.4.0.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.4.0.0
+
+# Previous ESAPI version
+PREV_VERSION=2.3.0.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2022-04-24
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2022-04-16
diff --git a/scripts/vars.2.5.0.0 b/scripts/vars.2.5.0.0
new file mode 100644
index 000000000..4d33532ea
--- /dev/null
+++ b/scripts/vars.2.5.0.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.5.0.0
+
+# Previous ESAPI version
+PREV_VERSION=2.4.0.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2022-07-20
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2022-04-24
diff --git a/scripts/vars.2.5.1.0 b/scripts/vars.2.5.1.0
new file mode 100644
index 000000000..ab72bcf74
--- /dev/null
+++ b/scripts/vars.2.5.1.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.5.1.0
+
+# Previous ESAPI version
+PREV_VERSION=2.5.0.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2022-11-27
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2022-07-20
diff --git a/scripts/vars.2.5.2.0 b/scripts/vars.2.5.2.0
new file mode 100644
index 000000000..750ab57b8
--- /dev/null
+++ b/scripts/vars.2.5.2.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.5.2.0
+
+# Previous ESAPI version
+PREV_VERSION=2.5.1.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2023-04-12
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2022-11-27
diff --git a/scripts/vars.2.5.3.0 b/scripts/vars.2.5.3.0
new file mode 100644
index 000000000..8fd04fa0a
--- /dev/null
+++ b/scripts/vars.2.5.3.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.5.3.0
+
+# Previous ESAPI version
+PREV_VERSION=2.5.2.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2023-11-24
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2023-04-12
diff --git a/scripts/vars.2.5.3.1 b/scripts/vars.2.5.3.1
new file mode 100644
index 000000000..0de9b1416
--- /dev/null
+++ b/scripts/vars.2.5.3.1
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.5.3.1
+
+# Previous ESAPI version
+PREV_VERSION=2.5.3.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2023-12-01
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2023-11-24
diff --git a/scripts/vars.2.5.4.0 b/scripts/vars.2.5.4.0
new file mode 100644
index 000000000..a5423489c
--- /dev/null
+++ b/scripts/vars.2.5.4.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.5.4.0
+
+# Previous ESAPI version
+PREV_VERSION=2.5.3.1
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2024-05-29
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2023-12-01
diff --git a/scripts/vars.2.5.5.0 b/scripts/vars.2.5.5.0
new file mode 100644
index 000000000..3f483d045
--- /dev/null
+++ b/scripts/vars.2.5.5.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.5.5.0
+
+# Previous ESAPI version
+PREV_VERSION=2.5.4.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2024-10-08
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2024-05-30
diff --git a/scripts/vars.2.6.0.0 b/scripts/vars.2.6.0.0
new file mode 100644
index 000000000..e44bce867
--- /dev/null
+++ b/scripts/vars.2.6.0.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.6.0.0
+
+# Previous ESAPI version
+PREV_VERSION=2.5.5.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2024-11-25
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2024-10-08
diff --git a/scripts/vars.2.6.1.0 b/scripts/vars.2.6.1.0
new file mode 100644
index 000000000..b067cb61f
--- /dev/null
+++ b/scripts/vars.2.6.1.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.6.1.0
+
+# Previous ESAPI version
+PREV_VERSION=2.6.0.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2025-05-19
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2024-11-25
diff --git a/scripts/vars.2.6.2.0 b/scripts/vars.2.6.2.0
new file mode 100644
index 000000000..244aeaf3b
--- /dev/null
+++ b/scripts/vars.2.6.2.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.6.2.0
+
+# Previous ESAPI version
+PREV_VERSION=2.6.1.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2025-06-02
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2025-05-19
diff --git a/scripts/vars.2.7.0.0 b/scripts/vars.2.7.0.0
new file mode 100644
index 000000000..829c1663c
--- /dev/null
+++ b/scripts/vars.2.7.0.0
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION=2.7.0.0
+
+# Previous ESAPI version
+PREV_VERSION=2.6.2.0
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE=2025-06-27
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE=2025-06-02
diff --git a/scripts/vars.template b/scripts/vars.template
new file mode 100644
index 000000000..7e127c7a3
--- /dev/null
+++ b/scripts/vars.template
@@ -0,0 +1,14 @@
+# Do NOT edit this file directly. It will be created by the new createVarsFile.sh script,
+# which should be run prior to the newReleaseNotes.sh script.
+
+# ESAPI (new / current) version
+VERSION
+
+# Previous ESAPI version
+PREV_VERSION
+
+# Release date of current version in yyyy-mm-dd format
+YYYY_MM_DD_RELEASE_DATE
+
+# Previous ESAPI release date in same format
+PREV_RELEASE_DATE
diff --git a/src/examples/README b/src/examples/README
new file mode 100644
index 000000000..126b6d85f
--- /dev/null
+++ b/src/examples/README
@@ -0,0 +1,37 @@
+README - This file you are now reading.
+java - Some Java examples.
+scripts - Some scripts to run that interact with the Java examples (but see
+ below). Purpose of script generally described at the beginning of
+ the file as a comment.
+
+
+
+NOTE: All scripts are meant to be run under *nix (or using something like
+ Cygwin or WSL under Windows) from under the 'scripts' directory using either
+ bash or KornShell
+
+ E.g., to compile the Java examples, execute:
+
+ $ cd scripts
+ $ chmod u+x *.sh # Required as some call each other.
+ $ # "Dot" the appropriate environment file. Either
+ $ # . ./setenv-zip.sh
+ $ # if ESAPI downloaded via zip file or
+ $ # . ./setenv-git.sh
+ $ # if ESAPI downloaded from a Git or Svn repository. For the
+ $ # example of this README file, we will assume it was
+ $ # downloaded via the zip file.
+ $ . ./setenv-zip.sh
+ $ sh ./compile.sh
+
+ You MUST be in the 'scripts' directory and execute the scripts as
+ "sh ./scriptname" and NOT as "sh scripts/scriptname".
+
+
+ Note that as delivered, these scripts are configured to run from
+ Eclipse or Maven as pulled directly from the ESAPI GitHub
+ repository or from pulled down from the zip file on GitHub at:
+ https://github.com/ESAPI/esapi-java-legacy/archive/refs/heads/develop.zip
+
+ If you get it from any other place, then all bets are off.
+ -- Kevin Wall
diff --git a/src/examples/java/DisplayEncryptedProperties.java b/src/examples/java/DisplayEncryptedProperties.java
new file mode 100644
index 000000000..ba0ce15ef
--- /dev/null
+++ b/src/examples/java/DisplayEncryptedProperties.java
@@ -0,0 +1,79 @@
+import java.io.*;
+import java.util.*;
+import org.owasp.esapi.EncryptedProperties;
+import org.owasp.esapi.errors.EncryptionException;
+import org.owasp.esapi.reference.crypto.DefaultEncryptedProperties;
+
+// Purpose: Short code snippet to show how to display encrypted property files
+// that were encrypted using ESAPI's EncryptedProperties class.
+//
+// Usage: java -classpath DisplayEncryptedProperties encryptedPropFileName
+// where is proper classpath, which minimally includes the esapi.jar.
+public class DisplayEncryptedProperties {
+
+ public DisplayEncryptedProperties() {
+ }
+
+ public void loadProperties(String encryptedPropertiesFilename,
+ Properties props )
+ throws IOException
+ {
+ EncryptedProperties loader = new DefaultEncryptedProperties();
+ loader.load( new FileInputStream(
+ new File( encryptedPropertiesFilename) ) );
+
+ System.out.println("\n\nLoaded encrypted properties file...");
+
+ try {
+ props.setProperty( "database.driver",
+ loader.getProperty( "database.driver" ) );
+ props.setProperty( "jdbc.url",
+ loader.getProperty( "jdbc.url" ) );
+ props.setProperty( "jdbc.username",
+ loader.getProperty( "jdbc.username" ) );
+ props.setProperty( "jdbc.password",
+ loader.getProperty( "jdbc.password" ) );
+ } catch( EncryptionException ee ) {
+ ee.printStackTrace();
+ }
+ }
+
+ public void showProperties(Properties props) throws Exception
+ {
+ System.out.println("");
+ String value = null;
+ value = props.getProperty( "database.driver");
+ System.out.println("database.driver=" + value);
+ value = props.getProperty( "jdbc.url");
+ System.out.println("jdbc.url=" + value);
+ value = props.getProperty( "jdbc.username");
+ System.out.println("jdbc.username=" + value);
+ value = props.getProperty( "jdbc.password");
+ System.out.println("jdbc.password=" + value);
+ }
+
+
+ public static void main(String[] args) {
+
+ try {
+ DisplayEncryptedProperties dep = new DisplayEncryptedProperties();
+ Properties props = new Properties();
+
+ String encryptedPropFname = "encrypted.properties";
+ if ( args.length == 1 ) {
+ encryptedPropFname = args[0];
+ } else {
+ System.err.println("Usage: java -classpath DisplayEncryptedProperties encryptedPropFileName");
+ System.exit(2);
+ }
+
+ dep.loadProperties(encryptedPropFname, props);
+ dep.showProperties(props);
+
+ } catch(Throwable t) {
+ System.err.println("Caught: " + t.getClass().getName() +
+ "; exception msg: " + t);
+ t.printStackTrace(System.err);
+ }
+ }
+}
diff --git a/src/examples/java/ESAPILogging.java b/src/examples/java/ESAPILogging.java
new file mode 100644
index 000000000..e2b1fc85c
--- /dev/null
+++ b/src/examples/java/ESAPILogging.java
@@ -0,0 +1,23 @@
+import org.owasp.esapi.ESAPI;
+import org.owasp.esapi.Logger;
+
+// Purpose: Short code snippet to show how ESAPI logging works.
+//
+// Usage: java -classpath ESAPILogging
+// where is proper classpath, which minimally includes the esapi.jar.
+public class ESAPILogging {
+
+ public static void main(String[] args) {
+
+ try {
+ Logger logger = ESAPI.getLogger("ESAPILogging");
+
+ logger.warning(Logger.SECURITY_FAILURE, "This is a warning.");
+ logger.always(Logger.SECURITY_AUDIT, "This is an audit log. It always logs.");
+ } catch(Throwable t) {
+ System.err.println("Caught: " + t.getClass().getName() +
+ "; exception msg: " + t);
+ t.printStackTrace(System.err);
+ }
+ }
+}
diff --git a/src/examples/java/PersistedEncryptedData.java b/src/examples/java/PersistedEncryptedData.java
new file mode 100644
index 000000000..1cabc04bb
--- /dev/null
+++ b/src/examples/java/PersistedEncryptedData.java
@@ -0,0 +1,184 @@
+import java.io.*;
+import org.owasp.esapi.*;
+import org.owasp.esapi.crypto.*;
+import org.owasp.esapi.errors.*;
+import org.owasp.esapi.codecs.*;
+import javax.servlet.ServletRequest;
+
+/** A slightly more complex example showing encoding encrypted data and writing
+ * it out to a file. This is very similar to the example in the ESAPI User
+ * Guide for "Symmetric Encryption in ESAPI 2.0".
+ */
+public class PersistedEncryptedData
+{
+ public enum OutputEncoding { raw, base64, hex }
+
+ private static final OutputEncoding dfltEncoding = OutputEncoding.raw;
+
+ private static boolean useBase64(OutputEncoding encoding) {
+ if ( encoding.equals(OutputEncoding.base64) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private static boolean useHex(OutputEncoding encoding) {
+ if ( encoding.equals(OutputEncoding.hex) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /** Take the specified plaintext, encrypt it, and then persist it
+ * to the specified file name according to the specified encoding.
+ *
+ * @param plaintext The {@code PlainText} we wish to encrypt.
+ * @param filemane Name of the file in which to store the encrypted, encoded data.
+ * @param encoding How it was encoded. Either base64, hex, or raw (meaning
+ * no encoding was used).
+ * @returns
+ * @throws EncryptionException
+ * @throws IOException
+ * @throws UnsupportedEncodingException
+ */
+ public static int persistEncryptedData(PlainText plaintext,
+ String filename,
+ OutputEncoding encoding)
+ throws EncryptionException, IOException, UnsupportedEncodingException
+ {
+ File serializedFile = new File(filename);
+ serializedFile.delete(); // Delete any old serialized file.
+
+ CipherText ct = ESAPI.encryptor().encrypt(plaintext);
+ byte[] serializedCiphertext = ct.asPortableSerializedByteArray();
+ String encodedStr = null;
+ byte[] serializedBytes = null;
+
+ if ( useBase64(encoding) ) {
+ encodedStr = Base64.encodeBytes(serializedCiphertext);
+ serializedBytes = encodedStr.getBytes("UTF-8");
+ } else if ( useHex(encoding) ) {
+ encodedStr = Hex.encode(serializedCiphertext, true);
+ serializedBytes = encodedStr.getBytes("UTF-8");
+ } else { // raw encoding
+ serializedBytes = serializedCiphertext;
+ }
+
+ FileOutputStream fos = new FileOutputStream(serializedFile);
+ fos.write( serializedBytes );
+ fos.close();
+ return serializedBytes.length;
+ }
+
+ /** Read the specified file name containing encoded encrypted data,
+ * and then decode it and decrypt it to retrieve the original plaintext.
+ *
+ * @param encryptedDataFilename Name of the file to read containing the
+ * encoded, encrypted data.
+ * @param encoding How it was encoded. Either base64, hex, or raw (meaning
+ * no encoding was used).
+ * @returns The original {@code PlainText} object.
+ * @throws EncryptionException
+ * @throws IOException
+ * @throws UnsupportedEncodingException
+ */
+ public static PlainText restorePlaintext(String encryptedDataFilename,
+ OutputEncoding encoding)
+ throws EncryptionException, IOException, UnsupportedEncodingException
+ {
+ File serializedFile = new File(encryptedDataFilename);
+ FileInputStream fis = new FileInputStream(serializedFile);
+ int avail = fis.available();
+ byte[] bytes = new byte[avail];
+ fis.read(bytes, 0, avail);
+ String encodedEncryptedData = new String(bytes, "UTF-8");
+
+ byte[] serializedCiphertext;
+
+ if ( useBase64(encoding) ) {
+ serializedCiphertext = Base64.decode(encodedEncryptedData);
+ } else if ( useHex(encoding) ) {
+ serializedCiphertext = Hex.decode(encodedEncryptedData);
+ } else {
+ // Raw encoding
+ serializedCiphertext = bytes;
+ }
+ System.out.println("Serialized ciphertext is " + serializedCiphertext.length +
+ " bytes.");
+
+ CipherText restoredCipherText =
+ CipherText.fromPortableSerializedBytes(serializedCiphertext);
+ fis.close();
+ PlainText plaintext = ESAPI.encryptor().decrypt(restoredCipherText);
+ return plaintext;
+ }
+
+ /**
+ * Usage: PersistedEncryptedData plaintext_string output_filename {raw|base64|hex}
+ */
+ public static void main(String[] args) {
+
+ try {
+ String plaintext = null;
+ String filename = null;
+ OutputEncoding encoding = dfltEncoding;
+
+ // NOTE: Ordinally, we would write to System.out for informational
+ // messages, but if something is not working (e.g., your
+ // classpath is missing a jar, etc.), it makes it a bit
+ // harder to debug because System.out is buffered and thus
+ // may not appear when exceptions are thrown.
+
+System.err.println("args.length=" + args.length);
+
+ if ( args.length == 3 ) {
+ plaintext = args[0];
+ filename = args[1];
+ if ( args[2].equalsIgnoreCase("raw") ) {
+ encoding = OutputEncoding.raw;
+ } else if ( args[2].equalsIgnoreCase("base64") ) {
+ encoding = OutputEncoding.base64;
+ } else if ( args[2].equalsIgnoreCase("hex") ) {
+ encoding = OutputEncoding.hex;
+ } else {
+ System.err.println(args[2] + ": Unrecognized encoding; using default.");
+ encoding = dfltEncoding;
+ }
+ } else {
+ System.err.println("Usage: java -classpath PersistedEncryptedData " +
+ "plaintext_string " +
+ "output_filename {raw|base64|hex}");
+ System.exit(2);
+ }
+
+ // Add file suffix, appropriate to encoding
+ filename = filename + "." + encoding;
+
+ System.err.println("Encrypting " + plaintext.length() +
+ " bytes of plaintext and storing in file '" +
+ filename + "'.");
+
+ int n = PersistedEncryptedData.persistEncryptedData(
+ new PlainText(plaintext),
+ filename, encoding);
+
+ System.err.println("Wrote " + n + " bytes to encrypted file " + filename + ".");
+ File f = new File(filename);
+ PlainText pt = PersistedEncryptedData.restorePlaintext(filename, encoding);
+
+ System.err.println("Plaintext recovered from encrypted file was: " + pt);
+ if ( pt.toString().equals( plaintext ) ) {
+ System.out.println("Plaintext recovered successfully.");
+ System.out.println("Recovered plaintext: " + pt);
+ } else {
+ System.out.println("Recovered plaintext differs from original plaintext.");
+ }
+ } catch(Throwable t) {
+ System.err.println("Caught: " + t.getClass().getName() +
+ "; exception msg: " + t);
+ t.printStackTrace(System.err);
+ }
+ }
+}
diff --git a/src/examples/scripts/compile.sh b/src/examples/scripts/compile.sh
new file mode 100755
index 000000000..eb5aa33e0
--- /dev/null
+++ b/src/examples/scripts/compile.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+if [[ -z "$esapi_classpath" ]]
+then
+ echo >&2 "esapi_classpath not set. Did you dot the appropriate env file?"
+ echo >&2 "If you are using ESAPI from downloaded zip file, use:"
+ echo >&2 " . ./setenv-zip.sh"
+ echo >&2 "If you are using ESAPI pulled from SVN repository, use:"
+ echo >&2 " . ./setenv-git.sh"
+ exit 1
+fi
+cd ../java
+set -x
+javac -classpath "$esapi_classpath" ${1:-*.java}
diff --git a/src/examples/scripts/encryptProperties.sh b/src/examples/scripts/encryptProperties.sh
new file mode 100755
index 000000000..7b09e3985
--- /dev/null
+++ b/src/examples/scripts/encryptProperties.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+# Create or display encrypted properties.
+#
+# Usage: encryptedProperties.sh {-display|-create} [encrypted_properties_filename]
+# You can use the file 'encrypted.properties' in this directory
+# as a sample if you so wish. That's what it defaults to.
+
+USAGE="Usage: encryptedProperties.sh {-display|-create} [encrypted_properties_filename]"
+
+if [[ -z "$esapi_classpath" ]]
+then
+ echo >&2 "esapi_classpath not set. Did you dot the appropriate env file?"
+ echo >&2 "If you are using ESAPI from downloaded zip file, use:"
+ echo >&2 " . ./setenv-zip.sh"
+ echo >&2 "If you are using ESAPI pulled from SVN repository, use:"
+ echo >&2 " . ./setenv-git.sh"
+ exit 1
+fi
+
+case $1 in
+-display|-create) action="$1" ;;
+*) echo "Missing '-display' or '-create' arg."; echo $USAGE; exit 2 ;;
+esac
+
+filename=${2:-encrypted.properties}
+case "$filename" in
+/*) ;;
+*) filename="$PWD/$filename" ;;
+esac
+
+if [[ -f "$filename" && "$action" == "-create" ]]
+then echo "Output file '$filename' already exists; will not overwrite."
+ echo "Remove manually if you want it overwritten."
+ exit 1
+elif [[ -f "$filename" && "$action" == "-display" ]]
+then
+ [[ ! -s "$filename" ]] && { echo "file has zero size"; exit 1; }
+else # File doesn't exist, so try to create it to see if we can write it.
+ > "$filename" || exit 1
+fi
+
+cd ../java
+# Here, we want to use the ESAPI.properties in $esapi_resources_test since
+# we know the Encryptor.MasterKey that it was encrypted with and we need
+# to decrypt with the same one. The one in $esapi_resources doesn't have
+# one set by default, and if 'setMasterKey.sh' is called first to create
+# that property, it will differ what was used in the 'encrypted.properties'
+# file.
+if [[ "$action" == "-display" ]]
+then
+ set -x
+ java -Dorg.owasp.esapi.resources="$esapi_resources_test" \
+ -classpath "$esapi_classpath" \
+ DisplayEncryptedProperties "$filename"
+else
+ echo
+ echo ======================= Instructions ======================
+ echo "When you see 'Enter key: ', enter the property name."
+ echo "When you see 'Enter value: ', enter the property value."
+ echo "The property value will be encrypted and the value will be in plaintext"
+ echo "and they will be placed in the specified output file."
+ echo "End entering key/value pairs by entering an empty key & value."
+ echo
+ echo "Using your TEST version of ESAPI.properties file: $esapi_resources_test/ESAPI.properties"
+ echo ===========================================================
+ echo
+ echo "Hit to continue..."; read GO
+ set -x
+ java -Dorg.owasp.esapi.resources="$esapi_resources_test" \
+ -Djava.util.logging.config.file="$esapi_resources/esapi-java-logging.properties" \
+ -classpath "$esapi_classpath" \
+ org.owasp.esapi.reference.crypto.DefaultEncryptedProperties "$filename" &&
+ echo "Output of encrypted properties in file: $filename"
+fi
diff --git a/src/examples/scripts/encrypted.properties b/src/examples/scripts/encrypted.properties
new file mode 100644
index 000000000..54b91117d
--- /dev/null
+++ b/src/examples/scripts/encrypted.properties
@@ -0,0 +1,6 @@
+#Encrypted Properties File
+#Sat Apr 24 22:48:37 EDT 2010
+jdbc.url=AAAAAAEytBoAAAEqnVoOoQAUQUVTL0NCQy9QS0NTNVBhZGRpbmcAgAAQABBnm1MbEbWLB/q+xTJAjtCvAAAAQD9JZlTKv78Dx8c2OQ6hJrvMpRz2YXuNPIXbKkartTPgG2Rljj0nwiFltdeYtXVkbpW62tvbQQddGNZo1E0NfzQAFNIbLlHoNLdGOnSzonvJL/xnGlGY
+database.driver=AAAAAAEytBoAAAEqnVWMrgAUQUVTL0NCQy9QS0NTNVBhZGRpbmcAgAAQABCDNOMJ+EeKtzHaAJuLikDcAAAAIBNgqefmRItecW16grynaqNH768VeEUraAUmGFB/PPWzABTmDDoPWg9DHOwRrvT4h5jouLGIfg\=\=
+jdbc.username=AAAAAAEytBoAAAEoMtoomAAUQUVTL0NCQy9QS0NTNVBhZGRpbmcAgAAQABAha165LauV/fMx6iY1OLDAAAAAINwPGRVoSKSyunLSE5HyjvEPrlTR+TRyiv6+M/4UtmFSABSRs7m648MkHV92GH0ToWRURjDRnA\=\=
+jdbc.password=AAAAAAEytBoAAAEoMtsy9wAUQUVTL0NCQy9QS0NTNVBhZGRpbmcAgAAQABAr1UdBfxmI+RxQmBqfQB9YAAAAIKiaF7vCiA5woJs90oZ/YAe4jGzwd+FZoUtfidJoGCthABTbotqgkU2Qt+9q2nXf6ut00pqQ4Q\=\=
diff --git a/src/examples/scripts/findjar.sh b/src/examples/scripts/findjar.sh
new file mode 100755
index 000000000..882c12b52
--- /dev/null
+++ b/src/examples/scripts/findjar.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Purpose: Find specified jar and provide full path name to it for use in
+# Java classpath.
+#
+############################################################################
+
+USAGE="Usage: ${0##*/} [-start starting_dir] jar_pattern"
+PROG=${0##*/}
+
+# Default starting directory is Maven2 repository under $HOME ...
+starting_dir=$HOME/.m2/repository
+
+# If we are on Cygwin on Windows, the Maven repo may be under $USERPROFILE.
+if [[ $(uname -o) == "Cygwin" && ! -d "$starting_dir" ]]
+then starting_dir="$(cygpath --unix ${USERPROFILE:-$HOME}/.m2/repository)"
+fi
+
+case "$1" in
+-start) shift; starting_dir="$1"; shift ;; # Expected to be right if provided
+-\?) echo "$USAGE" >&2; exit 2 ;;
+-*) echo "$PROG: Unknown option: $1; treating as a jar pattern." >&2 ;;
+esac
+
+jar_pattern="$1"
+case "$jar_pattern" in
+*.zip|*.jar) ;; # Suffix already present
+"") echo "$PROG: Missing jar pattern.\n$USAGE" >&2; exit 2 ;;
+*) jar_pattern="${jar_pattern}*.jar" ;;
+esac
+
+# echo "Starting location: $starting_dir" # DEBUG
+# echo "Jar pattern: $jar_pattern" # DEBUG
+if [[ -d "$starting_dir" ]]
+then
+ find "$starting_dir" -type f -name "$jar_pattern" -print |
+ egrep -v 'javadoc|sources'
+else
+ echo "$PROG: Can't find starting directory for Maven repo: $starting_dir" >&2
+ exit 1
+fi
diff --git a/src/examples/scripts/persistEncryptedData.sh b/src/examples/scripts/persistEncryptedData.sh
new file mode 100755
index 000000000..a63fce2c9
--- /dev/null
+++ b/src/examples/scripts/persistEncryptedData.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# Purpose: Persist some encrypted data by saving it to a file. Shows how
+# the serialization works. See ../java/PersistedEncryptedData.java
+# for details.
+# Usage: ./persistEncryptedData.sh plaintext_string output_file {hex|base64|raw}
+# The last argument refers to how the encrypted data will be encoded.
+# The output file name will also be named with this as the file
+# suffix.
+##############################################################################
+
+if [[ -z "$esapi_classpath" ]]
+then
+ echo >&2 "esapi_classpath not set. Did you dot the appropriate env file?"
+ echo >&2 "If you are using ESAPI from downloaded zip file, use:"
+ echo >&2 " . ./setenv-zip.sh"
+ echo >&2 "If you are using ESAPI pulled from SVN repository, use:"
+ echo >&2 " . ./setenv-git.sh"
+ exit 1
+fi
+
+cd ../java
+# Since this is just an illustration, we will use the test ESAPI.properties in
+# $esapi_resources_test. That way, it won't matter if the user has neglected
+# to run the 'setMasterKey.sh' example before running this one.
+echo "Using your TEST version of ESAPI.properties file: $esapi_resources_test/ESAPI.properties"
+set -x
+java -Dorg.owasp.esapi.resources="$esapi_resources_test" \
+ -Djava.util.logging.config.file="$esapi_resources/esapi-java-logging.properties" \
+ -ea -classpath "$esapi_classpath" \
+ PersistedEncryptedData "$@"
diff --git a/src/examples/scripts/runClass.sh b/src/examples/scripts/runClass.sh
new file mode 100755
index 000000000..c8fbf4b8e
--- /dev/null
+++ b/src/examples/scripts/runClass.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+# Purpose: Run an example class in ../java directory
+
+if [[ -z "$esapi_classpath" ]]
+then
+ echo >&2 "esapi_classpath not set. Did you dot the appropriate env file?"
+ echo >&2 "If you are using ESAPI from downloaded zip file, use:"
+ echo >&2 " . ./setenv-zip.sh"
+ echo >&2 "If you are using ESAPI pulled from SVN repository, use:"
+ echo >&2 " . ./setenv-git.sh"
+ exit 1
+fi
+
+cd ../java
+className=${1%.class}
+shift
+if [[ ! -r ${className}.class ]]
+then echo >2&1 "Can't find class file: ${className}.class"
+ exit 1
+fi
+echo "Using your TEST version of ESAPI.properties file: ${esapi_resources_test:?}/ESAPI.properties"
+echo
+set -x
+java -Dorg.owasp.esapi.resources="$esapi_resources_test" \
+ -Djava.util.logging.config.file="$esapi_resources/esapi-java-logging.properties" \
+ -classpath "$esapi_classpath" \
+ ${className} "$@"
diff --git a/src/examples/scripts/setMasterKey.sh b/src/examples/scripts/setMasterKey.sh
new file mode 100755
index 000000000..74b1fa3ae
--- /dev/null
+++ b/src/examples/scripts/setMasterKey.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+if [ -z "$esapi_classpath" ]
+then
+ echo >&2 "esapi_classpath not set. Did you dot the appropriate env file?"
+ echo >&2 "If you are using ESAPI from downloaded zip file, use:"
+ echo >&2 " . ./setenv-zip.sh"
+ echo >&2 "If you are using ESAPI pulled from Git or Svn repository, use:"
+ echo >&2 " . ./setenv-git.sh"
+ exit 1
+fi
+
+cd ../java
+echo "This will generate the properties Encryptor.MasterKey and Encryptor.MasterSalt"
+echo "which you will have to paste into your production ESAPI.properties file."
+echo
+echo "Do NOT copy those properties from your TEST ESAPI.properties as they are"
+echo "the same for everyone and therefore are not secret."
+echo
+echo "Your PRODUCTION version of ESAPI.properties file: $esapi_resources/ESAPI.properties"
+echo "Hit to continue..."; read GO
+echo
+set -x
+# This should use the real ESAPI.properties in $esapi_resources that does
+# not yet have Encryptor.MasterKey and Encryptor.MasterSalt yet set.
+java -Dorg.owasp.esapi.resources="$esapi_resources" \
+ -Djava.util.logging.config.file="$esapi_resources/esapi-java-logging.properties" \
+ -classpath "$esapi_classpath" \
+ org.owasp.esapi.reference.crypto.JavaEncryptor "$@"
diff --git a/src/examples/scripts/setenv-git.sh b/src/examples/scripts/setenv-git.sh
new file mode 100755
index 000000000..99b9a86f8
--- /dev/null
+++ b/src/examples/scripts/setenv-git.sh
@@ -0,0 +1,40 @@
+#/bin/bash
+# Purpose: Use to set up environment to compile and run examples if ESAPI
+# downloaded from an Svn or Git repository.
+# Usage: From csh, tcsh:
+# $ source ./setenv-git.sh
+# From most other *nix shells:
+# $ . ./setenv-git.sh
+#
+# where '$' represents the shell command line prompt.
+###########################################################################
+
+esapi_resources="$(\cd ../../../configuration/esapi >&- 2>&- && pwd)"
+esapi_resources_test="$(\cd ../../../src/test/resources/esapi >&- 2>&- && pwd)"
+
+
+# IMPORTANT NOTE: These dependency versions may need updated. Should match
+# what is in ESAPI's pom.xml.
+esapi_classpath=".:\
+../../../target/classes:\
+$(ls ../../../target/esapi-*.jar 2>&- || echo .):\
+$(./findjar.sh commons-fileupload-1.5.jar):\
+$(./findjar.sh servlet-api-2.4.jar)"
+
+if [[ ! -r "$esapi_resources"/ESAPI.properties ]]
+then echo >&2 "setenv-git.sh: Can't read ESAPI.properties in $esapi_resources"
+ return 1 # Don't use 'exit' here or it will kill their current shell.
+fi
+
+if [[ ! -r "$esapi_resources_test"/ESAPI.properties ]]
+then echo >&2 "setenv-git.sh: Can't read ESAPI.properties in $esapi_resources_test"
+ return 1 # Don't use 'exit' here or it will kill their current shell.
+fi
+
+echo ############################################################
+echo "esapi_resources=$esapi_resources"
+echo "esapi_resources_test=$esapi_resources_test"
+echo "esapi_classpath=$esapi_classpath"
+echo ############################################################
+
+export esapi_classpath esapi_resources esapi_resources_test
diff --git a/src/examples/scripts/setenv-svn.sh b/src/examples/scripts/setenv-svn.sh
new file mode 100755
index 000000000..a60a498cf
--- /dev/null
+++ b/src/examples/scripts/setenv-svn.sh
@@ -0,0 +1,40 @@
+#/bin/bash
+# Purpose: Use to set up environment to compile and run examples if ESAPI
+# downloaded from the Svn or Git repository.
+# Usage: From csh, tcsh:
+# $ source ./setenv-svn.sh
+# From most other *nix shells:
+# $ . ./setenv-svn.sh
+#
+# where '$' represents the shell command line prompt.
+###########################################################################
+
+# IMPORTANT NOTE: These dependency versions may need updated. Should match
+# what is in ESAPI's pom.xml.
+esapi_classpath=".:\
+../../../target/classes:\
+$(ls ../../../target/esapi-*.jar 2>&- || echo .):\
+$(./findjar.sh commons-fileupload-1.4.jar):\
+$(./findjar.sh servlet-api-3.1.0.jar)"
+
+esapi_resources="$(\cd ../../../configuration/esapi >&- 2>&- && pwd)"
+esapi_resources_test="$(\cd ../../../src/test/resources/esapi >&- 2>&- && pwd)"
+
+
+if [[ ! -r "$esapi_resources"/ESAPI.properties ]]
+then echo >&2 "setenv-svn.sh: Can't read ESAPI.properties in $esapi_resources"
+ return 1 # Don't use 'exit' here or it will kill their current shell.
+fi
+
+if [[ ! -r "$esapi_resources_test"/ESAPI.properties ]]
+then echo >&2 "setenv-svn.sh: Can't read ESAPI.properties in $esapi_resources_test"
+ return 1 # Don't use 'exit' here or it will kill their current shell.
+fi
+
+echo ############################################################
+echo "esapi_resources=$esapi_resources"
+echo "esapi_resources_test=$esapi_resources_test"
+echo "esapi_classpath=$esapi_classpath"
+echo ############################################################
+
+export esapi_classpath esapi_resources esapi_resources_test
diff --git a/src/examples/scripts/setenv-zip.sh b/src/examples/scripts/setenv-zip.sh
new file mode 100755
index 000000000..8bf714c97
--- /dev/null
+++ b/src/examples/scripts/setenv-zip.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Purpose: Use to set up environment to compile and run examples if ESAPI
+# downloaded as a zip file.
+# Usage: From csh, tcsh:
+# $ source ./setenv-zip.sh
+# From most other *nix shells:
+# $ . ./setenv-zip.sh
+#
+# where '$' represents the shell command line prompt.
+###########################################################################
+
+esapi_resources="$(\cd ../../../configuration/esapi >&- 2>&- && pwd)"
+esapi_resources_test="$(\cd ../../../src/test/resources/esapi >&- 2>&- && pwd)"
+
+# Here we don't look for the specific versions of the dependent libraries
+# since the specific version of the library is delivered as part of the
+# ESAPI zip file. In this manner, we do not have to update this if these
+# versions change.
+esapi_classpath=".:\
+$(ls ../../../esapi*.jar):\
+$(./findjar.sh -start ../../../libs commons-fileupload-*.jar):\
+$(./findjar.sh -start ../../../libs servlet-api-*.jar)"
+
+if [[ ! -r "$esapi_resources"/ESAPI.properties ]]
+then echo >&2 "setenv-zip.sh: Can't read ESAPI.properties in $esapi_resources"
+ return 1 # Don't use 'exit' here or it will kill their current shell.
+fi
+
+if [[ ! -r "$esapi_resources_test"/ESAPI.properties ]]
+then echo >&2 "setenv-zip.sh: Can't read ESAPI.properties in $esapi_resources_test"
+ return 1 # Don't use 'exit' here or it will kill their current shell.
+fi
+
+
+echo ############################################################
+echo "esapi_resources=$esapi_resources"
+echo "esapi_resources_test=$esapi_resources_test"
+echo "esapi_classpath=$esapi_classpath"
+echo ############################################################
+
+export esapi_classpath esapi_resources esapi_resources_test
diff --git a/src/main/assembly/dist.xml b/src/main/assembly/dist.xml
new file mode 100644
index 000000000..676039c82
--- /dev/null
+++ b/src/main/assembly/dist.xml
@@ -0,0 +1,53 @@
+
+ dist
+
+ zip
+ tar.gz
+
+ false
+ true
+
+
+
+ LICENSE*
+
+
+
+ target
+
+
+ *.jar
+
+
+ *-sources.jar
+ *-javadoc.jar
+
+
+
+ src
+ src
+
+
+ documentation
+ documentation
+
+
+ configuration
+ configuration
+
+ esapi/**/*
+ properties/**/*
+
+
+
+
+
+
+ compile
+ libs
+ false
+
+
+
diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..254272e1c
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/src/main/java/org/owasp/esapi/AccessControlRule.java b/src/main/java/org/owasp/esapi/AccessControlRule.java
new file mode 100644
index 000000000..51458ff3b
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/AccessControlRule.java
@@ -0,0 +1,8 @@
+package org.owasp.esapi;
+
+
+public interface AccessControlRule
{
+ void setPolicyParameters(P policyParameter);
+ P getPolicyParameters();
+ boolean isAuthorized(R runtimeParameter) throws Exception;
+}
diff --git a/src/main/java/org/owasp/esapi/AccessController.java b/src/main/java/org/owasp/esapi/AccessController.java
new file mode 100644
index 000000000..ad23d14c7
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/AccessController.java
@@ -0,0 +1,359 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007-2019 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import org.owasp.esapi.errors.AccessControlException;
+
+/**
+ * The AccessController interface defines a set of methods that can be used in a wide variety of applications to
+ * enforce access control. In most applications, access control must be performed in multiple different locations across
+ * the various application layers. This class provides access control for URLs, business functions, data, services, and
+ * files.
+ *
+ * The implementation of this interface will need to access the current User object (from Authenticator.getCurrentUser())
+ * to determine roles or permissions. In addition, the implementation
+ * will also need information about the resources that are being accessed. Using the user information and the resource
+ * information, the implementation should return an access control decision.
+ *
+ * Implementers are encouraged to implement the ESAPI access control rules, like assertAuthorizedForFunction() using
+ * existing access control mechanisms, such as methods like isUserInRole() or hasPrivilege(). While powerful,
+ * methods like isUserInRole() can be confusing for developers, as users may be in multiple roles or possess multiple
+ * overlapping privileges. Direct use of these finer grained access control methods encourages the use of complex boolean
+ * tests throughout the code, which can easily lead to developer mistakes.
+ *
+ * The point of the ESAPI access control interface is to centralize access control logic behind easy to use calls like
+ * assertAuthorized() so that access control is easy to use and easy to verify. Here is an example of a very
+ * straightforward to implement, understand, and verify ESAPI access control check:
+ *
+ *
+ *
+ * Note that in the user interface layer, access control checks can be used to control whether particular controls are
+ * rendered or not. These checks are supposed to fail when an unauthorized user is logged in, and do not represent
+ * attacks. Remember that regardless of how the user interface appears, an attacker can attempt to invoke any business
+ * function or access any data in your application. Therefore, access control checks in the user interface should be
+ * repeated in both the business logic and data layers.
+ *
+ *
+ *
+ * @author Mike H. Fauzy (mike.fauzy@aspectsecurity.com) ESAPI v1.6-
+ * @author Jeff Williams (jeff.williams@aspectsecurity.com) ESAPI v0-1.5
+ */
+public interface AccessController {
+
+ /**
+ * isAuthorized executes the AccessControlRule
+ * that is identified by key and listed in the
+ * resources/ESAPI-AccessControlPolicy.xml file. It returns
+ * true if the AccessControlRule decides that the operation
+ * should be allowed. Otherwise, it returns false. Any exception thrown by
+ * the AccessControlRule must result in false. If
+ * key does not map to an AccessControlRule, then
+ * false is returned.
+ *
+ * Developers should call isAuthorized to control execution flow. For
+ * example, if you want to decide whether to display a UI widget in the
+ * browser using the same logic that you will use to enforce permissions
+ * on the server, then isAuthorized is the method that you want to use.
+ *
+ * Typically, assertAuthorized should be used to enforce permissions on the
+ * server.
+ *
+ * @param key key maps to
+ * <AccessControlPolicy><AccessControlRules>
+ * <AccessControlRule name="key"
+ * @param runtimeParameter runtimeParameter can contain anything that
+ * the AccessControlRule needs from the runtime system.
+ * @return Returns true if and only if the AccessControlRule specified
+ * by key exists and returned true.
+ * Otherwise returns false
+ */
+ boolean isAuthorized(Object key, Object runtimeParameter);
+
+ /**
+ * assertAuthorized executes the AccessControlRule
+ * that is identified by key and listed in the
+ * resources/ESAPI-AccessControlPolicy.xml file. It does
+ * nothing if the AccessControlRule decides that the operation
+ * should be allowed. Otherwise, it throws an
+ * org.owasp.esapi.errors.AccessControlException. Any exception
+ * thrown by the AccessControlRule will also result in an
+ * AccesControlException. If key does not map to
+ * an AccessControlRule, then an AccessControlException
+ * is thrown.
+ *
+ * Developers should call {@code assertAuthorized} to enforce privileged access to
+ * the system. It should be used to answer the question: "Should execution
+ * continue." Ideally, the call to assertAuthorized should
+ * be integrated into the application framework so that it is called
+ * automatically.
+ *
+ * @param key key maps to
+ * <AccessControlPolicy><AccessControlRules>
+ * <AccessControlRule name="key"
+ * @param runtimeParameter runtimeParameter can contain anything that
+ * the AccessControlRule needs from the runtime system.
+ */
+ void assertAuthorized(Object key, Object runtimeParameter)
+ throws AccessControlException;
+
+
+
+
+ /*** Below this line has been deprecated as of ESAPI 1.6 ***/
+
+
+
+
+ /**
+ * Checks if the current user is authorized to access the referenced URL. Generally, this method should be invoked in the
+ * application's controller or a filter as follows:
+ *
+ *
+ * The implementation of this method should call assertAuthorizedForURL(String url), and if an AccessControlException is
+ * not thrown, this method should return true. This way, if the user is not authorized, false would be returned, and the
+ * exception would be logged.
+ *
+ * @param url
+ * the URL as returned by request.getRequestURI().toString()
+ *
+ * @return
+ * true, if is authorized for URL
+ */
+ @Deprecated
+ boolean isAuthorizedForURL(String url);
+
+ /**
+ * Checks if the current user is authorized to access the referenced function.
+ *
+ * The implementation of this method should call assertAuthorizedForFunction(String functionName), and if an
+ * AccessControlException is not thrown, this method should return true.
+ *
+ * @param functionName
+ * the name of the function
+ *
+ * @return
+ * true, if is authorized for function
+ */
+ @Deprecated
+ boolean isAuthorizedForFunction(String functionName);
+
+
+ /**
+ * Checks if the current user is authorized to access the referenced data, represented as an Object.
+ *
+ * The implementation of this method should call assertAuthorizedForData(String action, Object data), and if an
+ * AccessControlException is not thrown, this method should return true.
+ *
+ * @param action
+ * The action to verify for an access control decision, such as a role, or an action being performed on the object
+ * (e.g., Read, Write, etc.), or the name of the function the data is being passed to.
+ *
+ * @param data
+ * The actual object or object identifier being accessed or a reference to the object being accessed.
+ *
+ * @return
+ * true, if is authorized for the data
+ */
+ @Deprecated
+ boolean isAuthorizedForData(String action, Object data);
+
+ /**
+ * Checks if the current user is authorized to access the referenced file.
+ *
+ * The implementation of this method should call assertAuthorizedForFile(String filepath), and if an AccessControlException
+ * is not thrown, this method should return true.
+ *
+ * @param filepath
+ * the path of the file to be checked, including filename
+ *
+ * @return
+ * true, if is authorized for the file
+ */
+ @Deprecated
+ boolean isAuthorizedForFile(String filepath);
+
+ /**
+ * Checks if the current user is authorized to access the referenced service. This can be used in applications that
+ * provide access to a variety of back end services.
+ *
+ * The implementation of this method should call assertAuthorizedForService(String serviceName), and if an
+ * AccessControlException is not thrown, this method should return true.
+ *
+ * @param serviceName
+ * the service name
+ *
+ * @return
+ * true, if is authorized for the service
+ */
+ @Deprecated
+ boolean isAuthorizedForService(String serviceName);
+
+ /**
+ * Checks if the current user is authorized to access the referenced URL. The implementation should allow
+ * access to be granted to any part of the URL. Generally, this method should be invoked in the
+ * application's controller or a filter as follows:
+ *
+ *
+ * This method throws an AccessControlException if access is not authorized, or if the referenced URL does not exist.
+ * If the User is authorized, this method simply returns.
+ *
+ * Specification: The implementation should do the following:
+ *
+ *
Check to see if the resource exists and if not, throw an AccessControlException
+ *
Use available information to make an access control decision
+ *
+ *
Ideally, this policy would be data driven
+ *
You can use the current User, roles, data type, data name, time of day, etc.
+ *
Access control decisions must deny by default
+ *
+ *
If access is not permitted, throw an AccessControlException with details
+ *
+ * @param url
+ * the URL as returned by request.getRequestURI().toString()
+ *
+ * @throws AccessControlException
+ * if access is not permitted
+ */
+ @Deprecated
+ void assertAuthorizedForURL(String url) throws AccessControlException;
+
+ /**
+ * Checks if the current user is authorized to access the referenced function. The implementation should define the
+ * function "namespace" to be enforced. Choosing something simple like the class name of action classes or menu item
+ * names will make this implementation easier to use.
+ *
+ * This method throws an AccessControlException if access is not authorized, or if the referenced function does not exist.
+ * If the User is authorized, this method simply returns.
+ *
+ * Specification: The implementation should do the following:
+ *
+ *
Check to see if the function exists and if not, throw an AccessControlException
+ *
Use available information to make an access control decision
+ *
+ *
Ideally, this policy would be data driven
+ *
You can use the current User, roles, data type, data name, time of day, etc.
+ *
Access control decisions must deny by default
+ *
+ *
If access is not permitted, throw an AccessControlException with details
+ *
+ *
+ * @param functionName
+ * the function name
+ *
+ * @throws AccessControlException
+ * if access is not permitted
+ */
+ @Deprecated
+ void assertAuthorizedForFunction(String functionName) throws AccessControlException;
+
+
+ /**
+ * Checks if the current user is authorized to access the referenced data. This method simply returns if access is authorized.
+ * It throws an AccessControlException if access is not authorized, or if the referenced data does not exist.
+ *
+ * Specification: The implementation should do the following:
+ *
+ *
Check to see if the resource exists and if not, throw an AccessControlException
+ *
Use available information to make an access control decision
+ *
+ *
Ideally, this policy would be data driven
+ *
You can use the current User, roles, data type, data name, time of day, etc.
+ *
Access control decisions must deny by default
+ *
+ *
If access is not permitted, throw an AccessControlException with details
+ *
+ *
+ * @param action
+ * The action to verify for an access control decision, such as a role, or an action being performed on the object
+ * (e.g., Read, Write, etc.), or the name of the function the data is being passed to.
+ *
+ * @param data
+ * The actual object or object identifier being accessed or a reference to the object being accessed.
+ *
+ * @throws AccessControlException
+ * if access is not permitted
+ */
+ @Deprecated
+ void assertAuthorizedForData(String action, Object data) throws AccessControlException;
+
+ /**
+ * Checks if the current user is authorized to access the referenced file. The implementation should validate and canonicalize the
+ * input to be sure the filepath is not malicious.
+ *
+ * This method throws an AccessControlException if access is not authorized, or if the referenced File does not exist.
+ * If the User is authorized, this method simply returns.
+ *
+ * Specification: The implementation should do the following:
+ *
+ *
Check to see if the File exists and if not, throw an AccessControlException
+ *
Use available information to make an access control decision
+ *
+ *
Ideally, this policy would be data driven
+ *
You can use the current User, roles, data type, data name, time of day, etc.
+ *
Access control decisions must deny by default
+ *
+ *
If access is not permitted, throw an AccessControlException with details
+ *
+ *
+ * @param filepath
+ * Path to the file to be checked
+ * @throws AccessControlException if access is denied
+ */
+ @Deprecated
+ void assertAuthorizedForFile(String filepath) throws AccessControlException;
+
+ /**
+ * Checks if the current user is authorized to access the referenced service. This can be used in applications that
+ * provide access to a variety of backend services.
+ *
+ * This method throws an AccessControlException if access is not authorized, or if the referenced service does not exist.
+ * If the User is authorized, this method simply returns.
+ *
+ * Specification: The implementation should do the following:
+ *
+ *
Check to see if the service exists and if not, throw an AccessControlException
+ *
Use available information to make an access control decision
+ *
+ *
Ideally, this policy would be data driven
+ *
You can use the current User, roles, data type, data name, time of day, etc.
+ *
Access control decisions must deny by default
+ *
+ *
If access is not permitted, throw an AccessControlException with details
+ *
+ *
+ * @param serviceName
+ * the service name
+ *
+ * @throws AccessControlException
+ * if access is not permitted
+ */
+ @Deprecated
+ void assertAuthorizedForService(String serviceName) throws AccessControlException;
+
+}
diff --git a/src/main/java/org/owasp/esapi/AccessReferenceMap.java b/src/main/java/org/owasp/esapi/AccessReferenceMap.java
new file mode 100644
index 000000000..5f7e4e73c
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/AccessReferenceMap.java
@@ -0,0 +1,176 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import org.owasp.esapi.errors.AccessControlException;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.Set;
+
+
+/**
+ * The AccessReferenceMap interface is used to map from a set of internal
+ * direct object references to a set of indirect references that are safe to
+ * disclose publicly. This can be used to help protect database keys,
+ * filenames, and other types of direct object references. As a rule, developers
+ * should not expose their direct object references as it enables attackers to
+ * attempt to manipulate them.
+ *
+ * Indirect references are handled as strings, to facilitate their use in HTML.
+ * Implementations can generate simple integers or more complicated random
+ * character strings as indirect references. Implementations should probably add
+ * a constructor that takes a list of direct references.
+ *
+ * Note that in addition to defeating all forms of parameter tampering attacks,
+ * there is a side benefit of the AccessReferenceMap. Using random strings as indirect object
+ * references, as opposed to simple integers makes it impossible for an attacker to
+ * guess valid identifiers. So if per-user AccessReferenceMaps are used, then request
+ * forgery (CSRF) attacks will also be prevented.
+ *
+ *
+ * Set fileSet = new HashSet();
+ * fileSet.addAll(...); // add direct references (e.g. File objects)
+ * AccessReferenceMap map = new AccessReferenceMap( fileSet );
+ * // store the map somewhere safe - like the session!
+ * String indRef = map.getIndirectReference( file1 );
+ * String href = "http://www.aspectsecurity.com/esapi?file=" + indRef );
+ * ...
+ * // if the indirect reference doesn't exist, it's likely an attack
+ * // getDirectReference throws an AccessControlException
+ * // you should handle as appropriate
+ * String indref = request.getParameter( "file" );
+ * File file = (File)map.getDirectReference( indref );
+ *
+ *
+ *
+ *
+ * @author Jeff Williams (jeff.williams@aspectsecurity.com)
+ * @author Chris Schmidt (chrisisbeef@gmail.com)
+ */
+public interface AccessReferenceMap extends Serializable {
+
+ /**
+ * Get an iterator through the direct object references. No guarantee is made as
+ * to the order of items returned.
+ *
+ * @return the iterator
+ */
+ Iterator iterator();
+
+ /**
+ * Get a safe indirect reference to use in place of a potentially sensitive
+ * direct object reference. Developers should use this call when building
+ * URL's, form fields, hidden fields, etc... to help protect their private
+ * implementation information.
+ *
+ * @param directReference
+ * the direct reference
+ *
+ * @return
+ * the indirect reference
+ */
+ K getIndirectReference(T directReference);
+
+ /**
+ * Get the original direct object reference from an indirect reference.
+ * Developers should use this when they get an indirect reference from a
+ * request to translate it back into the real direct reference. If an
+ * invalid indirect reference is requested, then an AccessControlException is
+ * thrown.
+ *
+ * If a type is implied the requested object will be cast to that type, if the
+ * object is not of the requested type, a AccessControlException will be thrown to
+ * the caller.
+ *
+ * For example:
+ *
+ *
+ * Will never throw a AccessControlException as long as the object exists. If you are
+ * unsure of the object type of that an indirect reference references you should get
+ * the uncast object and test for type in the calling code.
+ *
+ *
+ * @param indirectReference
+ * the indirect reference
+ *
+ * @return
+ * the direct reference
+ *
+ * @throws AccessControlException
+ * if no direct reference exists for the specified indirect reference
+ * @throws ClassCastException
+ * if the implied type is not the same as the referenced object type
+ */
+ T getDirectReference(K indirectReference) throws AccessControlException;
+
+ /**
+ * Adds a direct reference to the AccessReferenceMap, then generates and returns
+ * an associated indirect reference.
+ *
+ * @param direct
+ * the direct reference
+ *
+ * @return
+ * the corresponding indirect reference
+ */
+ K addDirectReference(T direct);
+
+ /**
+ * Removes a direct reference and its associated indirect reference from the AccessReferenceMap.
+ *
+ * @param direct
+ * the direct reference to remove
+ *
+ * @return
+ * the corresponding indirect reference
+ *
+ * @throws AccessControlException
+ * if the reference does not exist.
+ */
+ K removeDirectReference(T direct) throws AccessControlException;
+
+ /**
+ * Updates the access reference map with a new set of direct references, maintaining
+ * any existing indirect references associated with items that are in the new list.
+ * New indirect references could be generated every time, but that
+ * might mess up anything that previously used an indirect reference, such
+ * as a URL parameter.
+ *
+ * @param directReferences
+ * a Set of direct references to add
+ */
+ void update(Set directReferences);
+}
diff --git a/src/main/java/org/owasp/esapi/Authenticator.java b/src/main/java/org/owasp/esapi/Authenticator.java
new file mode 100644
index 000000000..4e83903d5
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/Authenticator.java
@@ -0,0 +1,345 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import org.owasp.esapi.errors.AuthenticationException;
+import org.owasp.esapi.errors.EncryptionException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Set;
+
+
+/**
+ * The Authenticator interface defines a set of methods for generating and
+ * handling account credentials and session identifiers. The goal of this
+ * interface is to encourage developers to protect credentials from disclosure
+ * to the maximum extent possible.
+ *
+ * One possible implementation relies on the use of a thread local variable to
+ * store the current user's identity. The application is responsible for calling
+ * setCurrentUser() as soon as possible after each HTTP request is received. The
+ * value of getCurrentUser() is used in several other places in this API. This
+ * eliminates the need to pass a user object to methods throughout the library.
+ * For example, all of the logging, access control, and exception calls need
+ * access to the currently logged in user.
+ *
+ * The goal is to minimize the responsibility of the developer for
+ * authentication. In this example, the user simply calls authenticate with the
+ * current request and the name of the parameters containing the username and
+ * password. The implementation should verify the password if necessary, create
+ * a session if necessary, and set the user as the current user.
+ *
+ *
+ * public void doPost(ServletRequest request, ServletResponse response) {
+ * try {
+ * User user = ESAPI.authenticator().login(request, response);
+ * // continue with authenticated user
+ * } catch (AuthenticationException e) {
+ * // handle failed authentication (it's already been logged)
+ * }
+ *
+ *
+ * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @since June 1, 2007
+ */
+public interface Authenticator {
+
+ /**
+ * Clears the current User. This allows the thread to be reused safely.
+ *
+ * This clears all threadlocal variables from the thread. This should ONLY be called after
+ * all possible ESAPI operations have concluded. If you clear too early, many calls will
+ * fail, including logging, which requires the user identity.
+ */
+ void clearCurrent();
+
+ /**
+ * Calls login with the *current* request and response.
+ * @return Authenticated {@code User} if login is successful.
+ * @see HTTPUtilities#setCurrentHTTP(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ User login() throws AuthenticationException;
+
+ /**
+ * This method should be called for every HTTP request, to login the current user either from the session of HTTP
+ * request. This method will set the current user so that getCurrentUser() will work properly.
+ *
+ * Authenticates the user's credentials from the HttpServletRequest if
+ * necessary, creates a session if necessary, and sets the user as the
+ * current user.
+ *
+ * Specification: The implementation should do the following:
+ * 1) Check if the User is already stored in the session
+ * a. If so, check that session absolute and inactivity timeout have not expired
+ * b. Step 2 may not be required if 1a has been satisfied
+ * 2) Verify User credentials
+ * a. It is recommended that you use
+ * loginWithUsernameAndPassword(HttpServletRequest, HttpServletResponse) to verify credentials
+ * 3) Set the last host of the User (ex. user.setLastHostAddress(address) )
+ * 4) Verify that the request is secure (ex. over SSL)
+ * 5) Verify the User account is allowed to be logged in
+ * a. Verify the User is not disabled, expired or locked
+ * 6) Assign User to session variable
+ *
+ * @param request
+ * the current HTTP request
+ * @param response
+ * the HTTP response
+ *
+ * @return
+ * the User
+ *
+ * @throws AuthenticationException
+ * if the credentials are not verified, or if the account is disabled, locked, expired, or timed out
+ */
+ User login(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException;
+
+ /**
+ * Verify that the supplied password matches the password for this user. Password should
+ * be stored as a hash. By default, this method verifies password hashes created via the
+ * {@code hashPassword(password, accountName)} method in this class, however see WARNING
+ * the {@code hashPassword} method.
+ *
+ * This method is typically used for "reauthentication" for the most sensitive functions, such
+ * as transactions, changing email address, and changing other account information.
+ *
+ * @param user
+ * the user who requires verification
+ * @param password
+ * the hashed user-supplied password
+ *
+ * @return
+ * true, if the password is correct for the specified user
+ *
+ * @see #hashPassword(String password, String accountName)
+ */
+ boolean verifyPassword(User user, String password);
+
+ /**
+ * Logs out the current user.
+ *
+ * This is usually done by calling User.logout on the current User.
+ */
+ void logout();
+
+ /**
+ * Creates a new User with the information provided. Implementations should check
+ * accountName and password for proper format and strength against brute force
+ * attacks ( verifyAccountNameStrength(String), verifyPasswordStrength(String, String) ).
+ *
+ * Two copies of the new password are required to encourage user interface designers to
+ * include a "re-type password" field in their forms. Implementations should verify that
+ * both are the same.
+ *
+ * WARNING: The implementation of this method as defined in the
+ * default reference implementation class, {@code FileBasedAuthenticator},
+ * uses a password hash algorithm that is known to be weak. You are advised
+ * to replace the default reference implementation class with your own custom
+ * implementation that uses a stronger password hashing algorithm.
+ * See class comments in * {@code FileBasedAuthenticator} for further details.
+ *
+ * @param accountName
+ * the account name of the new user
+ * @param password1
+ * the password of the new user
+ * @param password2
+ * the password of the new user. This field is to encourage user interface designers to include two password fields in their forms.
+ *
+ * @return
+ * the User that has been created
+ *
+ * @throws AuthenticationException
+ * if user creation fails due to any of the qualifications listed in this method's description
+ */
+ User createUser(String accountName, String password1, String password2) throws AuthenticationException;
+
+ /**
+ * Generate a strong password. Implementations should use a large character set that does not
+ * include confusing characters, such as i I 1 l 0 o and O. There are many algorithms to
+ * generate strong memorable passwords that have been studied in the past.
+ *
+ * @return
+ * a password with strong password strength
+ */
+ String generateStrongPassword();
+
+ /**
+ * Generate strong password that takes into account the user's information and old password. Implementations
+ * should verify that the new password does not include information such as the username, fragments of the
+ * old password, and other information that could be used to weaken the strength of the password.
+ *
+ * @param user
+ * the user whose information to use when generating password
+ * @param oldPassword
+ * the old password to use when verifying strength of new password. The new password may be checked for fragments of oldPassword.
+ *
+ * @return
+ * a password with strong password strength
+ */
+ String generateStrongPassword(User user, String oldPassword);
+
+ /**
+ * Changes the password for the specified user. This requires the current password, as well as
+ * the password to replace it with. The new password should be checked against old hashes to be sure the new password does not closely resemble or equal any recent passwords for that User.
+ * Password strength should also be verified. This new password must be repeated to ensure that the user has typed it in correctly.
+ *
+ * @param user
+ * the user to change the password for
+ * @param currentPassword
+ * the current password for the specified user
+ * @param newPassword
+ * the new password to use
+ * @param newPassword2
+ * a verification copy of the new password
+ *
+ * @throws AuthenticationException
+ * if any errors occur
+ */
+ void changePassword(User user, String currentPassword, String newPassword, String newPassword2) throws AuthenticationException;
+
+ /**
+ * Returns the User matching the provided accountId. If the accoundId is not found, an Anonymous
+ * User or null may be returned.
+ *
+ * @param accountId
+ * the account id
+ *
+ * @return
+ * the matching User object, or the Anonymous User if no match exists
+ */
+ User getUser(long accountId);
+
+ /**
+ * Returns the User matching the provided accountName. If the accoundId is not found, an Anonymous
+ * User or null may be returned.
+ *
+ * @param accountName
+ * the account name
+ *
+ * @return
+ * the matching User object, or the Anonymous User if no match exists
+ */
+ User getUser(String accountName);
+
+ /**
+ * Gets a collection containing all the existing user names.
+ *
+ * @return
+ * a set of all user names
+ */
+ Set getUserNames();
+
+ /**
+ * Returns the currently logged in User.
+ *
+ * @return
+ * the matching User object, or the Anonymous User if no match
+ * exists
+ */
+ User getCurrentUser();
+
+ /**
+ * Sets the currently logged in User.
+ *
+ * @param user
+ * the user to set as the current user
+ */
+ void setCurrentUser(User user);
+
+ /**
+ * Returns a string representation of the hashed password, using the
+ * accountName as the salt. The salt helps to prevent against "rainbow"
+ * table attacks where the attacker pre-calculates hashes for known strings.
+ * This method specifies the use of the user's account name as the "salt"
+ * value. The Encryptor.hash method can be used if a different salt is
+ * required.
+ *
+ * WARNING: The implementation of this method as defined in the
+ * default reference implementation class, {@code FileBasedAuthenticator},
+ * is know to be extremely weak. The reference implementation class was
+ * meant to be an example implementation and generally should be avoided
+ * and replaced with your own implementation. See class comments in
+ * {@code FileBasedAuthenticator} for further details.
+ *
+ * @param password
+ * the password to hash
+ * @param accountName
+ * the account name to use as the salt
+ *
+ * @return
+ * the hashed password
+ * @throws EncryptionException
+ *
+ * @see org.owasp.esapi.reference.FileBasedAuthenticator FileBasedAuthenticator,
+ * the default reference implementation of this interface.
+ */
+ String hashPassword(String password, String accountName) throws EncryptionException;
+
+ /**
+ * Removes the account of the specified accountName.
+ *
+ * @param accountName
+ * the account name to remove
+ *
+ * @throws AuthenticationException
+ * the authentication exception if user does not exist
+ */
+ void removeUser(String accountName) throws AuthenticationException;
+
+ /**
+ * Ensures that the account name passes site-specific complexity requirements, like minimum length.
+ *
+ * @param accountName
+ * the account name
+ *
+ * @throws AuthenticationException
+ * if account name does not meet complexity requirements
+ */
+ void verifyAccountNameStrength(String accountName) throws AuthenticationException;
+
+ /**
+ * Ensures that the password meets site-specific complexity requirements, like length or number
+ * of character sets. This method takes the old password so that the algorithm can analyze the
+ * new password to see if it is too similar to the old password. Note that this has to be
+ * invoked when the user has entered the old password, as the list of old
+ * credentials stored by ESAPI is all hashed.
+ * Additionally, the user object is taken in order to verify the password and account name differ.
+ *
+ * @param oldPassword
+ * the old password
+ * @param newPassword
+ * the new password
+ * @param user
+ * the user
+ *
+ * @throws AuthenticationException
+ * if newPassword is too similar to oldPassword or if newPassword does not meet complexity requirements
+ */
+ void verifyPasswordStrength(String oldPassword, String newPassword, User user) throws AuthenticationException;
+
+ /**
+ * Determine if the account exists.
+ *
+ * @param accountName
+ * the account name
+ *
+ * @return true, if the account exists
+ */
+ boolean exists(String accountName);
+
+}
diff --git a/src/main/java/org/owasp/esapi/ESAPI.java b/src/main/java/org/owasp/esapi/ESAPI.java
new file mode 100644
index 000000000..55e4d896d
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/ESAPI.java
@@ -0,0 +1,299 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2008 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Mike Fauzy Aspect Security
+ * @author Rogan Dawes Aspect Security
+ * @created 2008
+ */
+package org.owasp.esapi;
+
+import java.util.Arrays;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.owasp.esapi.util.ObjFactory;
+import org.owasp.esapi.errors.ConfigurationException;
+
+/**
+ * ESAPI locator class is provided to make it easy to gain access to the current ESAPI classes in use.
+ * Use the set methods to override the reference implementations with instances of any custom ESAPI implementations.
+ */
+public final class ESAPI {
+ private static String securityConfigurationImplName = System.getProperty("org.owasp.esapi.SecurityConfiguration", "org.owasp.esapi.reference.DefaultSecurityConfiguration");
+
+ /**
+ * prevent instantiation of this class
+ */
+ private ESAPI() {
+ }
+
+ /**
+ * Clears the current User, HttpRequest, and HttpResponse associated with the current thread. This method
+ * MUST be called as some containers do not properly clear threadlocal variables when the execution of
+ * a thread is complete. The suggested approach is to put this call in a finally block inside a filter.
+ *
+ * The advantages of having identity everywhere are worth the risk here.
+ */
+ public static void clearCurrent() {
+ authenticator().clearCurrent();
+ httpUtilities().clearCurrent();
+ }
+
+ /**
+ * Get the current HTTP Servlet Request being processed.
+ * @return the current HTTP Servlet Request.
+ */
+ public static HttpServletRequest currentRequest() {
+ return httpUtilities().getCurrentRequest();
+ }
+
+ /**
+ * Get the current HTTP Servlet Response being generated.
+ * @return the current HTTP Servlet Response.
+ */
+ public static HttpServletResponse currentResponse() {
+ return httpUtilities().getCurrentResponse();
+ }
+
+ /**
+ * @return the current ESAPI AccessController object being used to maintain the access control rules for this application.
+ */
+ public static AccessController accessController() {
+ return ObjFactory.make( securityConfiguration().getAccessControlImplementation(), "AccessController" );
+ }
+
+ /**
+ * @return the current ESAPI Authenticator object being used to authenticate users for this application.
+ */
+ public static Authenticator authenticator() {
+ return ObjFactory.make( securityConfiguration().getAuthenticationImplementation(), "Authenticator" );
+ }
+
+ /**
+ * The ESAPI {@code Encoder} is primarily used to provide output encoding to
+ * prevent Cross-Site Scripting (XSS).
+ * @return the current ESAPI {@code Encoder} object being used to encode and decode data for this application.
+ */
+ public static Encoder encoder() {
+ return ObjFactory.make( securityConfiguration().getEncoderImplementation(), "Encoder" );
+ }
+
+ /**
+ * ESAPI {@code Encryptor} provides a set of methods for performing common encryption, random number, and
+ * hashing operations.
+ * @return the current ESAPI {@code Encryptor} object being used to encrypt and decrypt data for this application.
+ */
+ public static Encryptor encryptor() {
+ return ObjFactory.make( securityConfiguration().getEncryptionImplementation(), "Encryptor" );
+ }
+
+ /**
+ * @return the current ESAPI Executor object being used to safely execute OS commands for this application.
+ */
+ public static Executor executor() {
+ return ObjFactory.make( securityConfiguration().getExecutorImplementation(), "Executor" );
+ }
+
+ /**
+ * @return the current ESAPI HTTPUtilities object being used to safely access HTTP requests and responses
+ * for this application.
+ */
+ public static HTTPUtilities httpUtilities() {
+ return ObjFactory.make( securityConfiguration().getHTTPUtilitiesImplementation(), "HTTPUtilities" );
+ }
+
+ /**
+ * @return the current ESAPI IntrusionDetector being used to monitor for intrusions in this application.
+ */
+ public static IntrusionDetector intrusionDetector() {
+ return ObjFactory.make( securityConfiguration().getIntrusionDetectionImplementation(), "IntrusionDetector" );
+ }
+
+ /**
+ * Get the current LogFactory being used by ESAPI. If there isn't one yet, it will create one, and then
+ * return this same LogFactory from then on.
+ * @return The current LogFactory being used by ESAPI.
+ */
+ private static LogFactory logFactory() {
+ return ObjFactory.make( securityConfiguration().getLogImplementation(), "LogFactory" );
+ }
+
+ /**
+ * @param clazz The class to associate the logger with.
+ * @return The current Logger associated with the specified class.
+ */
+ public static Logger getLogger(Class clazz) {
+ return logFactory().getLogger(clazz);
+ }
+
+ /**
+ * @param moduleName The module to associate the logger with.
+ * @return The current Logger associated with the specified module.
+ */
+ public static Logger getLogger(String moduleName) {
+ return logFactory().getLogger(moduleName);
+ }
+
+ /**
+ * @return The default Logger.
+ */
+ public static Logger log() {
+ return logFactory().getLogger("DefaultLogger");
+ }
+
+ /**
+ * @return the current ESAPI Randomizer being used to generate random numbers in this application.
+ */
+ public static Randomizer randomizer() {
+ return ObjFactory.make( securityConfiguration().getRandomizerImplementation(), "Randomizer" );
+ }
+
+ private static volatile SecurityConfiguration overrideConfig = null;
+
+ /**
+ * @return the current ESAPI SecurityConfiguration being used to manage the security configuration for
+ * ESAPI for this application.
+ */
+ public static SecurityConfiguration securityConfiguration() {
+ // copy the volatile into a non-volatile to prevent TOCTTOU race condition
+ SecurityConfiguration override = overrideConfig;
+ if ( override != null ) {
+ return override;
+ }
+
+ return ObjFactory.make( securityConfigurationImplName, "SecurityConfiguration" );
+ }
+
+ /**
+ * @return the current ESAPI Validator being used to validate data in this application.
+ */
+ public static Validator validator() {
+ return ObjFactory.make( securityConfiguration().getValidationImplementation(), "Validator" );
+ }
+
+ // TODO: This should probably use the SecurityManager or some value within the current
+ // securityConfiguration to determine if this method is allowed to be called. This could
+ // allow for unit tests internal to ESAPI to modify the configuration for the purpose of
+ // testing stuff, and allow developers to allow this in development environments but make
+ // it so the securityConfiguration implementation *cannot* be modified in production environments.
+ //
+ // The purpose of this method is to replace the functionality provided by the setSecurityConfiguration
+ // method that is no longer on this class, and allow the context configuration of the ESAPI
+ // to be modified at Runtime.
+ public static String initialize( String impl ) {
+ String oldImpl = securityConfigurationImplName;
+ securityConfigurationImplName = impl;
+ return oldImpl;
+ }
+
+ /**
+ * Overrides the current security configuration with a new implementation. This is meant
+ * to be used as a temporary means to alter the behavior of the ESAPI and should *NEVER*
+ * be used in a production environment as it will affect the behavior and configuration of
+ * the ESAPI *GLOBALLY*.
+ *
+ * To clear an overridden Configuration, simple call this method with null for the config
+ * parameter.
+ *
+ * @param config The new security configuration.
+ */
+ public static void override( SecurityConfiguration config ) {
+ overrideConfig = config;
+ }
+
+ // KWW - OPEN ISSUE: I don't like placing this here, but it's convenient and I
+ // don't really know a better place for it and would rather not create
+ // a whole new utility class just to use it.
+ /**
+ * Determine if a given fully qualified (ESAPI) method name has been explicitly
+ * enabled in the ESAPI.properties's file via the property name
+ * ESAPI.dangerouslyAllowUnsafeMethods.methodNames. Note that there
+ * is no real reason for an ESAPI client to use this, It is intended for
+ * interal use,
+ *
+ * The reason this method exists is because certain (other) ESAPI method names
+ * are considered "unsafe" and therefore should be used with extra caution.
+ * These "unsafe" methods may include methods that are:
+ *
+ *
Deprecated and thus no longer suggested for long term use.
+ *
Methods where the programming contract is not in itself sufficient to ensure safety alone
+ * and developers are expected to take addional actions on their own to secure their application.
+ *
Methods that are using some unpatched transitive dependency that we haven't firmly
+ * established grounds for it not being exploitable in the manner that ESAPI uses it.
+ *
Methods whose reference implementations are not scalable to the enterprise level.
+ *
+ * Public methods that are not in that list for the above ESAPI property
+ * are generally are considered enabled and okay to use unless their Javadoc
+ * indicates otherwise.
+ *
+ * Note that this method is intended primarilly for internal ESAPI use and if we were
+ * using Java Modules (in JDK 9 and later), this method would not be exported.
+ *
+ * For further details, please see the ESAPI GitHub wiki article,
+ * "Reducing the ESAPI Library's Attack Surface".
+ * @param fullyQualifiedMethodName A fully qualified ESAPI class name (so, should start
+ * "org.owasp.esapi.") followed by the method name (but without
+ * parenthesis or any parameter signature information.
+ * @return {@code true} if the parameter {@code fullyQualifiedMethodName} is in the comma-separated
+ * list of values in the ESAPI property ESAPI.dangerouslyAllowUnsafeMethods.methodNames,
+ * otherwise {@code false} is returned.
+ */
+ public static boolean isMethodExplicityEnabled(String fullyQualifiedMethodName) {
+ if ( fullyQualifiedMethodName == null || fullyQualifiedMethodName.trim().isEmpty() ) {
+ throw new IllegalArgumentException("Program error: fullyQualifiedMethodName parameter cannot be null or empty");
+ }
+ String desiredMethodName = fullyQualifiedMethodName.trim();
+ // This regex is too liberal to be anything more than just a trivial
+ // sanity test to protect against typos.
+ if ( !desiredMethodName.matches("^org\\.owasp\\.esapi\\.(\\p{Alnum}|\\.)*$") ) {
+ throw new IllegalArgumentException("Program error: fullyQualifiedMethodName must start with " +
+ "'org.owasp.esapi.' and be a valid method name.");
+ }
+
+ String enabledMethods = null;
+ try {
+ // Need to do this w/in a try/catch because if the property is not
+ // found, getStringProp will throw a ConfigurationException rather
+ // than returning a null.
+ enabledMethods = securityConfiguration().getStringProp("ESAPI.dangerouslyAllowUnsafeMethods.methodNames");
+ } catch( ConfigurationException cex ) {
+ return false; // Property not found at all.
+ }
+
+
+ // Split it up by ',' and then filter it by finding the first on that
+ // matches the desired method name passed in as the method parameter.
+ // If no matches, return the empty string.
+ String result = Arrays.stream( enabledMethods.trim().split(",") )
+ .filter(methodName -> methodName.trim().equals( desiredMethodName ) )
+ .findFirst()
+ .orElse("");
+ return !result.isEmpty();
+ }
+}
diff --git a/src/main/java/org/owasp/esapi/Encoder.java b/src/main/java/org/owasp/esapi/Encoder.java
new file mode 100644
index 000000000..409b27b24
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/Encoder.java
@@ -0,0 +1,761 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007-2019 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.owasp.esapi.codecs.Codec;
+import org.owasp.esapi.errors.EncodingException;
+
+
+/**
+ * The {@code Encoder} interface contains a number of methods for decoding input and encoding output
+ * so that it will be safe for a variety of interpreters. Its primary use is to
+ * provide output encoding to prevent XSS.
+ *
+ * To prevent double-encoding, callers should make sure input does not already contain encoded characters
+ * by calling one of the {@code canonicalize()} methods. Validator implementations should call
+ * {@code canonicalize()} on user input before validating to prevent encoded attacks.
+ *
+ * All of the methods must use an "allow list" or "positive" security model rather
+ * than a "deny list" or "negative" security model. For the encoding methods, this means that
+ * all characters should be encoded, except for a specific list of "immune" characters that are
+ * known to be safe.
+ *
+ * The {@code Encoder} performs two key functions, encoding (also referred to as "escaping" in this Javadoc)
+ * and decoding. These functions rely on a set of codecs that can be found in the
+ * {@code org.owasp.esapi.codecs} package. These include:
+ *
+ *
CSS Escaping
+ *
HTMLEntity Encoding
+ *
JavaScript Escaping
+ *
MySQL Database Escaping
+ *
Oracle Database Escaping
+ *
JSON Escaping
+ *
Percent Encoding (aka URL Encoding)
+ *
Unix Shell Escaping
+ *
VBScript Escaping
+ *
Windows Cmd Escaping
+ *
LDAP Escaping
+ *
XML and XML Attribute Encoding
+ *
XPath Escaping
+ *
Base64 Encoding
+ *
+ *
+ * The primary use of ESAPI {@code Encoder} is to prevent XSS vulnerabilities by
+ * providing output encoding using the various "encodeForXYZ()" methods,
+ * where XYZ is one of CSS, HTML, HTMLAttribute, JavaScript, or URL. When
+ * using the ESAPI output encoders, it is important that you use the one for the
+ * appropriate context where the output will be rendered. For example, it
+ * the output appears in an JavaScript context, you should use {@code encodeForJavaScript}
+ * (note this includes all of the DOM JavaScript event handler attributes such as
+ * 'onfocus', 'onclick', 'onload', etc.). If the output would be rendered in an HTML
+ * attribute context (with the exception of the aforementioned 'onevent' type event
+ * handler attributes), you would use {@code encodeForHTMLAttribute}. If you are
+ * encoding anywhere a URL is expected (e.g., a 'href' attribute for for <a> or
+ * a 'src' attribute on a <img> tag, etc.), then you should use use {@code encodeForURL}.
+ * If encoding CSS, then use {@code encodeForCSS}. Etc. This is because there are
+ * different escaping requirements for these different contexts. Developers who are
+ * new to ESAPI or to defending against XSS vulnerabilities are highly encouraged to
+ * first read the
+ *
+ * OWASP Cross-Site Scripting Prevention Cheat Sheet.
+ *
+ * Note that in addition to these encoder methods, ESAPI also provides a JSP Tag
+ * Library ({@code META-INF/esapi.tld}) in the ESAPI jar. This allows one to use
+ * the more convenient JSP tags in JSPs. These JSP tags are simply wrappers for the
+ * various these "encodeForXXYZ()" method docmented in this {@code Encoder}
+ * interface.
+ *
+ * Some important final words:
+ *
+ *
Where to output encode for HTML rendering:
+ * Knowing where to place the output encoding in your code
+ * is just as important as knowing which context (HTML, HTML attribute, CSS,
+ * JavaScript, or URL) to use for the output encoding and surprisingly the two
+ * are often related. In general, output encoding should be done just prior to the
+ * output being rendered (that is, as close to the 'sink' as possible) because that
+ * is what determines what the appropriate context is for the output encoding.
+ * In fact, doing output encoding on untrusted data that is stored and to
+ * be used later--whether stored in an HTTP session or in a database--is almost
+ * always considered an anti-pattern. An example of this is one gathers and
+ * stores some untrusted data item such as an email address from a user. A
+ * developer thinks "let's output encode this and store the encoded data in
+ * the database, thus making the untrusted data safe to use all the time, thus
+ * saving all of us developers all the encoding troubles later on". On the surface,
+ * that sounds like a reasonable approach. The problem is how to know what
+ * output encoding to use, not only for now, but for all possible future
+ * uses? It might be that the current application code base is only using it in
+ * an HTML context that is displayed in an HTML report or shown in an HTML
+ * context in the user's profile. But what if it is later used in a {@code mailto:} URL?
+ * Then instead of HTML encoding, it would need to have URL encoding. Similarly,
+ * what if there is a later switch made to use AJAX and the untrusted email
+ * address gets used in a JavaScript context? The complication is that even if
+ * you know with certainty today all the ways that an untrusted data item is
+ * used in your application, it is generally impossible to predict all the
+ * contexts that it may be used in the future, not only in your application, but
+ * in other applications that could access that data in the database.
+ *
+ *
Avoiding multiple nested contexts:
+ * A really tricky situation to get correct is when there are multiple nested
+ * encoding contexts. But far, the most common place this seems to come up is
+ * untrusted URLs used in JavaScript. How should you handle that? Well,
+ * the best way is to rewrite your code to avoid it! An example of
+ * this that is well worth reading may be found at
+ * ESAPI-DEV mailing list archives:
+ * URL encoding within JavaScript. Be sure to read the entire thread.
+ * The question itself is too nuanced to be answered in Javadoc, but now,
+ * hopefully you are at least aware of the potential pitfalls. There is little
+ * available research or examples on how to do output encoding when multiple
+ * mixed encodings are required, although one that you may find useful is
+ *
+ * Automated Detecting and Repair of Cross-SiteScripting Vulnerabilities through Unit Testing
+ * It at least discusses a few of the common errors involved in multiple mixed
+ * encoding contexts.
+ *
A word about unit testing:
+ * Unit testing this is hard. You may be satisfied with stopped after you have
+ * tested against the ubiquitous XSS test case of
+ *
+ * </script>alert(1)</script>
+ *
+ * or similar simplistic XSS attack payloads and if that is properly encoded
+ * (or, you don't see an alert box popped in your browser), you consider it
+ * "problem fixed", and consider the unit testing sufficient. Unfortunately, that
+ * minimalist testing may not always detect places where you used the wrong output
+ * encoder. You need to do better. Fortunately, the aforementioned link,
+ *
+ * Automated Detecting and Repair of Cross-SiteScripting Vulnerabilities through Unit Testing
+ * provides some insight on this. You may also wish to look at the
+ * ESAPI Encoder JUnittest cases for ideas.
+ * If you are really ambitious, an excellent resource for XSS attack patterns is
+ * BeEF - The Browser Exploitation Framework Project.
+ *
A final note on {@code Encoder} implementation details:
+ * Most of the {@code Encoder} methods make extensive use of ESAPI's {@link org.owasp.esapi.codecs.Codec}
+ * classes under-the-hood. These {@code Codec} classes are intended for use for encoding and decoding
+ * input based on some particular context or specification. While the OWASP team
+ * over the years have made every effort to be cautious--often going to extremes
+ * to make "safe harbor" decisions on harmful inputs other similar encoders assume are already safe
+ * (we did this to in order to protect the client's users from buggy browsers that don't adhere
+ * to the W3C HTML specications)&em;the various {@code Codec} implemtations can offer
+ * NO GUARANTEE of safety of the content being encoded or decoded. Therefore,
+ * it is highly advised to practice a security-in-depth approach for everything you do.
+ * By following that advice, you will minimize the impact and/or likelihood of any
+ * vulnerabilities from bugs in the ESAPI code or accidental misuse of the ESAPI
+ * library on your part. In particular, whenever there are cases where cients use
+ * any of these {@link org.owasp.esapi.codecs.Codec} classes directly, it is highly
+ * recommended to perform canonicalization followed by strict input valiation both
+ * prior to encoding and after decoding to protect your application from input-based
+ * attacks.
+ *
+ * (If the {@code Encoder.DefaultCodecList} property is null or not set,
+ * these same codecs are listed in the same order. Note that you may supply
+ * your own codec by using a fully cqualified class name of a class that
+ * implements {@code org.owasp.esapi.codecs.Codec}.
+ *
+ * @see #canonicalize(String, boolean, boolean)
+ * @see W3C specifications
+ *
+ * @param input the text to canonicalize
+ * @return a String containing the canonicalized text
+ */
+ String canonicalize(String input);
+
+ /**
+ * This method is the equivalent to calling {@code Encoder.canonicalize(input, strict, strict);}.
+ *
+ * @see #canonicalize(String, boolean, boolean)
+ * @see W3C specifications
+ *
+ * @param input
+ * the text to canonicalize
+ * @param strict
+ * true if checking for multiple and mixed encoding is desired, false otherwise
+ *
+ * @return a String containing the canonicalized text
+ */
+ String canonicalize(String input, boolean strict);
+
+ /**
+ * Canonicalization is simply the operation of reducing a possibly encoded
+ * string down to its simplest form. This is important, because attackers
+ * frequently use encoding to change their input in a way that will bypass
+ * validation filters, but still be interpreted properly by the target of
+ * the attack. Note that data encoded more than once is not something that a
+ * normal user would generate and should be regarded as an attack.
+ *
+ * Everyone says you shouldn't do validation
+ * without canonicalizing the data first. This is easier said than done. The canonicalize method can
+ * be used to simplify just about any input down to its most basic form. Note that canonicalize doesn't
+ * handle Unicode issues, it focuses on higher level encoding and escaping schemes. In addition to simple
+ * decoding, canonicalize also handles:
+ *
Perverse but legal variants of escaping schemes
+ *
Multiple escaping (%2526 or <)
+ *
Mixed escaping (%26lt;)
+ *
Nested escaping (%%316 or &%6ct;)
+ *
All combinations of multiple, mixed, and nested encoding/escaping (%253c or ┦gt;)
+ *
+ * Using canonicalize is simple. The default is just...
+ *
+ * You need to decode untrusted data so that it's safe for ANY downstream interpreter or decoder. For
+ * example, if your data goes into a Windows command shell, then into a database, and then to a browser,
+ * you're going to need to decode for all of those systems. You can build a custom encoder to canonicalize
+ * for your application like this...
+ *
+ * ArrayList list = new ArrayList();
+ * list.add( new WindowsCodec() );
+ * list.add( new MySQLCodec() );
+ * list.add( new PercentCodec() );
+ * Encoder encoder = new DefaultEncoder( list );
+ * String clean = encoder.canonicalize( request.getParameter( "input" ));
+ *
+ * or alternately, you can just customize {@code Encoder.DefaultCodecList} property
+ * in the {@code ESAPI.properties} file with your preferred codecs; for
+ * example:
+ *
+ * as you normally would. However, the downside to using the
+ * {@code ESAPI.properties} file approach does not allow you to vary your
+ * list of codecs that are used each time. The downside to using the
+ * {@code DefaultEncoder} constructor is that your code is now timed to
+ * specific reference implementations rather than just interfaces and those
+ * reference implementations are what is most likely to change in ESAPI 3.x.
+ *
+ * In ESAPI, the {@code Validator} uses the {@code canonicalize} method before it does validation. So all you need to
+ * do is to validate as normal and you'll be protected against a host of encoded attacks.
+ *
+ * However, the default canonicalize() method only decodes HTMLEntity, percent (URL) encoding, and JavaScript
+ * encoding. If you'd like to use a custom canonicalizer with your validator, that's pretty easy too.
+ *
+ * Although ESAPI is able to canonicalize multiple, mixed, or nested encoding, it's safer to not accept
+ * this stuff in the first place. In ESAPI, the default is "strict" mode that throws an IntrusionException
+ * if it receives anything not single-encoded with a single scheme. This is configurable
+ * in {@code ESAPI.properties} using the properties:
+ *
+ * This method allows you to override the default behavior by directly specifying whether to restrict
+ * multiple or mixed encoding. Even if you disable restrictions, you'll still get
+ * warning messages in the log about each multiple encoding and mixed encoding received.
+ *
+ * WARNING #1!!! Please note that this method is incompatible with URLs and if there exist any HTML Entities
+ * that correspond with parameter values in a URL such as "¶" in a URL like
+ * "https://foo.com/?bar=foo¶meter=wrong" you will get a mixed encoding validation exception.
+ *
+ * If you wish to canonicalize a URL/URI use the method {@code Encoder.getCanonicalizedURI(URI dirtyUri);}
+ *
+ * WARNING #2!!! Even if you use {@code WindowsCodec} or {@code UnixCodec}
+ * as appropriate, file path names in the {@code input} parameter will NOT
+ * be canonicalized. It the failure of such file path name canonicalization
+ * presents a potential security issue, consider using one of the
+ * {@code Validator.getValidDirectoryPath()} methods instead of or in addition to this method.
+ *
+ * @see W3C specifications
+ * @see #canonicalize(String)
+ * @see #getCanonicalizedURI(URI dirtyUri)
+ * @see org.owasp.esapi.Validator#getValidDirectoryPath(java.lang.String, java.lang.String, java.io.File, boolean)
+ *
+ * @param input
+ * the text to canonicalize
+ * @param restrictMultiple
+ * true if checking for multiple encoding is desired, false otherwise
+ * @param restrictMixed
+ * true if checking for mixed encoding is desired, false otherwise
+ *
+ * @return a String containing the canonicalized text
+ */
+ String canonicalize(String input, boolean restrictMultiple, boolean restrictMixed);
+
+ /**
+ * Encode data for use in Cascading Style Sheets (CSS) content.
+ *
+ * @see CSS Syntax [w3.org]
+ *
+ * @param untrustedData
+ * the untrusted data to output encode for CSS
+ *
+ * @return the untrusted data safely output encoded for use in a CSS
+ */
+ String encodeForCSS(String untrustedData);
+
+ /**
+ * Encode data for use in HTML using HTML entity encoding
+ *
+ * Note that the following characters:
+ * 00-08, 0B-0C, 0E-1F, and 7F-9F
+ *
cannot be used in HTML.
+ *
+ * @see HTML Encodings [wikipedia.org]
+ * @see SGML Specification [w3.org]
+ * @see XML Specification [w3.org]
+ *
+ * @param untrustedData
+ * the untrusted data to output encode for HTML
+ *
+ * @return the untrusted data safely output encoded for use in a HTML
+ */
+ String encodeForHTML(String untrustedData);
+
+ /**
+ * Decodes HTML entities.
+ * @param input the String to decode
+ * @return the newly decoded String
+ */
+ String decodeForHTML(String input);
+
+ /**
+ * Encode data for use in HTML attributes.
+ *
+ * @param untrustedData
+ * the untrusted data to output encode for an HTML attribute
+ *
+ * @return the untrusted data safely output encoded for use in a use as an HTML attribute
+ */
+ String encodeForHTMLAttribute(String untrustedData);
+
+
+ /**
+ * Encode data for insertion inside a data value or function argument in JavaScript. Including user data
+ * directly inside a script is quite dangerous. Great care must be taken to prevent including user data
+ * directly into script code itself, as no amount of encoding will prevent attacks there.
+ *
+ * Please note there are some JavaScript functions that can never safely receive untrusted data
+ * as input – even if the user input is encoded.
+ *
+ * For example:
+ *
+ * <script>
+ * window.setInterval('<%= EVEN IF YOU ENCODE UNTRUSTED DATA YOU ARE XSSED HERE %>');
+ * </script>
+ *
+ * @param untrustedData
+ * the untrusted data to output encode for JavaScript
+ *
+ * @return the untrusted data safely output encoded for use in a use in JavaScript
+ */
+ String encodeForJavaScript(String untrustedData);
+
+ /**
+ * Encode data for insertion inside a data value in a Visual Basic script. Putting user data directly
+ * inside a script is quite dangerous. Great care must be taken to prevent putting user data
+ * directly into script code itself, as no amount of encoding will prevent attacks there.
+ *
+ * This method is not recommended as VBScript is only supported by Internet Explorer
+ *
+ * @param untrustedData
+ * the untrusted data to output encode for VBScript
+ *
+ * @return the untrusted data safely output encoded for use in a use in VBScript
+ */
+ String encodeForVBScript(String untrustedData);
+
+
+ /**
+ * Encode input for use in a SQL query, according to the selected codec
+ * (appropriate codecs include the {@link org.owasp.esapi.codecs.MySQLCodec}
+ * and {@link org.owasp.esapi.codecs.OracleCodec}), but see
+ * "SECURITY WARNING" below before using.
+ *
+ * The this method attempts to ensure make sure any single-quotes are double-quoted
+ * (i.e., as '', not double-quotes, as in "). Another possible approach
+ * is to use the {escape} syntax described in the JDBC specification in section 1.5.6.
+ * However, this syntax does not work with all drivers, and requires
+ * modification of all queries.
+ *
+ * SECURITY WARNING: This method is NOT recommended. The use of the {@code PreparedStatement}
+ * interface is the preferred approach. However, if for some reason
+ * this is impossible, then this method is provided as a significantly weaker
+ * alternative. In particular, it should be noted that if all you do to
+ * address potential SQL Injection attacks is to use this method to escape
+ * parameters, you will fail miserably. According to the
+ *
+ * OWASP SQL Injection Prevention Cheat Sheet, these are the primary
+ * defenses against SQL Injection (as of June 2025):
+ *
+ *
Option 1: Use of Prepared Statements (with Parameterized Queries)
+ *
Option 2: Use of Properly Constructed Stored Procedures
+ *
Option 3: Allow-list Input Validation
+ *
Option 4: STRONGLY DISCOURAGED: Escaping All User Supplied Input
+ *
+ *
+ * According to "Option 4" (which is what this method implements), that OWASP Cheat Sheet
+ * states:
+ *
+ * In this approach, the developer will escape all user input
+ * before putting it in a query. It is very database specific
+ * in its implementation. This methodology is frail compared
+ * to other defenses, and we CANNOT guarantee that this option
+ * will prevent all SQL injections in all situations.
+ *
+ * (Emphasis ours.)
+ *
+ * Note you could give yourself a slightly better chance at success if prior to
+ * escaping by this method, you first canonicalize the input and run it through
+ * some strong allow-list validation. We will not provide anymore details than
+ * that, lest we encourage its misuse; however, it should be noted that resorting
+ * to use this method--especially by itself--should rarely, if ever, used. It
+ * is intended as a last ditch, emergency, Hail Mary effort. (To be honest, you'd
+ * likely have more success setting up a WAF such as
+ * OWASP ModSecurity and
+ * OWASP CRS
+ * if you need a temporary emergency SQLi defense shield, but using {@code PreparedStatement}
+ * is still your best option if you have the time and resources.
+ *
+ * Note to AppSec / Security Auditor teams: If see this method being used in
+ * application code, the risk of an exploitable SQLi vulnerability is still high. We
+ * stress the importance of the first two Options discussed in the
+ *
+ * OWASP SQL Injection Prevention Cheat Sheet. If you allow this, we recommend only
+ * doing so for a limited time duration and in the meantime creating some sort of security
+ * exception ticket to track it.
+ *
+ * IMPORTANT NOTE: If you really do insist enabling leg cannon mode and use
+ * this method, then you MUST follow these instructions. Failure to do so will
+ * result in a {@link org.owasp.esapi.errors.NotConfiguredByDefaultException} being
+ * thrown when you try to call it. Thus to make it work, you need to add the implementation
+ * method corresponding to this interace (defined in the property "ESAPI.Encoder"
+ * (wihch defaults to "org.owasp.esapi.reference.DefaultEncoder") in your "ESAPI.properties" file,
+ * to the ESAPI property "ESAPI.dangerouslyAllowUnsafeMethods.methodNames". See
+ * the Security Bulletin #13 document referenced below for additional details.
+ *
+ * @see JDBC Specification
+ * @see java.sql.PreparedStatement
+ * @see ESAPI Security Bulletin #13
+ *
+ * @param codec
+ * a {@link org.owasp.esapi.codecs.Codec} that declares which database 'input' is being encoded for (ie. MySQL, Oracle, etc.)
+ * @param input
+ * the text to encode for SQL
+ *
+ * @return input encoded for use in SQL
+ * @see
+ * ESAPI Security Bulletin #13
+ * @deprecated This method is considered dangerous and not easily made safe and thus under strong
+ * consideration to be removed within 1 years time after the 2.7.0.0 release. Please
+ * see the referenced ESAPI Security Bulletin #13 for further details.
+ */
+ @Deprecated
+ String encodeForSQL(Codec codec, String input);
+
+ /**
+ * Encode for an operating system command shell according to the selected codec (appropriate codecs include the WindowsCodec and UnixCodec).
+ *
+ * Please note the following recommendations before choosing to use this method:
+ *
+ * 1) It is strongly recommended that applications avoid making direct OS system calls if possible as such calls are not portable, and they are potentially unsafe. Please use language provided features if at all possible, rather than native OS calls to implement the desired feature.
+ * 2) If an OS call cannot be avoided, then it is recommended that the program to be invoked be invoked directly (e.g., System.exec("nameofcommand" + "parameterstocommand");) as this avoids the use of the command shell. The "parameterstocommand" should of course be validated before passing them to the OS command.
+ * 3) If you must use this method, then we recommend validating all user supplied input passed to the command shell as well, in addition to using this method in order to make the command shell invocation safe.
+ *
+ * An example use of this method would be: System.exec("dir " + ESAPI.encodeForOS(WindowsCodec, "parameter(s)tocommandwithuserinput");
+ *
+ * @param codec
+ * a Codec that declares which operating system 'input' is being encoded for (ie. Windows, Unix, etc.)
+ * @param input
+ * the text to encode for the command shell
+ *
+ * @return input encoded for use in command shell
+ */
+ String encodeForOS(Codec codec, String input);
+
+ /**
+ * Encode data for use in LDAP queries. Wildcard (*) characters will be encoded.
+ *
+ * This encoder operates according to RFC 4515, Section 3. RFC 4515 says the following character ranges
+ * are valid: 0x01-0x27, 0x2B-0x5B and 0x5D-0x7F. Characters outside the ranges are hex encoded, and they
+ * include 0x00 (NUL), 0x28 (LPAREN), 0x29 (RPAREN), 0x2A (ASTERISK), and 0x5C (ESC). The encoder will also
+ * encode 0x2F (FSLASH), which is required by Microsoft Active Directory.
+ *
+ * NB: At ESAPI 2.5.3, {@code encodeForLDAP} began strict conformance with RFC 4515. Characters above 0x7F
+ * are converted to UTF-8, and then the byte sequences are hex encoded according to the RFC.
+ *
+ * @param input
+ * the text to encode for LDAP
+ *
+ * @return input encoded for use in LDAP
+ *
+ * @see RFC 4515, Lightweight Directory Access Protocol
+ * (LDAP): String Representation of Search Filters
+ *
+ * @since ESAPI 1.3
+ */
+ String encodeForLDAP(String input);
+
+ /**
+ * Encode data for use in LDAP queries. You have the option whether or not to encode wildcard (*) characters.
+ *
+ * This encoder operates according to RFC 4515, Section 3. RFC 4515 says the following character ranges
+ * are valid: 0x01-0x27, 0x2B-0x5B and 0x5D-0x7F. Characters outside the ranges are hex encoded, and they
+ * include 0x00 (NUL), 0x28 (LPAREN), 0x29 (RPAREN), 0x2A (ASTERISK), and 0x5C (ESC). The encoder will also
+ * encode 0x2F (FSLASH), which is required by Microsoft Active Directory.
+ *
+ * NB: At ESAPI 2.5.3, {@code encodeForLDAP} began strict conformance with RFC 4515. Characters above 0x7F
+ * are converted to UTF-8, and then the byte sequences are hex encoded according to the RFC.
+ *
+ * @param input
+ * the text to encode for LDAP
+ * @param encodeWildcards
+ * whether or not wildcard (*) characters will be encoded.
+ *
+ * @return input encoded for use in LDAP
+ *
+ * @see RFC 4515, Lightweight Directory Access Protocol
+ * (LDAP): String Representation of Search Filters
+ *
+ * @since ESAPI 1.3
+ */
+ String encodeForLDAP(String input, boolean encodeWildcards);
+
+ /**
+ * Encode data for use in an LDAP distinguished name.
+ *
+ * This encoder operates according to RFC 4514, Section 3. RFC 4514 says the following character ranges
+ * are valid: 0x01-0x21, 0x23-0x2A, 0x2D-0x3A, 0x3D, 0x3F-0x5B, 0x5D-0x7F. Characters outside the ranges
+ * are hex encoded, and they include 0x00 (NUL), 0x22 (DQUOTE), 0x2B (PLUS), 0x2C (COMMA),
+ * 0x3B (SEMI), 0x3C (LANGLE), 0x3E (RANGLE) and 0x5C (ESC). The encoder will also encode 0x2F (FSLASH),
+ * which is required by Microsoft Active Directory. The leading and trailing characters in a distinguished
+ * name string will also have 0x20 (SPACE) and 0x23 (SHARP) encoded.
+ *
+ * NB: At ESAPI 2.5.3, {@code encodeForDN} began strict conformance with RFC 4514. Characters above 0x7F
+ * are converted to UTF-8, and then the byte sequences are hex encoded according to the RFC.
+ *
+ * @param input
+ * the text to encode for an LDAP distinguished name
+ *
+ * @return input encoded for use in an LDAP distinguished name
+ *
+ * @see RFC 4514, Lightweight Directory Access Protocol
+ * (LDAP): String Representation of Distinguished Names
+ *
+ * @since ESAPI 1.3
+ */
+ String encodeForDN(String input);
+
+ /**
+ * Encode data for use in an XPath query.
+ *
+ * NB: The reference implementation encodes almost everything and may over-encode.
+ *
+ * The difficulty with XPath encoding is that XPath has no built-in mechanism for escaping
+ * characters. It is possible to use XQuery in a parameterized way to
+ * prevent injection.
+ *
+ * For more information, refer to this
+ * article which specifies the following list of characters as the most
+ * dangerous: ^ & " * ' ; < > ( ) . This
+ * paper suggests disallowing ' and " in queries.
+ *
+ * @see XPath Injection [ibm.com]
+ * @see Blind XPath Injection [packetstormsecurity.org]
+ *
+ * @param input
+ * the text to encode for XPath
+ * @return
+ * input encoded for use in XPath
+ */
+ String encodeForXPath(String input);
+
+ /**
+ * Encode data for use in an XML element. The implementation should follow the Character Encoding in Entities
+ * from W3C.
+ *
+ * The use of a real XML parser is strongly encouraged. However, in the
+ * hopefully rare case that you need to make sure that data is safe for
+ * inclusion in an XML document and cannot use a parser, this method provides
+ * a safe mechanism to do so.
+ *
+ * @see Character Encoding in Entities
+ *
+ * @param input
+ * the text to encode for XML
+ *
+ * @return
+ * input encoded for use in XML
+ */
+ String encodeForXML(String input);
+
+ /**
+ * Encode data for use in an XML attribute. The implementation should follow the Character Encoding in Entities
+ * from W3C.
+ *
+ * The main property controlling the selection of the implementation class is the
+ * property {@code ESAPI.Encryptor} in {@code ESAPI.properties}. Most of the
+ * the other encryption related properties have property names that start with
+ * the string "Encryptor.". These properties all you to do things such as
+ * select the encryption algorithms, the preferred JCE provider, etc.
+ *
+ * In addition, there are two important properties (initially delivered as unset
+ * from the ESAPI download) named {@code Encryptor.MasterKey} and
+ * {@code Encryptor.MasterSalt} that must be set before using ESAPI encryption.
+ * There is a bash(1) shell script provided with the standard ESAPI distribution
+ * called 'setMasterKey.sh' that will assist you in setting these two properties. The
+ * script is in 'src/examples/scripts/setMasterKey.sh'.
+ *
+ * Possible future enhancements (depending on feedback) are discussed in
+ * section 4 of
+ *
+ * Design Goals in OWASP ESAPI Cryptography.
+ *
+ * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @since June 1, 2007
+ * @see User Guide for Symmetric Encryption in ESAPI 2.0
+ */
+public interface Encryptor {
+
+ /**
+ * Returns a string representation of the hash of the provided plaintext and
+ * salt. The salt helps to protect against a rainbow table attack by mixing
+ * in some extra data with the plaintext. Some good choices for a salt might
+ * be an account name or some other string that is known to the application
+ * but not to an attacker.
+ * See
+ * this article for more information about hashing as it pertains to password schemes.
+ *
+ * @param plaintext
+ * the plaintext String to encrypt
+ * @param salt
+ * the salt to add to the plaintext String before hashing
+ *
+ * @return
+ * the encrypted hash of 'plaintext' stored as a String
+ *
+ * @throws EncryptionException
+ * if the specified hash algorithm could not be found or another problem exists with
+ * the hashing of 'plaintext'
+ */
+ String hash(String plaintext, String salt) throws EncryptionException;
+
+ /**
+ * Returns a string representation of the hash of the provided plaintext and
+ * salt. The salt helps to protect against a rainbow table attack by mixing
+ * in some extra data with the plaintext. Some good choices for a salt might
+ * be an account name or some other string that is known to the application
+ * but not to an attacker.
+ * See
+ * this article for more information about hashing as it pertains to password schemes.
+ *
+ * @param plaintext
+ * the plaintext String to encrypt
+ * @param salt
+ * the salt to add to the plaintext String before hashing
+ * @param iterations
+ * the number of times to iterate the hash
+ *
+ * @return
+ * the encrypted hash of 'plaintext' stored as a String
+ *
+ * @throws EncryptionException
+ * if the specified hash algorithm could not be found or another problem exists with
+ * the hashing of 'plaintext'
+ */
+ String hash(String plaintext, String salt, int iterations) throws EncryptionException;
+
+ /**
+ * Encrypts the provided plaintext bytes using the cipher transformation
+ * specified by the property Encryptor.CipherTransformation
+ * and the master encryption key as specified by the property
+ * {@code Encryptor.MasterKey} as defined in the ESAPI.properties file.
+ *
+ *
+ * @param plaintext The {@code PlainText} to be encrypted.
+ * @return the {@code CipherText} object from which the raw ciphertext, the
+ * IV, the cipher transformation, and many other aspects about
+ * the encryption detail may be extracted.
+ * @throws EncryptionException Thrown if something should go wrong such as
+ * the JCE provider cannot be found, the cipher algorithm,
+ * cipher mode, or padding scheme not being supported, specifying
+ * an unsupported key size, specifying an IV of incorrect length,
+ * etc.
+ * @see #encrypt(SecretKey, PlainText)
+ * @since 2.0
+ */
+ CipherText encrypt(PlainText plaintext) throws EncryptionException;
+
+
+ /**
+ * Encrypts the provided plaintext bytes using the cipher transformation
+ * specified by the property Encryptor.CipherTransformation
+ * as defined in the ESAPI.properties file and the
+ * specified secret key.
+ *
+ * This method is similar to {@link #encrypt(PlainText)} except that it
+ * permits a specific {@code SecretKey} to be used for encryption.
+ *
+ * @param key The {@code SecretKey} to use for encrypting the plaintext.
+ * @param plaintext The byte stream to be encrypted. Note if a Java
+ * {@code String} is to be encrypted, it should be converted
+ * using {@code "some string".getBytes("UTF-8")}.
+ * @return the {@code CipherText} object from which the raw ciphertext, the
+ * IV, the cipher transformation, and many other aspects about
+ * the encryption detail may be extracted.
+ * @throws EncryptionException Thrown if something should go wrong such as
+ * the JCE provider cannot be found, the cipher algorithm,
+ * cipher mode, or padding scheme not being supported, specifying
+ * an unsupported key size, specifying an IV of incorrect length,
+ * etc.
+ * @see #encrypt(PlainText)
+ * @since 2.0
+ */
+ CipherText encrypt(SecretKey key, PlainText plaintext)
+ throws EncryptionException;
+
+ /**
+ * Decrypts the provided {@link CipherText} using the information from it
+ * and the master encryption key as specified by the property
+ * {@code Encryptor.MasterKey} as defined in the {@code ESAPI.properties}
+ * file.
+ *
+ * @param ciphertext The {@code CipherText} object to be decrypted.
+ * @return The {@code PlainText} object resulting from decrypting the specified
+ * ciphertext. Note that if it is desired to convert the returned
+ * plaintext byte array to a Java String it should be done using
+ * {@code new String(byte[], "UTF-8");} rather than simply using
+ * {@code new String(byte[]);} which uses native encoding and may
+ * not be portable across hardware and/or OS platforms.
+ * @throws EncryptionException Thrown if something should go wrong such as
+ * the JCE provider cannot be found, the cipher algorithm,
+ * cipher mode, or padding scheme not being supported, specifying
+ * an unsupported key size, or incorrect encryption key was
+ * specified or a {@code PaddingException} occurs.
+ * @see #decrypt(SecretKey, CipherText)
+ */
+ PlainText decrypt(CipherText ciphertext) throws EncryptionException;
+
+ /**
+ * Decrypts the provided {@link CipherText} using the information from it
+ * and the specified secret key.
+ *
+ * This decrypt method is similar to {@link #decrypt(CipherText)} except that
+ * it allows decrypting with a secret key other than the master secret key.
+ *
+ * @param key The {@code SecretKey} to use for encrypting the plaintext.
+ * @param ciphertext The {@code CipherText} object to be decrypted.
+ * @return The {@code PlainText} object resulting from decrypting the specified
+ * ciphertext. Note that if it is desired to convert the returned
+ * plaintext byte array to a Java String it should be done using
+ * {@code new String(byte[], "UTF-8");} rather than simply using
+ * {@code new String(byte[]);} which uses native encoding and may
+ * not be portable across hardware and/or OS platforms.
+ * @throws EncryptionException Thrown if something should go wrong such as
+ * the JCE provider cannot be found, the cipher algorithm,
+ * cipher mode, or padding scheme not being supported, specifying
+ * an unsupported key size, or incorrect encryption key was
+ * specified or a {@code PaddingException} occurs.
+ * @see #decrypt(CipherText)
+ */
+ PlainText decrypt(SecretKey key, CipherText ciphertext) throws EncryptionException;
+
+ /**
+ * Create a digital signature for the provided data and return it in a
+ * string.
+ *
+ * Limitations: A new public/private key pair used for ESAPI 2.0 digital
+ * signatures with this method and {@link #verifySignature(String, String)}
+ * are dynamically created when the default reference implementation class,
+ * {@link org.owasp.esapi.reference.crypto.JavaEncryptor} is first created.
+ * Because this key pair is not persisted nor is the public key shared,
+ * this method and the corresponding {@link #verifySignature(String, String)}
+ * can not be used with expected results across JVM instances. This limitation
+ * will be addressed in ESAPI 2.1.
+ *
+ *
+ * @param data
+ * the data to sign
+ *
+ * @return
+ * the digital signature stored as a String
+ *
+ * @throws EncryptionException
+ * if the specified signature algorithm cannot be found
+ */
+ String sign(String data) throws EncryptionException;
+
+ /**
+ * Verifies a digital signature (created with the sign method) and returns
+ * the boolean result.
+ *
+ * Limitations: A new public/private key pair used for ESAPI 2.0 digital
+ * signatures with this method and {@link #sign(String)}
+ * are dynamically created when the default reference implementation class,
+ * {@link org.owasp.esapi.reference.crypto.JavaEncryptor} is first created.
+ * Because this key pair is not persisted nor is the public key shared,
+ * this method and the corresponding {@link #sign(String)}
+ * can not be used with expected results across JVM instances. This limitation
+ * will be addressed in ESAPI 2.1.
+ *
+ * @param signature
+ * the signature to verify against 'data'
+ * @param data
+ * the data to verify against 'signature'
+ *
+ * @return
+ * true, if the signature is verified, false otherwise
+ */
+ boolean verifySignature(String signature, String data);
+
+ /**
+ * Creates a seal that binds a set of data and includes an expiration timestamp.
+ *
+ * @param data
+ * the data to seal
+ * @param timestamp
+ * the absolute expiration date of the data, expressed as seconds since the epoch
+ *
+ * @return
+ * the seal
+ *
+ * @throws IntegrityException
+ */
+ String seal(String data, long timestamp) throws IntegrityException;
+
+ /**
+ * Unseals data (created with the seal method) and throws an exception
+ * describing any of the various problems that could exist with a seal, such
+ * as an invalid seal format, expired timestamp, or decryption error.
+ *
+ * @param seal
+ * the sealed data
+ *
+ * @return
+ * the original (unsealed) data
+ *
+ * @throws EncryptionException
+ * if the unsealed data cannot be retrieved for any reason
+ */
+ String unseal( String seal ) throws EncryptionException;
+
+ /**
+ * Verifies a seal (created with the seal method) and throws an exception
+ * describing any of the various problems that could exist with a seal, such
+ * as an invalid seal format, expired timestamp, or data mismatch.
+ *
+ * @param seal
+ * the seal to verify
+ *
+ * @return
+ * true, if the seal is valid. False otherwise
+ */
+ boolean verifySeal(String seal);
+
+ /**
+ * Gets an absolute timestamp representing an offset from the current time to be used by
+ * other functions in the library.
+ *
+ * @param offset
+ * the offset to add to the current time
+ *
+ * @return
+ * the absolute timestamp
+ */
+ long getRelativeTimeStamp( long offset );
+
+ /**
+ * Gets a timestamp representing the current date and time to be used by
+ * other functions in the library.
+ *
+ * @return
+ * a timestamp representing the current time
+ */
+ long getTimeStamp();
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/owasp/esapi/ExecuteResult.java b/src/main/java/org/owasp/esapi/ExecuteResult.java
new file mode 100644
index 000000000..6887b80c1
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/ExecuteResult.java
@@ -0,0 +1,75 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2010 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Patrick Higgins
+ * @created 2010
+ */
+package org.owasp.esapi;
+
+/**
+ * The ExecuteResult class encapsulates the pieces of data that can be returned
+ * from a process executed by the Executor interface.
+ *
+ * This class is immutable for thread-safety.
+ *
+ * @author Patrick Higgins
+ * @since Aug 25, 2010
+ */
+public class ExecuteResult {
+
+ private final int exitValue;
+ private final String output;
+ private final String errors;
+
+ /**
+ * Constructs an ExecuteResult from the given values.
+ *
+ * @param exitValue
+ * the code from java.lang.Process.exitValue()
+ * @param output
+ * the contents read from java.lang.Process.getInputStream()
+ * @param errors
+ * the contents read from java.lang.Process.getErrorStream()
+ */
+ public ExecuteResult(int exitValue, String output, String errors) {
+ this.exitValue = exitValue;
+ this.output = output;
+ this.errors = errors;
+ }
+
+ /**
+ * @return the code from java.lang.Process.exitValue()
+ */
+ public int getExitValue() {
+ return exitValue;
+ }
+
+ /**
+ * @return the contents read from java.lang.Process.getInputStream()
+ */
+ public String getOutput() {
+ return output;
+ }
+
+ /**
+ * @return the contents read from java.lang.Process.getErrorStream()
+ */
+ public String getErrors() {
+ return errors;
+ }
+
+ @Override
+ public String toString() {
+ return "ExecuteResult[exitValue="+exitValue+",output="+output+",errors="+errors+"]";
+ }
+
+}
diff --git a/src/main/java/org/owasp/esapi/Executor.java b/src/main/java/org/owasp/esapi/Executor.java
new file mode 100644
index 000000000..122dcdb94
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/Executor.java
@@ -0,0 +1,78 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import java.io.File;
+import java.util.List;
+
+import org.owasp.esapi.codecs.Codec;
+import org.owasp.esapi.errors.ExecutorException;
+
+/**
+ * The Executor interface is used to run an OS command with reduced security risk.
+ *
+ *
Implementations should do as much as possible to minimize the risk of
+ * injection into either the command or parameters. In addition, implementations
+ * should timeout after a specified time period in order to help prevent denial
+ * of service attacks.
+ *
+ *
The class should perform logging and error handling as
+ * well. Finally, implementation should handle errors and generate an
+ * ExecutorException with all the necessary information.
+ *
+ *
The reference implementation does all of the above.
+ *
+ * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @since June 1, 2007
+ */
+public interface Executor {
+
+ /**
+ * Invokes the specified executable with default workdir and codec and not logging parameters.
+ *
+ * @param executable
+ * the command to execute
+ * @param params
+ * the parameters of the command being executed
+ */
+ ExecuteResult executeSystemCommand(File executable, List params) throws ExecutorException;
+
+ /**
+ * Executes a system command after checking that the executable exists and
+ * escaping all the parameters to ensure that injection is impossible.
+ * Implementations must change to the specified working
+ * directory before invoking the command.
+ *
+ * @param executable
+ * the command to execute
+ * @param params
+ * the parameters of the command being executed
+ * @param workdir
+ * the working directory
+ * @param codec
+ * the codec to use to encode for the particular OS in use
+ * @param logParams
+ * use false if any parameters contains sensitive or confidential information
+ *
+ * @return the output of the command being run
+ *
+ * @throws ExecutorException
+ * the service exception
+ */
+ ExecuteResult executeSystemCommand(File executable, List params, File workdir, Codec codec, boolean logParams, boolean redirectErrorStream) throws ExecutorException;
+
+}
diff --git a/src/main/java/org/owasp/esapi/HTTPUtilities.java b/src/main/java/org/owasp/esapi/HTTPUtilities.java
new file mode 100644
index 000000000..582f1a1b7
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/HTTPUtilities.java
@@ -0,0 +1,750 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007-2019 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import org.owasp.esapi.errors.*;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The HTTPUtilities interface is a collection of methods that provide additional security related to HTTP requests,
+ * responses, sessions, cookies, headers, and logging.
+ *
+ * Note: This most of the methods in this interface NOT compatible with the Jakarta Servlet API Spec 5.0 or later, which
+ * uses the jakarta.servlet package namespace rather than the javax.servlet package namespace. For further details,
+ * please see the GitHub Discussion issue
+ * Add support for Jakarta Servlet API Specification #768.
+ *
+ * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @since June 1, 2007
+ */
+public interface HTTPUtilities
+{
+ // All implied static final as this is an interface
+ String REMEMBER_TOKEN_COOKIE_NAME = "rtoken";
+ int MAX_COOKIE_LEN = 4096; // From RFC 2109
+ int MAX_COOKIE_PAIRS = 20; // From RFC 2109
+ String CSRF_TOKEN_NAME = "ctoken";
+ String ESAPI_STATE = "estate";
+
+ int PARAMETER = 0;
+ int HEADER = 1;
+ int COOKIE = 2;
+
+ /**
+ * Calls addCookie with the *current* request.
+ *
+ * @param cookie The cookie to add
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void addCookie(Cookie cookie);
+
+ /**
+ * Add a cookie to the response after ensuring that there are no encoded or
+ * illegal characters in the name and name and value. This method also sets
+ * the secure and HttpOnly flags on the cookie.
+ *
+ * @param response The HTTP response to add the cookie to
+ * @param cookie The cookie to add
+ */
+ void addCookie(HttpServletResponse response, Cookie cookie);
+
+ /**
+ * Adds the current user's CSRF token (see User.getCSRFToken()) to the URL for purposes of preventing CSRF attacks.
+ * This method should be used on all URLs to be put into all links and forms the application generates.
+ *
+ * @param href the URL to which the CSRF token will be appended
+ * @return the updated URL with the CSRF token parameter added
+ */
+ String addCSRFToken(String href);
+
+ /**
+ * Calls addHeader with the *current* request.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void addHeader(String name, String value);
+
+ /**
+ * Add a header to the response after ensuring that there are no encoded or
+ * illegal characters in the name and name and value. This implementation
+ * follows the following recommendation: "A recipient MAY replace any linear
+ * white space with a single SP before interpreting the field value or
+ * forwarding the message downstream."
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
+ *
+ * @param name
+ * @param value
+ */
+ void addHeader(HttpServletResponse response, String name, String value);
+
+ /**
+ * Calls assertSecureRequest with the *current* request.
+ * @see HTTPUtilities#assertSecureRequest(HttpServletRequest)
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void assertSecureRequest() throws AccessControlException;
+
+ /**
+ * Calls assertSecureChannel with the *current* request.
+ * @see HTTPUtilities#assertSecureChannel(HttpServletRequest)
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void assertSecureChannel() throws AccessControlException;
+
+ /**
+ * Ensures that the request uses both SSL and POST to protect any sensitive parameters
+ * in the querystring from being sniffed, logged, bookmarked, included in referer header, etc...
+ * This method should be called for any request that contains sensitive data from a web form.
+ *
+ * @param request
+ * @throws AccessControlException if security constraints are not met
+ */
+ void assertSecureRequest(HttpServletRequest request) throws AccessControlException;
+
+ /**
+ * Ensures the use of SSL to protect any sensitive parameters in the request and
+ * any sensitive data in the response. This method should be called for any request
+ * that contains sensitive data from a web form or will result in sensitive data in the
+ * response page.
+ *
+ * @param request
+ * @throws AccessControlException if security constraints are not met
+ */
+ void assertSecureChannel(HttpServletRequest request) throws AccessControlException;
+
+ /**
+ * Calls changeSessionIdentifier with the *current* request.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ HttpSession changeSessionIdentifier() throws AuthenticationException;
+
+ /**
+ * Invalidate the existing session after copying all of its contents to a newly created session with a new session id.
+ * Note that this is different from logging out and creating a new session identifier that does not contain the
+ * existing session contents. Care should be taken to use this only when the existing session does not contain
+ * hazardous contents.
+ *
+ * @param request
+ * @return the new HttpSession with a changed id
+ * @throws AuthenticationException the exception
+ */
+ HttpSession changeSessionIdentifier(HttpServletRequest request) throws AuthenticationException;
+
+ /**
+ * Clears the current HttpRequest and HttpResponse associated with the current thread.
+ *
+ * @see ESAPI#clearCurrent()
+ */
+ void clearCurrent();
+
+ /**
+ * Decrypts an encrypted hidden field value and returns the cleartext. If the field does not decrypt properly,
+ * an IntrusionException is thrown to indicate tampering.
+ *
+ * @param encrypted hidden field value to decrypt
+ * @return decrypted hidden field value stored as a String
+ */
+ String decryptHiddenField(String encrypted);
+
+ /**
+ * Takes an encrypted querystring and returns a Map containing the original parameters.
+ *
+ * @param encrypted the encrypted querystring to decrypt
+ * @return a Map object containing the decrypted querystring
+ * @throws EncryptionException
+ */
+ Map decryptQueryString(String encrypted) throws EncryptionException;
+
+ /**
+ * Calls decryptStateFromCookie with the *current* request.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ Map decryptStateFromCookie() throws EncryptionException;
+
+ /**
+ * Retrieves a map of data from a cookie encrypted with encryptStateInCookie().
+ *
+ * @param request
+ * @return a map containing the decrypted cookie state value
+ * @throws EncryptionException
+ */
+ Map decryptStateFromCookie(HttpServletRequest request) throws EncryptionException;
+
+ /**
+ * Encrypts a hidden field value for use in HTML.
+ *
+ * @param value the cleartext value of the hidden field
+ * @return the encrypted value of the hidden field
+ * @throws EncryptionException
+ */
+ String encryptHiddenField(String value) throws EncryptionException;
+
+ /**
+ * Takes a querystring (everything after the question mark in the URL) and returns an encrypted string containing the parameters.
+ *
+ * @param query the querystring to encrypt
+ * @return encrypted querystring stored as a String
+ * @throws EncryptionException
+ */
+ String encryptQueryString(String query) throws EncryptionException;
+
+ /**
+ * Calls encryptStateInCookie with the *current* response.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void encryptStateInCookie(Map cleartext) throws EncryptionException;
+
+ /**
+ * Stores a Map of data in an encrypted cookie. Generally the session is a better
+ * place to store state information, as it does not expose it to the user at all.
+ * If there is a requirement not to use sessions, or the data should be stored
+ * across sessions (for a long time), the use of encrypted cookies is an effective
+ * way to prevent the exposure.
+ *
+ * @param response
+ * @param cleartext
+ * @throws EncryptionException
+ */
+ void encryptStateInCookie(HttpServletResponse response, Map cleartext) throws EncryptionException;
+
+ /**
+ * Calls getCookie with the *current* response.
+ *
+ * @param name The cookie to get
+ * @return the requested cookie value
+ * @throws ValidationException
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ String getCookie(String name) throws ValidationException;
+
+ /**
+ * A safer replacement for getCookies() in HttpServletRequest that returns the canonicalized
+ * value of the named cookie after "global" validation against the
+ * general type defined in ESAPI.properties. This should not be considered a replacement for
+ * more specific validation.
+ *
+ * @param request
+ * @param name The cookie to get
+ * @return the requested cookie value
+ * @throws ValidationException
+ */
+ String getCookie(HttpServletRequest request, String name) throws ValidationException;
+
+ /**
+ * Returns the current user's CSRF token. If there is no current user then return null.
+ *
+ * @return the current user's CSRF token
+ */
+ String getCSRFToken();
+
+ /**
+ * Retrieves the current HttpServletRequest
+ *
+ * @return the current request
+ */
+ HttpServletRequest getCurrentRequest();
+
+ /**
+ * Retrieves the current HttpServletResponse
+ *
+ * @return the current response
+ */
+ HttpServletResponse getCurrentResponse();
+
+ /**
+ * Calls {@code getFileUploads} with the current request, default upload directory, and default allowed file extensions
+ *
+ * @return List of new File objects from upload
+ * @throws ValidationException if the file fails validation
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ List getFileUploads() throws ValidationException;
+
+ /**
+ * Call {@code getFileUploads} with the specified request, default upload directory, and default allowed file extensions
+ *
+ * @param request The applicable HTTP request
+ *
+ * @return List of new File objects from upload
+ * @throws ValidationException if the file fails validation
+ */
+ List getFileUploads(HttpServletRequest request) throws ValidationException;
+
+ /**
+ * Call {@code getFileUploads} with the specified request, specified upload directory, and default allowed file extensions
+ *
+ * @param request The applicable HTTP request
+ * @param finalDir The destination directory to leave the uploaded file(s) in.
+ *
+ * @return List of new File objects from upload
+ * @throws ValidationException if the file fails validation
+ */
+ List getFileUploads(HttpServletRequest request, File finalDir) throws ValidationException;
+
+
+ /**
+ * Extract uploaded files from a multipart/form-data HTTP request. Implementations must check the content to ensure that it
+ * is safe before making a permanent copy on the local filesystem. Checks should include length and content checks,
+ * possibly virus checking, and path and name checks. Refer to the file checking methods in Validator for more
+ * information. Important Note: The ESAPI reference implementation (i.e.,
+ * {@code org.owasp.esapi.referenceDefaultHTTPUtilities} only does some of these things listed above and some of those
+ * are limited to which {@code getFileUploads} method is called and how you've set your relevant ESAPI properties
+ * in your ESAPI.properties file.
+ *
+ * This method uses {@link HTTPUtilities#getCurrentRequest()} to obtain the
+ * {@link javax.servlet.http.HttpServletRequest HttpServletRequest}
+ * object. If the ESAPI property HttpUtilities.FileUploadAllowAnonymousUser is set to {@code false} (the
+ * default is {@code true}), then {@code getFileUploads} will call {@code ESAPI.authenticator().getCurrentUser()}
+ * to check if the user is authenticated. If that property is set to {@code false} and a call to that function returns
+ * an anonymous (i.e., unauthenticated) user, then the file upload is blocked.
+ *
+ * ESAPI properties relevant to this and the other {@code getFileUploads} methods referenced in this table. The
+ * last 2 properties are new since release 2.5.2.0:
+ *
Comma separated allowed list of file suffixes that may be uploaded.
+ *
+ *
+ *
HttpUtilities.MaxUploadFileBytes
+ *
5000000
+ *
5000000
+ *
Total maximum upload file size for uploaded files per HTTP request.
+ *
+ *
+ *
HttpUtilities.MaxUploadFileCount
+ *
20
+ *
20
+ *
Maximum total number of uploaded files per HTTP request.
+ *
+ *
+ *
HttpUtilities.FileUploadAllowAnonymousUser
+ *
true
+ *
true
+ *
Controls whether anonymous (i.e., unauthenticated) users may upload files.
+ *
+ *
+ *
+ * As alluded to above, it is important to note that these {@code getFileUploads} methods do not do
+ * everything to keey your application and environment secure. Some of the more obvious omissions are the
+ * absence of examining the actual file content to determine the actual file type or running some AV scan
+ * on the uploaded files. You have to add that functionality to you if you want or need that. Some
+ * resource that you may find useful are:
+ *
+ *
+ * @param request The applicable HTTP request
+ * @param destinationDir The destination directory to leave the uploaded file in.
+ * @param allowedExtensions Permitted file suffixes. (Yes, this is a weak check. Use Apache Tika if you
+ * want something more.)
+ * @return List of new {@code File} objects from upload
+ * @throws ValidationException if the file fails validation
+ * @throws java.security.AccessControlException If anonymous users are not allowed and the user is
+ * not authenticated as per the ESAPI {@code Authenticator}.
+ */
+ List getFileUploads(HttpServletRequest request, File destinationDir, List allowedExtensions) throws ValidationException;
+
+
+ /**
+ * Calls getHeader with the *current* request.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ String getHeader(String name) throws ValidationException;
+
+ /**
+ * A safer replacement for getHeader() in HttpServletRequest that returns the canonicalized
+ * value of the named header after "global" validation against the
+ * general type defined in ESAPI.properties. This should not be considered a replacement for
+ * more specific validation.
+ *
+ * @param request
+ * @param name
+ * @return the requested header value
+ */
+ String getHeader(HttpServletRequest request, String name) throws ValidationException;
+
+ /**
+ * Calls getParameter with the *current* request.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ String getParameter(String name) throws ValidationException;
+
+ /**
+ * A safer replacement for getParameter() in HttpServletRequest that returns the canonicalized
+ * value of the named parameter after "global" validation against the
+ * general type defined in ESAPI.properties. This should not be considered a replacement for
+ * more specific validation.
+ *
+ * @param request
+ * @param name
+ * @return the requested parameter value
+ */
+ String getParameter(HttpServletRequest request, String name) throws ValidationException;
+
+ /**
+ * Calls killAllCookies with the *current* request and response.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void killAllCookies();
+
+ /**
+ * Kill all cookies received in the last request from the browser. Note that new cookies set by the application in
+ * this response may not be killed by this method.
+ *
+ * @param request
+ * @param response
+ */
+ void killAllCookies(HttpServletRequest request, HttpServletResponse response);
+
+ /**
+ * Calls killCookie with the *current* request and response.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void killCookie(String name);
+
+ /**
+ * Kills the specified cookie by setting a new cookie that expires immediately. Note that this
+ * method does not delete new cookies that are being set by the application for this response.
+ *
+ * @param request
+ * @param name
+ * @param response
+ */
+ void killCookie(HttpServletRequest request, HttpServletResponse response, String name);
+
+ /**
+ * Calls logHTTPRequest with the *current* request and logger.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void logHTTPRequest();
+
+ /**
+ * Format the Source IP address, URL, URL parameters, and all form
+ * parameters into a string suitable for the log file. Be careful not
+ * to log sensitive information, and consider masking with the
+ * logHTTPRequest( List parameterNamesToObfuscate ) method.
+ *
+ * @param request
+ * @param logger the logger to write the request to
+ */
+ void logHTTPRequest(HttpServletRequest request, Logger logger);
+
+ /**
+ * Format the Source IP address, URL, URL parameters, and all form
+ * parameters into a string suitable for the log file. The list of parameters to
+ * obfuscate should be specified in order to prevent sensitive information
+ * from being logged. If a null list is provided, then all parameters will
+ * be logged. If HTTP request logging is done in a central place, the
+ * parameterNamesToObfuscate could be made a configuration parameter. We
+ * include it here in case different parts of the application need to obfuscate
+ * different parameters.
+ *
+ * @param request The HTTP request to log
+ * @param logger the logger to write the request to
+ * @param parameterNamesToObfuscate the sensitive parameters
+ */
+ void logHTTPRequest(HttpServletRequest request, Logger logger, List parameterNamesToObfuscate);
+
+ /**
+ * Calls sendForward with the *current* request and response.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void sendForward(String location) throws AccessControlException, ServletException, IOException;
+
+ /**
+ * This method performs a forward to any resource located inside the WEB-INF directory. Forwarding to
+ * publicly accessible resources can be dangerous, as the request will have already passed the URL
+ * based access control check. This method ensures that you can only forward to non-publicly
+ * accessible resources.
+ *
+ * @param request
+ * @param response
+ * @param location the URL to forward to, including parameters
+ * @throws AccessControlException
+ * @throws ServletException
+ * @throws IOException
+ */
+ void sendForward(HttpServletRequest request, HttpServletResponse response, String location) throws AccessControlException, ServletException, IOException;
+
+
+ /**
+ * Calls sendRedirect with the *current* response.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void sendRedirect(String location) throws AccessControlException, IOException;
+
+
+ /**
+ * This method performs a forward to any resource located inside the WEB-INF directory. Forwarding to
+ * publicly accessible resources can be dangerous, as the request will have already passed the URL
+ * based access control check. This method ensures that you can only forward to non-publicly
+ * accessible resources.
+ *
+ * @param response
+ * @param location the URL to forward to, including parameters
+ * @throws AccessControlException
+ * @throws IOException
+ */
+ void sendRedirect(HttpServletResponse response, String location) throws AccessControlException, IOException;
+
+ /**
+ * Calls setContentType with the *current* request and response.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void setContentType();
+
+ /**
+ * Set the content type character encoding header on every HttpServletResponse in order to limit
+ * the ways in which the input data can be represented. This prevents
+ * malicious users from using encoding and multi-byte escape sequences to
+ * bypass input validation routines.
+ *
+ * Implementations of this method should set the content type header to a safe value for your environment.
+ * The default is text/html; charset=UTF-8 character encoding, which is the default in early
+ * versions of HTML and HTTP. See RFC 2047 (http://ds.internic.net/rfc/rfc2045.txt) for more
+ * information about character encoding and MIME.
+ *
+ * The DefaultHTTPUtilities reference implementation sets the content type as specified.
+ *
+ * @param response The servlet response to set the content type for.
+ */
+ void setContentType(HttpServletResponse response);
+
+ /**
+ * Stores the current HttpRequest and HttpResponse so that they may be readily accessed throughout
+ * ESAPI (and elsewhere)
+ *
+ * @param request the current request
+ * @param response the current response
+ */
+ void setCurrentHTTP(HttpServletRequest request, HttpServletResponse response);
+
+
+ /**
+ * Calls setHeader with the *current* response.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void setHeader(String name, String value);
+
+ /**
+ * Add a header to the response after ensuring that there are no encoded or
+ * illegal characters in the name and value. "A recipient MAY replace any
+ * linear white space with a single SP before interpreting the field value
+ * or forwarding the message downstream."
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
+ *
+ * @param name
+ * @param value
+ */
+ void setHeader(HttpServletResponse response, String name, String value);
+
+
+ /**
+ * Calls setNoCacheHeaders with the *current* response.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void setNoCacheHeaders();
+
+
+ /**
+ * Set headers to protect sensitive information against being cached in the browser. Developers should make this
+ * call for any HTTP responses that contain any sensitive data that should not be cached within the browser or any
+ * intermediate proxies or caches. Implementations should set headers for the expected browsers. The safest approach
+ * is to set all relevant headers to their most restrictive setting. These include:
+ *
+ *
+ *
+ * Note that the header "pragma: no-cache" is intended only for use in HTTP requests, not HTTP responses. However, Microsoft has chosen to
+ * directly violate the standards, so we need to include that header here. For more information, please refer to the relevant standards:
+ *
+ *
+ * @param response
+ */
+ void setNoCacheHeaders(HttpServletResponse response);
+
+ /**
+ * Calls setNoCacheHeaders with the *current* response.
+ *
+ * ~DEPRECATED~ Per Kevin Wall, storing passwords with reversible encryption is contrary to *many*
+ * company's stated security policies.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ @Deprecated
+ String setRememberToken(String password, int maxAge, String domain, String path);
+
+ /**
+ *
+ */
+ String setRememberToken(HttpServletRequest request, HttpServletResponse response, int maxAge, String domain, String path);
+
+
+ /**
+ * Set a cookie containing the current User's remember me token for automatic authentication. The use of remember me tokens
+ * is generally not recommended, but this method will help do it as safely as possible. The user interface should strongly warn
+ * the user that this should only be enabled on computers where no other users will have access.
+ *
+ * Implementations should save the user's remember me data in an encrypted cookie and send it to the user.
+ * Any old remember me cookie should be destroyed first. Setting this cookie should keep the user
+ * logged in until the maxAge passes, the password is changed, or the cookie is deleted.
+ * If the cookie exists for the current user, it should automatically be used by ESAPI to
+ * log the user in, if the data is valid and not expired.
+ *
+ * The ESAPI reference implementation, DefaultHTTPUtilities.setRememberToken() implements all these suggestions.
+ *
+ * The username can be retrieved with: User username = ESAPI.authenticator().getCurrentUser();
+ *
+ *~DEPRECATED~ Per Kevin Wall, storing passwords with reversible encryption is contrary to *many*
+ * company's stated security policies.
+ *
+ * @param request
+ * @param password the user's password
+ * @param response
+ * @param maxAge the length of time that the token should be valid for in relative seconds
+ * @param domain the domain to restrict the token to or null
+ * @param path the path to restrict the token to or null
+ * @return encrypted "Remember Me" token stored as a String
+ */
+ @Deprecated
+ String setRememberToken(HttpServletRequest request, HttpServletResponse response, String password, int maxAge, String domain, String path);
+
+
+ /**
+ * Calls verifyCSRFToken with the *current* request.
+ *
+ * @see HTTPUtilities#setCurrentHTTP(HttpServletRequest, HttpServletResponse)
+ */
+ void verifyCSRFToken();
+
+ /**
+ * Checks the CSRF token in the URL (see User.getCSRFToken()) against the user's CSRF token and
+ * throws an IntrusionException if it is missing.
+ *
+ * @param request
+ * @throws IntrusionException if CSRF token is missing or incorrect
+ */
+ void verifyCSRFToken(HttpServletRequest request) throws IntrusionException;
+
+ /**
+ * Gets a typed attribute from the session associated with the calling thread. If the
+ * object referenced by the passed in key is not of the implied type, a ClassCastException
+ * will be thrown to the calling code.
+ *
+ * @param key
+ * The key that references the session attribute
+ * @return The requested object.
+ * @see HTTPUtilities#getSessionAttribute(javax.servlet.http.HttpSession, String)
+ */
+ T getSessionAttribute( String key );
+
+ /**
+ * Gets a typed attribute from the passed in session. This method has the same
+ * responsibility as {link #getSessionAttribute(String} however it only references
+ * the passed in session and thus performs slightly better since it does not need
+ * to return to the Thread to get the {@link HttpSession} associated with the current
+ * thread.
+ *
+ * @param session
+ * The session to retrieve the attribute from
+ * @param key
+ * The key that references the requested object
+ * @return The requested object
+ */
+ T getSessionAttribute( HttpSession session, String key );
+
+ /**
+ * Gets a typed attribute from the {@link HttpServletRequest} associated
+ * with the caller thread. If the attribute on the request is not of the implied
+ * type, a ClassCastException will be thrown back to the caller.
+ *
+ * @param key The key that references the request attribute.
+ * @return The requested object
+ */
+ T getRequestAttribute( String key );
+
+ /**
+ * Gets a typed attribute from the {@link HttpServletRequest} associated
+ * with the passed in request. If the attribute on the request is not of the implied
+ * type, a ClassCastException will be thrown back to the caller.
+ *
+ * @param request The request to retrieve the attribute from
+ * @param key The key that references the request attribute.
+ * @return The requested object
+ */
+ T getRequestAttribute( HttpServletRequest request, String key );
+}
diff --git a/src/main/java/org/owasp/esapi/IntrusionDetector.java b/src/main/java/org/owasp/esapi/IntrusionDetector.java
new file mode 100644
index 000000000..ccb2bc984
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/IntrusionDetector.java
@@ -0,0 +1,63 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import org.owasp.esapi.errors.IntrusionException;
+
+
+/**
+ * The IntrusionDetector interface is intended to track security relevant events and identify attack behavior. The
+ * implementation can use as much state as necessary to detect attacks, but note that storing too much state will burden
+ * your system.
+ *
+ * The interface is currently designed to accept exceptions as well as custom events. Implementations can use this
+ * stream of information to detect both normal and abnormal behavior.
+ *
+ * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @since June 1, 2007
+ */
+public interface IntrusionDetector {
+
+ /**
+ * Adds the exception to the IntrusionDetector. This method should immediately log the exception so that developers throwing an
+ * IntrusionException do not have to remember to log every error. The implementation should store the exception somewhere for the current user
+ * in order to check if the User has reached the threshold for any Enterprise Security Exceptions. The User object is the recommended location for storing
+ * the current user's security exceptions. If the User has reached any security thresholds, the appropriate security action can be taken and logged.
+ *
+ * @param exception
+ * the exception thrown
+ *
+ * @throws IntrusionException
+ * the intrusion exception
+ */
+ void addException(Exception exception) throws IntrusionException;
+
+ /**
+ * Adds the event to the IntrusionDetector. This method should immediately log the event. The implementation should store the event somewhere for the current user
+ * in order to check if the User has reached the threshold for any Enterprise Security Exceptions. The User object is the recommended location for storing
+ * the current user's security event. If the User has reached any security thresholds, the appropriate security action can be taken and logged.
+ *
+ * @param eventName
+ * the event to add
+ * @param logMessage
+ * the message to log with the event
+ *
+ * @throws IntrusionException
+ * the intrusion exception
+ */
+ void addEvent(String eventName, String logMessage) throws IntrusionException;
+
+}
diff --git a/src/main/java/org/owasp/esapi/LogFactory.java b/src/main/java/org/owasp/esapi/LogFactory.java
new file mode 100644
index 000000000..7571ea460
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/LogFactory.java
@@ -0,0 +1,60 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Rogan DawesAspect Security
+ * @created 2008
+ */
+package org.owasp.esapi;
+
+/**
+ * The LogFactory interface is intended to allow substitution of various logging packages, while providing
+ * a common interface to access them.
+ *
+ * In the reference implementation, JavaLogFactory.java implements this interface. JavaLogFactory.java also contains an
+ * inner class called JavaLogger which implements Logger.java and uses the Java logging package to log events.
+ *
+ * @see org.owasp.esapi.ESAPI
+ *
+ * @author rdawes
+ *
+ */
+public interface LogFactory {
+
+ /**
+ * Gets the logger associated with the specified module name. The module name is used by the logger to log which
+ * module is generating the log events. The implementation of this method should return any preexisting Logger
+ * associated with this module name, rather than creating a new Logger.
+ *
+ * The JavaLogFactory reference implementation meets these requirements.
+ *
+ * @param moduleName
+ * The name of the module requesting the logger.
+ * @return
+ * The Logger associated with this module.
+ */
+ Logger getLogger(String moduleName);
+
+ /**
+ * Gets the logger associated with the specified class. The class is used by the logger to log which
+ * class is generating the log events. The implementation of this method should return any preexisting Logger
+ * associated with this class name, rather than creating a new Logger.
+ *
+ * The JavaLogFactory reference implementation meets these requirements.
+ *
+ * @param clazz
+ * The name of the class requesting the logger.
+ * @return
+ * The Logger associated with this class.
+ */
+ Logger getLogger(Class clazz);
+
+}
diff --git a/src/main/java/org/owasp/esapi/Logger.java b/src/main/java/org/owasp/esapi/Logger.java
new file mode 100644
index 000000000..b0a5b7ccc
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/Logger.java
@@ -0,0 +1,433 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007-2019 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+/**
+ * The {@code Logger} interface defines a set of methods that can be used to log
+ * security events. It supports a hierarchy of logging levels which can be configured at runtime to determine
+ * the severity of events that are logged, and those below the current threshold that are discarded.
+ * Implementors should use a well established logging library
+ * as it is quite difficult to create a high-performance logger.
+ *
+ * The logging levels defined by this interface (in descending order) are:
+ *
+ *
fatal (highest value)
+ *
error
+ *
warning
+ *
info
+ *
debug
+ *
trace (lowest value)
+ *
+ * There are also several variations of {@code always()} methods that will always
+ * log a message regardless of the log level.
+ *
+ * ESAPI also allows for the definition of the type of log event that is being generated.
+ * The {@code Logger} interface predefines 6 types of Log events:
+ *
+ *
SECURITY_SUCCESS
+ *
SECURITY_FAILURE
+ *
SECURITY_AUDIT
+ *
EVENT_SUCCESS
+ *
EVENT_FAILURE
+ *
EVENT_UNSPECIFIED
+ *
+ *
+ * Your custom implementation can extend or change this list if desired.
+ *
+ * This {@code Logger} allows callers to determine which logging levels are enabled, and to submit events
+ * at different severity levels.
+ * Implementors of this interface should:
+ *
+ *
+ *
Provide a mechanism for setting the logging level threshold that is currently enabled. This usually works by logging all
+ * events at and above that severity level, and discarding all events below that level.
+ * This is usually done via configuration, but can also be made accessible programmatically.
+ *
Ensure that dangerous HTML characters are encoded before they are logged to defend against malicious injection into logs
+ * that might be viewed in an HTML based log viewer.
+ *
Encode any CRLF characters included in log data in order to prevent log injection attacks.
+ *
Avoid logging the user's session ID. Rather, they should log something equivalent like a
+ * generated logging session ID, or a hashed value of the session ID so they can track session specific
+ * events without risking the exposure of a live session's ID.
+ *
Record the following information with each event:
+ *
+ *
Identity of the user that caused the event.
+ *
A description of the event (supplied by the caller).
+ *
Whether the event succeeded or failed (indicated by the caller).
+ *
Severity level of the event (indicated by the caller).
+ *
That this is a security relevant event (indicated by the caller).
+ *
Hostname or IP where the event occurred (and ideally the user's source IP as well).
Filter out any sensitive data specific to the current application or organization, such as credit cards,
+ * social security numbers, etc.
+ *
+ *
+ * There are both SLF4J and native Java Logging (i.e., {@code java.util.logging}, aka JUL) implementations
+ * of the ESAPI logger with JUL being our default logger for our stock ESAPI.properties file that
+ * is delivered along with ESAPI releases in a separate esapi-configuration jar available from the
+ * releases mentioned on
+ * ESAPI's GitHub Releases page.
+ *
+ * The {@code org.owasp.esapi.logging.java.JavaLogger} class uses the {@code java.util.logging} package as
+ * the basis for its logging implementation. Both provided implementations implement requirements #1 through #5 above.
+ *
+ * Customization: It is expected that most organizations may wish to implement their own custom {@code Logger} class in
+ * order to integrate ESAPI logging with their specific logging infrastructure. The ESAPI reference implementations
+ * can serve as a useful starting point to intended to provide a simple functional example of an implementation, but
+ * they are also largely usable out-of-the-box with some additional minimal log configuration.
+ *
+ * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @since June 1, 2007
+ */
+public interface Logger {
+
+ // All implied static final as this is an interface
+
+ /**
+ * A security type of log event that has succeeded. This is one of 6 predefined
+ * ESAPI logging events. New events can be added.
+ */
+ EventType SECURITY_SUCCESS = new EventType( "SECURITY SUCCESS", true);
+
+ /**
+ * A security type of log event that has failed. This is one of 6 predefined
+ * ESAPI logging events. New events can be added.
+ */
+ EventType SECURITY_FAILURE = new EventType( "SECURITY FAILURE", false);
+
+ /**
+ * A security type of log event that is associated with an audit trail of some type,
+ * but the log event is not specifically something that has either succeeded or failed
+ * or that is irrelevant in the case of this logged message.
+ */
+ // CHECKME: Should the Boolean for this be 'null' or 'true'? See EVENT_UNSPECIFIED.
+ EventType SECURITY_AUDIT = new EventType( "SECURITY AUDIT", null);
+
+ /**
+ * A non-security type of log event that has succeeded. This is one of 6 predefined
+ * ESAPI logging events. New events can be added.
+ */
+ EventType EVENT_SUCCESS = new EventType( "EVENT SUCCESS", true);
+
+ /**
+ * A non-security type of log event that has failed. This is one of 6 predefined
+ * ESAPI logging events. New events can be added.
+ */
+ EventType EVENT_FAILURE = new EventType( "EVENT FAILURE", false);
+
+ /**
+ * A non-security type of log event that is unspecified. This is one of 6 predefined
+ * ESAPI logging events. New events can be added.
+ */
+ EventType EVENT_UNSPECIFIED = new EventType( "EVENT UNSPECIFIED", null);
+
+ /**
+ * Defines the type of log event that is being generated. The Logger interface defines 6 types of Log events:
+ * SECURITY_SUCCESS, SECURITY_FAILURE, EVENT_SUCCESS, EVENT_FAILURE, EVENT_UNSPECIFIED.
+ * Your implementation can extend or change this list if desired.
+ */
+ class EventType {
+
+ private String type;
+ private Boolean success = null;
+
+ public EventType (String name, Boolean newSuccess) {
+ this.type = name;
+ this.success = newSuccess;
+ }
+
+ public Boolean isSuccess() {
+ return success;
+ }
+
+ /**
+ * Convert the {@code EventType} to a string.
+ * @return The event type name.
+ */
+ @Override
+ public String toString() {
+ return this.type;
+ }
+ }
+
+ /*
+ * The Logger interface defines 6 logging levels: FATAL, ERROR, WARNING, INFO, DEBUG, TRACE. It also
+ * supports ALL, which logs all events, and OFF, which disables all logging.
+ * Your implementation can extend or change this list if desired.
+ */
+
+ /** OFF indicates that no messages should be logged. This level is initialized to Integer.MAX_VALUE. */
+ int OFF = Integer.MAX_VALUE;
+
+ /** FATAL indicates that only FATAL messages should be logged. This level is initialized to 1000. */
+ int FATAL = 1000;
+
+ /** ERROR indicates that ERROR messages and above should be logged.
+ * This level is initialized to 800. */
+ int ERROR = 800;
+
+ /** WARNING indicates that WARNING messages and above should be logged.
+ * This level is initialized to 600. */
+ int WARNING = 600;
+
+ /** INFO indicates that INFO messages and above should be logged.
+ * This level is initialized to 400. */
+ int INFO = 400;
+
+ /** DEBUG indicates that DEBUG messages and above should be logged.
+ * This level is initialized to 200. */
+ int DEBUG = 200;
+
+ /** TRACE indicates that TRACE messages and above should be logged.
+ * This level is initialized to 100. */
+ int TRACE = 100;
+
+ /** ALL indicates that all messages should be logged. This level is initialized to Integer.MIN_VALUE. */
+ int ALL = Integer.MIN_VALUE;
+
+
+ /**
+ * Dynamically set the ESAPI logging severity level. All events of this level and higher will be logged from
+ * this point forward for all logs. All events below this level will be discarded.
+ *
+ * @param level The level to set the logging level to.
+ */
+ void setLevel(int level);
+
+ /** Retrieve the current ESAPI logging level for this logger.
+ *
+ * @return The current logging level.
+ */
+ int getESAPILevel();
+
+ /**
+ * Log a fatal event if 'fatal' level logging is enabled.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ */
+ void fatal(EventType type, String message);
+
+ /**
+ * Log a fatal level security event if 'fatal' level logging is enabled
+ * and also record the stack trace associated with the event.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ * @param throwable
+ * the exception to be logged
+ */
+ void fatal(EventType type, String message, Throwable throwable);
+
+ /**
+ * Allows the caller to determine if messages logged at this level
+ * will be discarded, to avoid performing expensive processing.
+ *
+ * @return true if fatal level messages will be output to the log
+ */
+ boolean isFatalEnabled();
+
+ /**
+ * Log an error level security event if 'error' level logging is enabled.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ */
+ void error(EventType type, String message);
+
+ /**
+ * Log an error level security event if 'error' level logging is enabled
+ * and also record the stack trace associated with the event.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ * @param throwable
+ * the exception to be logged
+ */
+ void error(EventType type, String message, Throwable throwable);
+
+ /**
+ * Allows the caller to determine if messages logged at this level
+ * will be discarded, to avoid performing expensive processing.
+ *
+ * @return true if error level messages will be output to the log
+ */
+ boolean isErrorEnabled();
+
+ /**
+ * Log a warning level security event if 'warning' level logging is enabled.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ */
+ void warning(EventType type, String message);
+
+ /**
+ * Log a warning level security event if 'warning' level logging is enabled
+ * and also record the stack trace associated with the event.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ * @param throwable
+ * the exception to be logged
+ */
+ void warning(EventType type, String message, Throwable throwable);
+
+ /**
+ * Allows the caller to determine if messages logged at this level
+ * will be discarded, to avoid performing expensive processing.
+ *
+ * @return true if warning level messages will be output to the log
+ */
+ boolean isWarningEnabled();
+
+ /**
+ * Log an info level security event if 'info' level logging is enabled.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ */
+ void info(EventType type, String message);
+
+ /**
+ * Log an info level security event if 'info' level logging is enabled
+ * and also record the stack trace associated with the event.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ * @param throwable
+ * the exception to be logged
+ */
+ void info(EventType type, String message, Throwable throwable);
+
+ /**
+ * Allows the caller to determine if messages logged at this level
+ * will be discarded, to avoid performing expensive processing.
+ *
+ * @return true if info level messages will be output to the log
+ */
+ boolean isInfoEnabled();
+
+ /**
+ * Log a debug level security event if 'debug' level logging is enabled.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ */
+ void debug(EventType type, String message);
+
+ /**
+ * Log a debug level security event if 'debug' level logging is enabled
+ * and also record the stack trace associated with the event.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ * @param throwable
+ * the exception to be logged
+ */
+ void debug(EventType type, String message, Throwable throwable);
+
+ /**
+ * Allows the caller to determine if messages logged at this level
+ * will be discarded, to avoid performing expensive processing.
+ *
+ * @return true if debug level messages will be output to the log
+ */
+ boolean isDebugEnabled();
+
+ /**
+ * Log a trace level security event if 'trace' level logging is enabled.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ */
+ void trace(EventType type, String message);
+
+ /**
+ * Log a trace level security event if 'trace' level logging is enabled
+ * and also record the stack trace associated with the event.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ * @param throwable
+ * the exception to be logged
+ */
+ void trace(EventType type, String message, Throwable throwable);
+
+ /**
+ * Allows the caller to determine if messages logged at this level
+ * will be discarded, to avoid performing expensive processing.
+ *
+ * @return true if trace level messages will be output to the log
+ */
+ boolean isTraceEnabled();
+
+ /**
+ * Log an event regardless of what logging level is enabled.
+ *
+ * Note that logging will not occur if the underlying logging implementation has logging disabled.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ */
+ void always(EventType type, String message);
+
+ /**
+ * Log an event regardless of what logging level is enabled
+ * and also record the stack trace associated with the event.
+ *
+ * Note that logging will not occur if the underlying logging implementation has logging disabled.
+ *
+ * @param type
+ * the type of event
+ * @param message
+ * the message to log
+ * @param throwable
+ * the exception to be logged
+ */
+ void always(EventType type, String message, Throwable throwable);
+}
diff --git a/src/main/java/org/owasp/esapi/PreparedString.java b/src/main/java/org/owasp/esapi/PreparedString.java
new file mode 100644
index 000000000..5102a324c
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/PreparedString.java
@@ -0,0 +1,137 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007-2019 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2009
+ */
+package org.owasp.esapi;
+
+import java.util.ArrayList;
+import org.owasp.esapi.codecs.Codec;
+
+/**
+ * A parameterized string that uses escaping to make untrusted data safe before combining it with
+ * a command or query intended for use in an interpreter.
+ *
+ * PreparedString div = new PreparedString( "<a href=\"http:\\\\example.com?id=?\" onmouseover=\"alert('?')\">test</a>", new HTMLEntityCodec() );
+ * div.setURL( 1, request.getParameter( "url" ), new PercentCodec() );
+ * div.set( 2, request.getParameter( "message" ), new JavaScriptCodec() );
+ * out.println( div.toString() );
+ *
+ * // escaping for SQL
+ * PreparedString query = new PreparedString( "SELECT * FROM users WHERE name='?' AND password='?'", new OracleCodec() );
+ * query.set( 1, request.getParameter( "name" ) );
+ * query.set( 2, request.getParameter( "pass" ) );
+ * stmt.execute( query.toString() );
+ *
+ *
+ * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @since June 1, 2007
+ */
+public class PreparedString {
+ char parameterCharacter = '?';
+ Codec codec = null;
+ String[] parameters = null;
+ ArrayList parts = new ArrayList();
+ private final static char[] IMMUNE = {};
+
+ /**
+ * Create a PreparedString with the supplied template and Codec. The template should use the
+ * default parameter placeholder character (?) in the place where actual parameters are to be inserted.
+ * The supplied Codec will be used to escape characters in calls to set, unless a specific Codec is
+ * provided to override it.
+ * @param template
+ * @param codec
+ */
+ public PreparedString( String template, Codec codec ) {
+ this.codec = codec;
+ split( template, parameterCharacter );
+ }
+
+ /**
+ * Create a PreparedString with the supplied template, parameter placeholder character, and Codec. The parameter character
+ * can be any character, but should not be one that will be used in the template. The parameter character can safely
+ * be used in a parameter passed into the set methods.
+ * @param template
+ * @param parameterCharacter
+ * @param codec
+ */
+ public PreparedString( String template, char parameterCharacter, Codec codec ) {
+ this.codec = codec;
+ this.parameterCharacter = parameterCharacter;
+ split( template, parameterCharacter );
+ }
+
+ /**
+ * Split a string with a particular character.
+ * @param str
+ * @param c
+ */
+ private void split( String str, char c ) {
+ int index = 0;
+ int pcount = 0;
+ for ( int i = 0; i < str.length(); i++ ) {
+ if ( str.charAt(i) == c ) {
+ pcount++;
+ parts.add( str.substring(index,i) );
+ index = i + 1;
+ }
+ }
+ parts.add( str.substring(index) );
+ parameters = new String[pcount];
+ }
+
+ /**
+ * Set the parameter at index with supplied value using the default Codec to escape.
+ * @param index
+ * @param value
+ */
+ public void set( int index, String value ) {
+ if ( index < 1 || index > parameters.length ) {
+ throw new IllegalArgumentException( "Attempt to set parameter " + index + " on a PreparedString with only " + parameters.length + " placeholders" );
+ }
+ String encoded = codec.encode( IMMUNE, value );
+ parameters[index-1] = encoded;
+ }
+
+ /**
+ * Set the parameter at index with supplied value using the supplied Codec to escape.
+ * @param index
+ * @param value
+ * @param codec
+ */
+ public void set( int index, String value, Codec codec ) {
+ if ( index < 1 || index > parameters.length ) {
+ throw new IllegalArgumentException( "Attempt to set parameter " + index + " on a PreparedString with only " + parameters.length + " placeholders" );
+ }
+ String encoded = codec.encode( IMMUNE, value );
+ parameters[index-1] = encoded;
+ }
+
+ /**
+ * Render the PreparedString by combining the template with properly escaped parameters.
+ */
+ public String toString() {
+ for ( int ix = 0; ix < parameters.length; ix++ ) {
+ if ( parameters[ix] == null ) {
+ throw new RuntimeException( "Attempt to render PreparedString without setting parameter " + ( ix + 1 ));
+ }
+ }
+ StringBuilder sb = new StringBuilder();
+ int i = 0;
+ for ( int p=0; p < parts.size(); p++ ) {
+ sb.append( parts.get( p ) );
+ if ( i < parameters.length ) sb.append( parameters[i++] );
+ }
+ return sb.toString();
+ }
+}
diff --git a/src/main/java/org/owasp/esapi/PropNames.java b/src/main/java/org/owasp/esapi/PropNames.java
new file mode 100644
index 000000000..8aa4179a9
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/PropNames.java
@@ -0,0 +1,206 @@
+// TODO: Discuss: Should the name of this be PropConstants or PropertConstants
+// since there are some property values included here? I don't
+// really like that as much as PropNames, but I could live with
+// it.
+/*
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * https://owasp.org/www-project-enterprise-security-api/.
+ *
+ * Copyright (c) 2022 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ */
+package org.owasp.esapi;
+
+
+/**
+ * This non-constructable class of public constants defines all the property names used in {@code ESAPI.properties} as
+ * well as some of the default property values for some of those properties. This class is not intended
+ * to be extended or instantiated. Technically, an interface would have worked here, but we
+ * also wanted to be able to prevent 'implements PropNames', which really does not make much
+ * sense since no specific behavior is promised here. Another alternative would have
+ * been to place all of these in the {@code org.owasp.esapi.SecurityConfiguration} interface,
+ * but that interface is already overly bloated. Hence this was decided as a compromise.
+ *
+ * Note that the constants herein were originally all defined within
+ * {@code org.owasp.esapi.reference.DefaultSecurityConfiguration}, but those
+ * values are now marked deprecated and they are candidates for removal 2 years
+ * from the date of this release.
+ *
+ * Mostly this is intended to prevent having to hard-code property names all
+ * over the place in implementation-level classes (e.g.,
+ * {@code org.owasp.esapi.reference.DefaultSecurityConfiguration}).
+ * It is suggested that this file be used as a 'static import';
+ * e.g.,
+ *
+ * import static org.owasp.esapi.PropNames.*; // Import all properties, en masse
+ * or
+ * import static org.owasp.esapi.PropNames.SomeSpecificPropName; // Import specific property name
+ *
+ * This can be extremely useful when used with methods such as
+ * {@code SecurityConfiguration.getIntProp(String propName)},
+ * {@code SecurityConfiguration.getBooleanProp(String propName)},
+ * {@code SecurityConfiguration.getStringProp(String propName)}, etc.
+ *
+ * @author Kevin W. Wall (kevin.w.wall .at. gmail.com)
+ * @since 2.4.1.0
+ * @see org.owasp.esapi.reference.DefaultSecurityConfiguration
+ */
+
+public final class PropNames {
+
+ public static final String REMEMBER_TOKEN_DURATION = "Authenticator.RememberTokenDuration";
+ public static final String IDLE_TIMEOUT_DURATION = "Authenticator.IdleTimeoutDuration";
+ public static final String ABSOLUTE_TIMEOUT_DURATION = "Authenticator.AbsoluteTimeoutDuration";
+ public static final String ALLOWED_LOGIN_ATTEMPTS = "Authenticator.AllowedLoginAttempts";
+ public static final String USERNAME_PARAMETER_NAME = "Authenticator.UsernameParameterName";
+ public static final String PASSWORD_PARAMETER_NAME = "Authenticator.PasswordParameterName";
+ public static final String MAX_OLD_PASSWORD_HASHES = "Authenticator.MaxOldPasswordHashes";
+
+ public static final String ALLOW_MULTIPLE_ENCODING = "Encoder.AllowMultipleEncoding";
+ public static final String ALLOW_MIXED_ENCODING = "Encoder.AllowMixedEncoding";
+ public static final String CANONICALIZATION_CODECS = "Encoder.DefaultCodecList";
+
+ public static final String DISABLE_INTRUSION_DETECTION = "IntrusionDetector.Disable";
+
+ public static final String MASTER_KEY = "Encryptor.MasterKey";
+ public static final String MASTER_SALT = "Encryptor.MasterSalt";
+ public static final String KEY_LENGTH = "Encryptor.EncryptionKeyLength";
+ public static final String ENCRYPTION_ALGORITHM = "Encryptor.EncryptionAlgorithm";
+ public static final String HASH_ALGORITHM = "Encryptor.HashAlgorithm";
+ public static final String HASH_ITERATIONS = "Encryptor.HashIterations";
+ public static final String CHARACTER_ENCODING = "Encryptor.CharacterEncoding";
+ public static final String RANDOM_ALGORITHM = "Encryptor.RandomAlgorithm";
+ public static final String DIGITAL_SIGNATURE_ALGORITHM = "Encryptor.DigitalSignatureAlgorithm";
+ public static final String DIGITAL_SIGNATURE_KEY_LENGTH = "Encryptor.DigitalSignatureKeyLength";
+ public static final String PREFERRED_JCE_PROVIDER = "Encryptor.PreferredJCEProvider";
+ public static final String CIPHER_TRANSFORMATION_IMPLEMENTATION = "Encryptor.CipherTransformation";
+ public static final String CIPHERTEXT_USE_MAC = "Encryptor.CipherText.useMAC";
+ public static final String PLAINTEXT_OVERWRITE = "Encryptor.PlainText.overwrite";
+ public static final String IV_TYPE = "Encryptor.ChooseIVMethod"; // Will be removed in future release.
+ public static final String COMBINED_CIPHER_MODES = "Encryptor.cipher_modes.combined_modes";
+ public static final String ADDITIONAL_ALLOWED_CIPHER_MODES = "Encryptor.cipher_modes.additional_allowed";
+ public static final String KDF_PRF_ALG = "Encryptor.KDF.PRF";
+ public static final String PRINT_PROPERTIES_WHEN_LOADED = "ESAPI.printProperties";
+ public static final String ACCEPTED_UNSAFE_METHOD_NAMES = "ESAPI.dangerouslyAllowUnsafeMethods.methodNames";
+ public static final String ACCEPTED_UNSAFE_METHODS_JUSTIFICATION = "ESAPI.dangerouslyAllowUnsafeMethods.justification";
+
+ public static final String WORKING_DIRECTORY = "Executor.WorkingDirectory";
+ public static final String APPROVED_EXECUTABLES = "Executor.ApprovedExecutables";
+
+ public static final String FORCE_HTTPONLYSESSION = "HttpUtilities.ForceHttpOnlySession";
+ public static final String FORCE_SECURESESSION = "HttpUtilities.SecureSession";
+ public static final String FORCE_HTTPONLYCOOKIES = "HttpUtilities.ForceHttpOnlyCookies";
+ public static final String FORCE_SECURECOOKIES = "HttpUtilities.ForceSecureCookies";
+ public static final String MAX_HTTP_HEADER_SIZE = "HttpUtilities.MaxHeaderSize";
+ public static final String UPLOAD_DIRECTORY = "HttpUtilities.UploadDir";
+ public static final String UPLOAD_TEMP_DIRECTORY = "HttpUtilities.UploadTempDir";
+ public static final String APPROVED_UPLOAD_EXTENSIONS = "HttpUtilities.ApprovedUploadExtensions";
+ public static final String MAX_UPLOAD_FILE_BYTES = "HttpUtilities.MaxUploadFileBytes";
+ public static final String MAX_UPLOAD_FILE_COUNT = "HttpUtilities.MaxUploadFileCount";
+ public static final String FILEUPLOAD_ALLOW_ANONYMOUS_USERS = "HttpUtilities.FileUploadAllowAnonymousUser";
+ public static final String RESPONSE_CONTENT_TYPE = "HttpUtilities.ResponseContentType";
+ public static final String HTTP_SESSION_ID_NAME = "HttpUtilities.HttpSessionIdName";
+
+ public static final String APPLICATION_NAME = "Logger.ApplicationName";
+ public static final String LOG_USER_INFO = "Logger.UserInfo";
+ public static final String LOG_CLIENT_INFO = "Logger.ClientInfo";
+ public static final String LOG_ENCODING_REQUIRED = "Logger.LogEncodingRequired";
+ public static final String LOG_APPLICATION_NAME = "Logger.LogApplicationName";
+ public static final String LOG_SERVER_IP = "Logger.LogServerIP";
+ public static final String LOG_PREFIX = "Logger.LogPrefix";
+
+ public static final String VALIDATION_PROPERTIES = "Validator.ConfigurationFile";
+ public static final String VALIDATION_PROPERTIES_MULTIVALUED = "Validator.ConfigurationFile.MultiValued";
+ public static final String ACCEPT_LENIENT_DATES = "Validator.AcceptLenientDates";
+ public static final String VALIDATOR_HTML_VALIDATION_ACTION = "Validator.HtmlValidationAction";
+ public static final String VALIDATOR_HTML_VALIDATION_CONFIGURATION_FILE = "Validator.HtmlValidationConfigurationFile";
+
+ /**
+ * Special {@code java.lang.System} property that, if set to {@code true}, will
+ * disable logging from {@code DefaultSecurityConfiguration.logToStdout()}
+ * methods, which is called from various {@code logSpecial()} methods.
+ *
+ * @see org.owasp.esapi.reference.DefaultSecurityConfiguration#logToStdout(String msg, Throwable t)
+ */
+ public static final String DISCARD_LOGSPECIAL = "org.owasp.esapi.logSpecial.discard";
+
+ /*
+ * Implementation Keys for the various major ESAPI components.
+ */
+ public static final String LOG_IMPLEMENTATION = "ESAPI.Logger";
+ public static final String AUTHENTICATION_IMPLEMENTATION = "ESAPI.Authenticator";
+ public static final String ENCODER_IMPLEMENTATION = "ESAPI.Encoder";
+ public static final String ACCESS_CONTROL_IMPLEMENTATION = "ESAPI.AccessControl";
+ public static final String ENCRYPTION_IMPLEMENTATION = "ESAPI.Encryptor";
+ public static final String INTRUSION_DETECTION_IMPLEMENTATION = "ESAPI.IntrusionDetector";
+ public static final String RANDOMIZER_IMPLEMENTATION = "ESAPI.Randomizer";
+ public static final String EXECUTOR_IMPLEMENTATION = "ESAPI.Executor";
+ public static final String VALIDATOR_IMPLEMENTATION = "ESAPI.Validator";
+ public static final String HTTP_UTILITIES_IMPLEMENTATION = "ESAPI.HTTPUtilities";
+
+
+ //////////////////////////////////////////////////////////////////////////////
+ // //
+ // These are not really property names, but the shouldn't really be in an //
+ // implementation class that we want to only deal with via the //
+ // SecurityConfiguration interface. //
+ // //
+ //////////////////////////////////////////////////////////////////////////////
+
+
+ /*
+ * These are default implementation classes.
+ */
+ public static final String DEFAULT_LOG_IMPLEMENTATION = "org.owasp.esapi.logging.java.JavaLogFactory";
+ public static final String DEFAULT_AUTHENTICATION_IMPLEMENTATION = "org.owasp.esapi.reference.FileBasedAuthenticator";
+ public static final String DEFAULT_ENCODER_IMPLEMENTATION = "org.owasp.esapi.reference.DefaultEncoder";
+ public static final String DEFAULT_ACCESS_CONTROL_IMPLEMENTATION = "org.owasp.esapi.reference.DefaultAccessController";
+ public static final String DEFAULT_ENCRYPTION_IMPLEMENTATION = "org.owasp.esapi.reference.crypto.JavaEncryptor";
+ public static final String DEFAULT_INTRUSION_DETECTION_IMPLEMENTATION = "org.owasp.esapi.reference.DefaultIntrusionDetector";
+ public static final String DEFAULT_RANDOMIZER_IMPLEMENTATION = "org.owasp.esapi.reference.DefaultRandomizer";
+ public static final String DEFAULT_EXECUTOR_IMPLEMENTATION = "org.owasp.esapi.reference.DefaultExecutor";
+ public static final String DEFAULT_HTTP_UTILITIES_IMPLEMENTATION = "org.owasp.esapi.reference.DefaultHTTPUtilities";
+ public static final String DEFAULT_VALIDATOR_IMPLEMENTATION = "org.owasp.esapi.reference.DefaultValidator";
+
+ /** The name of the ESAPI property file */
+ public static final String DEFAULT_RESOURCE_FILE = "ESAPI.properties";
+
+ //
+ // Private CTOR to prevent creation of PropName objects. We wouldn't need
+ // this if this were an interface, nor would we need the explict 'public static final'.
+ //
+ private PropNames() {
+ throw new AssertionError("Thought you'd cheat using reflection or JNI, huh? :)");
+ }
+
+
+ /** Enum used with the search paths used to locate an
+ * {@code ESAPI.properties} and/or a {@code validation.properties}
+ * file.
+ */
+ public enum DefaultSearchPath {
+
+ RESOURCE_DIRECTORY("resourceDirectory/"),
+ SRC_MAIN_RESOURCES("src/main/resources/"),
+ ROOT(""),
+ DOT_ESAPI(".esapi/"),
+ ESAPI("esapi/"),
+ RESOURCES("resources/");
+
+ private final String path;
+
+ private DefaultSearchPath(String s){
+ this.path = s;
+ }
+
+ public String value(){
+ return path;
+ }
+ }
+}
diff --git a/src/main/java/org/owasp/esapi/Randomizer.java b/src/main/java/org/owasp/esapi/Randomizer.java
new file mode 100644
index 000000000..bef0c4a1b
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/Randomizer.java
@@ -0,0 +1,147 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import org.owasp.esapi.errors.EncryptionException;
+
+/**
+ * The Randomizer interface defines a set of methods for creating
+ * cryptographically random numbers and strings. Implementers should be sure to
+ * use a strong cryptographic implementation, such as the JCE or BouncyCastle.
+ * Weak sources of randomness can undermine a wide variety of security
+ * mechanisms. The specific algorithm used is configurable in ESAPI.properties.
+ *
+ * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @since June 1, 2007
+ */
+public interface Randomizer {
+
+ /**
+ * Gets a random string of a desired length and character set. The use of java.security.SecureRandom
+ * is recommended because it provides a cryptographically strong pseudo-random number generator.
+ * If SecureRandom is not used, the pseudo-random number generator used should comply with the
+ * statistical random number generator tests specified in
+ * FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1.
+ *
+ * @param length
+ * the length of the string
+ * @param characterSet
+ * the set of characters to include in the created random string
+ *
+ * @return
+ * the random string of the desired length and character set
+ */
+ String getRandomString(int length, char[] characterSet);
+
+ /**
+ * Returns a random boolean. The use of java.security.SecureRandom
+ * is recommended because it provides a cryptographically strong pseudo-random number generator.
+ * If SecureRandom is not used, the pseudo-random number generator used should comply with the
+ * statistical random number generator tests specified in
+ * FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1.
+ *
+ * @return
+ * true or false, randomly
+ */
+ boolean getRandomBoolean();
+
+ /**
+ * Gets the random integer in the range of [min, max). The use of java.security.SecureRandom
+ * is recommended because it provides a cryptographically strong pseudo-random number generator.
+ * If SecureRandom is not used, the pseudo-random number generator used should comply with the
+ * statistical random number generator tests specified in
+ * FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1.
+ *
+ * @param min
+ * the minimum integer that will be returned, inclusive
+ * @param max
+ * the maximum integer that will be returned, exclusive
+ *
+ * @return
+ * the random integer
+ */
+ int getRandomInteger(int min, int max);
+
+
+ /**
+ * Gets the random long. The use of java.security.SecureRandom
+ * is recommended because it provides a cryptographically strong pseudo-random number generator.
+ * If SecureRandom is not used, the pseudo-random number generator used should comply with the
+ * statistical random number generator tests specified in
+ * FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1.
+ *
+ * @return
+ * the random long
+ */
+ long getRandomLong();
+
+
+ /**
+ * Returns an unguessable random filename with the specified extension. This method could call
+ * getRandomString(length, charset) from this Class with the desired length and alphanumerics as the charset
+ * then merely append "." + extension.
+ *
+ * @param extension
+ * extension to add to the random filename
+ *
+ * @return
+ * a random unguessable filename ending with the specified extension
+ */
+ String getRandomFilename( String extension );
+
+
+ /**
+ * Gets the random real in the range of [min, max]. The use of java.security.SecureRandom
+ * is recommended because it provides a cryptographically strong pseudo-random number generator.
+ * If SecureRandom is not used, the pseudo-random number generator used should comply with the
+ * statistical random number generator tests specified in
+ * FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1.
+ *
+ * @param min
+ * the minimum real number that will be returned, inclusive
+ * @param max
+ * the maximum real number that will be returned, inclusive
+ *
+ * @return
+ * the random real
+ */
+ float getRandomReal(float min, float max);
+
+ /**
+ * Generates a random GUID. This method could use a hash of random Strings, the current time,
+ * and any other random data available. The format is a well-defined sequence of 32 hex digits
+ * grouped into chunks of 8-4-4-4-12.
+ *
+ * For more information including algorithms used to create UUIDs,
+ * see the Internet-Draft UUIDs and GUIDs
+ * or the standards body definition at ISO/IEC 11578:1996.
+ * @return
+ * the GUID
+ *
+ * @throws
+ * EncryptionException if hashing or encryption fails
+ */
+ String getRandomGUID() throws EncryptionException;
+
+ /**
+ * Generates a specified number of random bytes.
+ * @param n The requested number of random bytes.
+ * @return The {@code n} random bytes are returned.
+ */
+ byte[] getRandomBytes(int n);
+
+}
diff --git a/src/main/java/org/owasp/esapi/SafeFile.java b/src/main/java/org/owasp/esapi/SafeFile.java
new file mode 100644
index 000000000..e048e9419
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/SafeFile.java
@@ -0,0 +1,107 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2008 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Arshan Dabirsiaghi Aspect Security
+ * @created 2008
+ */
+package org.owasp.esapi;
+
+import java.io.File;
+import java.net.URI;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.owasp.esapi.errors.ValidationException;
+
+/**
+ * Extension to java.io.File to prevent against null byte injections and
+ * other unforeseen problems resulting from unprintable characters
+ * causing problems in path lookups. This does _not_ prevent against
+ * directory traversal attacks.
+ */
+public class SafeFile extends File {
+
+ private static final long serialVersionUID = 1L;
+ private static final Pattern PERCENTS_PAT = Pattern.compile("(%)([0-9a-fA-F])([0-9a-fA-F])");
+ private static final Pattern FILE_BLACKLIST_PAT = Pattern.compile("([\\\\/:*?<>|^])");
+ private static final Pattern DIR_BLACKLIST_PAT = Pattern.compile("([*?<>|^])");
+
+ public SafeFile(String path) throws ValidationException {
+ super(path);
+ doDirCheck(this.getParent());
+ doFileCheck(this.getName());
+ }
+
+ public SafeFile(String parent, String child) throws ValidationException {
+ super(parent, child);
+ doDirCheck(this.getParent());
+ doFileCheck(this.getName());
+ }
+
+ public SafeFile(File parent, String child) throws ValidationException {
+ super(parent, child);
+ doDirCheck(this.getParent());
+ doFileCheck(this.getName());
+ }
+
+ public SafeFile(URI uri) throws ValidationException {
+ super(uri);
+ doDirCheck(this.getParent());
+ doFileCheck(this.getName());
+ }
+
+
+ private void doDirCheck(String path) throws ValidationException {
+ Matcher m1 = DIR_BLACKLIST_PAT.matcher( path );
+ if ( null != m1 && m1.find() ) {
+ throw new ValidationException( "Invalid directory", "Directory path (" + path + ") contains illegal character: " + m1.group() );
+ }
+
+ Matcher m2 = PERCENTS_PAT.matcher( path );
+ if (null != m2 && m2.find() ) {
+ throw new ValidationException( "Invalid directory", "Directory path (" + path + ") contains encoded characters: " + m2.group() );
+ }
+
+ int ch = containsUnprintableCharacters(path);
+ if (ch != -1) {
+ throw new ValidationException("Invalid directory", "Directory path (" + path + ") contains unprintable character: " + ch);
+ }
+ }
+
+ private void doFileCheck(String path) throws ValidationException {
+ Matcher m1 = FILE_BLACKLIST_PAT.matcher( path );
+ if ( m1.find() ) {
+ throw new ValidationException( "Invalid directory", "Directory path (" + path + ") contains illegal character: " + m1.group() );
+ }
+
+ Matcher m2 = PERCENTS_PAT.matcher( path );
+ if ( m2.find() ) {
+ throw new ValidationException( "Invalid file", "File path (" + path + ") contains encoded characters: " + m2.group() );
+ }
+
+ int ch = containsUnprintableCharacters(path);
+ if (ch != -1) {
+ throw new ValidationException("Invalid file", "File path (" + path + ") contains unprintable character: " + ch);
+ }
+ }
+
+ private int containsUnprintableCharacters(String s) {
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ if (((int) ch) < 32 || ((int) ch) > 126) {
+ return (int) ch;
+ }
+ }
+ return -1;
+ }
+
+}
diff --git a/src/main/java/org/owasp/esapi/SecurityConfiguration.java b/src/main/java/org/owasp/esapi/SecurityConfiguration.java
new file mode 100644
index 000000000..e0b529b49
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/SecurityConfiguration.java
@@ -0,0 +1,767 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Mike Fauzy Aspect Security
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import org.owasp.esapi.configuration.EsapiPropertyLoader;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * The {@code SecurityConfiguration} interface stores all configuration information
+ * that directs the behavior of the ESAPI implementation.
+ *
+ * Protection of this configuration information is critical to the secure
+ * operation of the application using the ESAPI. You should use operating system
+ * access controls to limit access to wherever the configuration information is
+ * stored.
+ *
+ * Please note that adding another layer of encryption does not make the
+ * attackers job much more difficult. Somewhere there must be a master "secret"
+ * that is stored unencrypted on the application platform (unless you are
+ * willing to prompt for some passphrase when you application starts or insert
+ * a USB thumb drive or an HSM card, etc., in which case this master "secret"
+ * it would only be in memory). Creating another layer of indirection provides
+ * additional obfuscation, but doesn't provide any real additional security.
+ * It's up to the reference implementation to decide whether this file should
+ * be encrypted or not.
+ *
+ * The ESAPI reference implementation (DefaultSecurityConfiguration.java) does
+ * not encrypt its properties file.
+ *
+ * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @since June 1, 2007
+ */
+public interface SecurityConfiguration extends EsapiPropertyLoader {
+
+ /**
+ * Gets the application name, used for logging
+ *
+ * @return the name of the current application
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getApplicationName();
+
+ /**
+ * Returns the fully qualified classname of the ESAPI Logging implementation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getLogImplementation();
+
+ /**
+ * Returns the fully qualified classname of the ESAPI Authentication implementation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getAuthenticationImplementation();
+
+ /**
+ * Returns the fully qualified classname of the ESAPI Encoder implementation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getEncoderImplementation();
+
+ /**
+ * Returns the fully qualified classname of the ESAPI Access Control implementation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getAccessControlImplementation();
+
+ /**
+ * Returns the fully qualified classname of the ESAPI Intrusion Detection implementation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getIntrusionDetectionImplementation();
+
+ /**
+ * Returns the fully qualified classname of the ESAPI Randomizer implementation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getRandomizerImplementation();
+
+ /**
+ * Returns the fully qualified classname of the ESAPI Encryption implementation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getEncryptionImplementation();
+
+ /**
+ * Returns the fully qualified classname of the ESAPI Validation implementation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getValidationImplementation();
+
+ /**
+ * Returns the validation pattern for a particular type
+ * @param typeName
+ * @return the validation pattern
+ */
+ Pattern getValidationPattern( String typeName );
+
+ /**
+ * Determines whether ESAPI will accept "lenient" dates when attempt
+ * to parse dates. Controlled by ESAPI property
+ * {@code Validator.AcceptLenientDates}, which defaults to {@code false}
+ * if unset.
+ *
+ * @return True if lenient dates are accepted; false otherwise.
+ * @see java.text.DateFormat#setLenient(boolean)
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getLenientDatesAccepted();
+
+ /**
+ * Returns the fully qualified classname of the ESAPI OS Execution implementation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getExecutorImplementation();
+
+ /**
+ * Returns the fully qualified classname of the ESAPI HTTPUtilities implementation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getHTTPUtilitiesImplementation();
+
+ /**
+ * Gets the master key. This password is used to encrypt/decrypt other files or types
+ * of data that need to be protected by your application.
+ *
+ * @return the current master key
+ * @deprecated Use SecurityConfiguration.getByteArrayProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ byte[] getMasterKey();
+
+ /**
+ * Retrieves the upload directory as specified in the ESAPI.properties file.
+ * @return the upload directory
+ */
+ File getUploadDirectory();
+
+ /**
+ * Retrieves the temp directory to use when uploading files, as specified in ESAPI.properties.
+ * @return the temp directory
+ */
+ File getUploadTempDirectory();
+
+ /**
+ * Gets the key length to use in cryptographic operations declared in the ESAPI properties file.
+ * Note that this corresponds to the ESAPI property Encryptor.EncryptionKeyLength which is
+ * considered the default key size that ESAPI will use for symmetric
+ * ciphers supporting multiple key sizes. (Note that there is also an Encryptor.MinEncryptionKeyLength,
+ * which is the minimum key size (in bits) that ESAPI will support
+ * for encryption. (There is no minimum for decryption.)
+ *
+ * @return the key length (in bits)
+ * @deprecated Use SecurityConfiguration.getIntProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ int getEncryptionKeyLength();
+
+ /**
+ * Gets the master salt that is used to salt stored password hashes and any other location
+ * where a salt is needed.
+ *
+ * @return the current master salt
+ * @deprecated Use SecurityConfiguration.getByteArrayProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ byte[] getMasterSalt();
+
+ /**
+ * Gets the allowed executables to run with the Executor.
+ *
+ * @return a list of the current allowed file extensions
+ */
+ List getAllowedExecutables();
+
+ /**
+ * Gets the allowed file extensions for files that are uploaded to this application.
+ *
+ * @return a list of the current allowed file extensions
+ */
+ List getAllowedFileExtensions();
+
+ /**
+ * Gets the maximum allowed file upload size.
+ *
+ * @return the current allowed file upload size
+ * @deprecated Use SecurityConfiguration.getIntProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ int getAllowedFileUploadSize();
+
+ /**
+ * Gets the name of the password parameter used during user authentication.
+ *
+ * @return the name of the password parameter
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getPasswordParameterName();
+
+ /**
+ * Gets the name of the username parameter used during user authentication.
+ *
+ * @return the name of the username parameter
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getUsernameParameterName();
+
+ /**
+ * Gets the encryption algorithm used by ESAPI to protect data. This is
+ * mostly used for compatibility with ESAPI 1.4; ESAPI 2.0 prefers to
+ * use "cipher transformation" since it supports multiple cipher modes
+ * and padding schemes.
+ *
+ * @return the current encryption algorithm
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getEncryptionAlgorithm();
+
+ /**
+ * Retrieve the cipher transformation. In general, the cipher transformation
+ * is a specification of cipher algorithm, cipher mode, and padding scheme
+ * and in general, is a {@code String} that takes the following form:
+ *
+ * where cipher_alg is the JCE cipher algorithm (e.g., "DESede"),
+ * cipher_mode is the cipher mode (e.g., "CBC", "CFB", "CTR", etc.),
+ * and padding_scheme is the cipher padding scheme (e.g., "NONE" for
+ * no padding, "PKCS5Padding" for PKCS#5 padding, etc.) and where
+ * [bits] is an optional bit size that applies to certain cipher
+ * modes such as {@code CFB} and {@code OFB}. Using modes such as CFB and
+ * OFB, block ciphers can encrypt data in units smaller than the cipher's
+ * actual block size. When requesting such a mode, you may optionally
+ * specify the number of bits to be processed at a time. This generally must
+ * be an integral multiple of 8-bits so that it can specify a whole number
+ * of octets.
+ *
+ * NOTE: Occasionally, in cryptographic literature, you may also
+ * see the key size (in bits) specified after the cipher algorithm in the
+ * cipher transformation. Generally, this is done to account for cipher
+ * algorithms that have variable key sizes. The Blowfish cipher for example
+ * supports key sizes from 32 to 448 bits. So for Blowfish, you might see
+ * a cipher transformation something like this:
+ *
+ * "Blowfish-192/CFB8/PKCS5Padding"
+ *
+ * in the cryptographic literature. It should be noted that the Java
+ * Cryptography Extensions (JCE) do not generally support this (at least
+ * not the reference JCE implementation of "SunJCE"), and therefore it
+ * should be avoided.
+ * @return The cipher transformation.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getCipherTransformation();
+
+ /**
+ * Set the cipher transformation. This allows a different cipher transformation
+ * to be used without changing the {@code ESAPI.properties} file. For instance
+ * you may normally want to use AES/CBC/PKCS5Padding, but have some legacy
+ * encryption where you have ciphertext that was encrypted using 3DES.
+ *
+ * @param cipherXform The new cipher transformation. See
+ * {@link #getCipherTransformation} for format. If
+ * {@code null} is passed as the parameter, the cipher
+ * transformation will be set to the the default taken
+ * from the property {@code Encryptor.CipherTransformation}
+ * in the {@code ESAPI.properties} file. BEWARE:
+ * there is NO sanity checking here (other than
+ * the empty string, and then, only if Java assertions are
+ * enabled), so if you set this wrong, you will not get
+ * any errors until you later try to use it to encrypt
+ * or decrypt data.
+ * @return The previous cipher transformation is returned for convenience,
+ * with the assumption that you may wish to restore it once you have
+ * completed the encryption / decryption with the new cipher
+ * transformation.
+ * @deprecated To be replaced by new class in ESAPI 2.1, but here if you need it
+ * until then. Details of replacement forthcoming to ESAPI-Dev
+ * list. Most likely to be replaced by a new CTOR for
+ * JavaEncryptor that takes a list of properties to override.
+ */
+ @Deprecated
+ String setCipherTransformation(String cipherXform);
+
+ /**
+ * Retrieve the preferred JCE provider for ESAPI and your application.
+ * ESAPI 2.0 now allows setting the property
+ * {@code Encryptor.PreferredJCEProvider} in the
+ * {@code ESAPI.properties} file, which will cause the specified JCE
+ * provider to be automatically and dynamically loaded (assuming that
+ * {@code SecurityManager} permissions allow) as the Ii>preferred
+ * JCE provider. (Note this only happens if the JCE provider is not already
+ * loaded.) This method returns the property {@code Encryptor.PreferredJCEProvider}.
+ *
+ * By default, this {@code Encryptor.PreferredJCEProvider} property is set
+ * to an empty string, which means that the preferred JCE provider is not
+ * changed.
+ * @return The property {@code Encryptor.PreferredJCEProvider} is returned.
+ * @see org.owasp.esapi.crypto.SecurityProviderLoader
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getPreferredJCEProvider();
+
+// TODO - DISCUSS: Where should this web page (below) go? Maybe with the Javadoc? But where?
+// Think it makes more sense as part of the release notes, but OTOH, I
+// really don't want to rewrite this as a Wiki page either.
+ /**
+ * Determines whether the {@code CipherText} should be used with a Message
+ * Authentication Code (MAC). Generally this makes for a more robust cryptographic
+ * scheme, but there are some minor performance implications. Controlled by
+ * the ESAPI property Encryptor.CipherText.useMAC.
+ *
+ * @return {@code true} if a you want a MAC to be used, otherwise {@code false}.
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean useMACforCipherText();
+
+ /**
+ * Indicates whether the {@code PlainText} objects may be overwritten after
+ * they have been encrypted. Generally this is a good idea, especially if
+ * your VM is shared by multiple applications (e.g., multiple applications
+ * running in the same J2EE container) or if there is a possibility that
+ * your VM may leave a core dump (say because it is running non-native
+ * Java code.
+ *
+ * Controlled by the property {@code Encryptor.PlainText.overwrite} in
+ * the {@code ESAPI.properties} file.
+ *
+ * @return True if it is OK to overwrite the {@code PlainText} objects
+ * after encrypting, false otherwise.
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean overwritePlainText();
+
+ /**
+ * Get a string indicating how to compute an Initialization Vector (IV).
+ * Currently supported modes are "random" to generate a random IV or
+ * "fixed" to use a fixed (static) IV.
+ *
+ * WARNING: 'fixed' was only intended to support legacy applications with
+ * fixed IVs, but the use of non-random IVs is inherently insecure,
+ * especially for any supported cipher mode that is considered a streaming mode
+ * (which is basically anything except CBC for modes that support require an IV).
+ * For this reason, 'fixed' has now been removed (it was considered deprecated
+ * since release 2.2.0.0). An ESAPI.properties value of {@code fixed} for the property
+ * {@code Encryptor.ChooseIVMethod} will now result in a {@code ConfigurationException}
+ * being thrown.
+ *
+ * @return A string specifying the IV type. Should be "random". Anything
+ * else should fail with a {@code ConfigurationException} being thrown.
+ *
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ * This method will be removed in a future release as it is now moot since
+ * it can only legitimately have the single value of "random".
+ */
+ @Deprecated
+ String getIVType();
+
+ /**
+ * Return a {@code List} of strings of combined cipher modes that support
+ * both confidentiality and authenticity. These would be preferred
+ * cipher modes to use if your JCE provider supports them. If such a
+ * cipher mode is used, no explicit separate MAC is calculated as part of
+ * the {@code CipherText} object upon encryption nor is any attempt made
+ * to verify the same on decryption.
+ *
+ * The list is taken from the comma-separated list of cipher modes specified
+ * by the ESAPI property
+ * {@code Encryptor.cipher_modes.combined_modes}.
+ *
+ * @return The parsed list of comma-separated cipher modes if the property
+ * was specified in {@code ESAPI.properties}; otherwise the empty list is
+ * returned.
+ */
+ List getCombinedCipherModes();
+
+ /**
+ * Return {@code List} of strings of additional cipher modes that are
+ * permitted (i.e., in addition to those returned by
+ * {@link #getCombinedCipherModes()}) to be used for encryption and
+ * decryption operations.
+ *
+ * The list is taken from the comma-separated list of cipher modes specified
+ * by the ESAPI property
+ * {@code Encryptor.cipher_modes.additional_allowed}.
+ *
+ * @return The parsed list of comma-separated cipher modes if the property
+ * was specified in {@code ESAPI.properties}; otherwise the empty list is
+ * returned.
+ *
+ * @see #getCombinedCipherModes()
+ */
+ List getAdditionalAllowedCipherModes();
+
+ /**
+ * Gets the hashing algorithm used by ESAPI to hash data.
+ *
+ * @return the current hashing algorithm
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getHashAlgorithm();
+
+ /**
+ * Gets the hash iterations used by ESAPI to hash data.
+ *
+ * @return the current hashing algorithm
+ * @deprecated Use SecurityConfiguration.getIntProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ int getHashIterations();
+
+ /**
+ * Retrieve the Pseudo Random Function (PRF) used by the ESAPI
+ * Key Derivation Function (KDF).
+ *
+ * @return The KDF PRF algorithm name.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getKDFPseudoRandomFunction();
+
+ /**
+ * Gets the character encoding scheme supported by this application. This is used to set the
+ * character encoding scheme on requests and responses when setCharacterEncoding() is called
+ * on SafeRequests and SafeResponses. This scheme is also used for encoding/decoding URLs
+ * and any other place where the current encoding scheme needs to be known.
+ *
+ * Note: This does not get the configured response content type. That is accessed by calling
+ * getResponseContentType().
+ *
+ * @return the current character encoding scheme
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getCharacterEncoding();
+
+ /**
+ * Return true if multiple encoding is allowed
+ *
+ * @return whether multiple encoding is allowed when canonicalizing data
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getAllowMultipleEncoding();
+
+ /**
+ * Return true if mixed encoding is allowed
+ *
+ * @return whether mixed encoding is allowed when canonicalizing data
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getAllowMixedEncoding();
+
+ /**
+ * Returns the List of Codecs to use when canonicalizing data
+ *
+ * @return the codec list
+ */
+ List getDefaultCanonicalizationCodecs();
+
+ /**
+ * Gets the digital signature algorithm used by ESAPI to generate and verify signatures.
+ *
+ * @return the current digital signature algorithm
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getDigitalSignatureAlgorithm();
+
+ /**
+ * Gets the digital signature key length used by ESAPI to generate and verify signatures.
+ *
+ * @return the current digital signature key length
+ * @deprecated Use SecurityConfiguration.getIntProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ int getDigitalSignatureKeyLength();
+
+ /**
+ * Gets the random number generation algorithm used to generate random numbers where needed.
+ *
+ * @return the current random number generation algorithm
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getRandomAlgorithm();
+
+ /**
+ * Gets the number of login attempts allowed before the user's account is locked. If this
+ * many failures are detected within the alloted time period, the user's account will be locked.
+ *
+ * @return the number of failed login attempts that cause an account to be locked
+ * @deprecated Use SecurityConfiguration.getIntProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ int getAllowedLoginAttempts();
+
+ /**
+ * Gets the maximum number of old password hashes that should be retained. These hashes can
+ * be used to ensure that the user doesn't reuse the specified number of previous passwords
+ * when they change their password.
+ *
+ * @return the number of old hashed passwords to retain
+ * @deprecated Use SecurityConfiguration.getIntProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ int getMaxOldPasswordHashes();
+
+ /**
+ * Allows for complete disabling of all intrusion detection mechanisms
+ *
+ * @return true if intrusion detection should be disabled
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getDisableIntrusionDetection();
+
+ /**
+ * Gets the intrusion detection quota for the specified event.
+ *
+ * @param eventName the name of the event whose quota is desired
+ *
+ * @return the Quota that has been configured for the specified type of event
+ */
+ Threshold getQuota(String eventName);
+
+ /**
+ * Gets a file from the resource directory
+ *
+ * @param filename The file name resource.
+ * @return A {@code File} object representing the specified file name or null if not found.
+ */
+ File getResourceFile( String filename );
+
+ /**
+ * Returns true if session cookies are required to have HttpOnly flag set.
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getForceHttpOnlySession() ;
+
+ /**
+ * Returns true if session cookies are required to have Secure flag set.
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getForceSecureSession() ;
+
+ /**
+ * Returns true if new cookies are required to have HttpOnly flag set.
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getForceHttpOnlyCookies() ;
+
+ /**
+ * Returns true if new cookies are required to have Secure flag set.
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getForceSecureCookies() ;
+
+ /**
+ * Returns the maximum allowable HTTP header size.
+ * @deprecated Use SecurityConfiguration.getIntProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ int getMaxHttpHeaderSize() ;
+
+ /**
+ * Gets an InputStream to a file in the resource directory
+ *
+ * @param filename A file name in the resource directory.
+ * @return An {@code InputStream} to the specified file name in the resource directory.
+ * @throws IOException If the specified file name cannot be found or opened for reading.
+ */
+ InputStream getResourceStream( String filename ) throws IOException;
+
+ /**
+ * Sets the ESAPI resource directory.
+ *
+ * @param dir The location of the resource directory.
+ */
+ void setResourceDirectory(String dir);
+
+ /**
+ * Gets the content type for responses used when setSafeContentType() is called.
+ *
+ * Note: This does not get the configured character encoding scheme. That is accessed by calling
+ * getCharacterEncoding().
+ *
+ * @return The current content-type set for responses.
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getResponseContentType();
+
+ /**
+ * This method returns the configured name of the session identifier,
+ * likely "JSESSIONID" though this can be overridden.
+ *
+ * @return The name of the session identifier, like "JSESSIONID"
+ * @deprecated Use SecurityConfiguration.getStringProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ String getHttpSessionIdName();
+
+ /**
+ * Gets the length of the time to live window for remember me tokens (in milliseconds).
+ *
+ * @return The time to live length for generated "remember me" tokens.
+ */
+ // OPEN ISSUE: Can we replace w/ SecurityConfiguration.getIntProp("appropriate_esapi_prop_name") instead?
+ long getRememberTokenDuration();
+
+
+ /**
+ * Gets the idle timeout length for sessions (in milliseconds). This is the amount of time that a session
+ * can live before it expires due to lack of activity. Applications or frameworks could provide a reauthenticate
+ * function that enables a session to continue after reauthentication.
+ *
+ * @return The session idle timeout length.
+ * @deprecated Use SecurityConfiguration.getIntProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ int getSessionIdleTimeoutLength();
+
+ /**
+ * Gets the absolute timeout length for sessions (in milliseconds). This is the amount of time that a session
+ * can live before it expires regardless of the amount of user activity. Applications or frameworks could
+ * provide a reauthenticate function that enables a session to continue after reauthentication.
+ *
+ * @return The session absolute timeout length.
+ * @deprecated Use SecurityConfiguration.getIntProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ int getSessionAbsoluteTimeoutLength();
+
+
+ /**
+ * Returns whether HTML entity encoding should be applied to log entries.
+ *
+ * @return True if log entries are to be HTML Entity encoded. False otherwise.
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getLogEncodingRequired();
+
+ /**
+ * Returns whether ESAPI should log the application name. This might be clutter in some
+ * single-server/single-app environments.
+ *
+ * @return True if ESAPI should log the application name, False otherwise
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getLogApplicationName();
+
+ /**
+ * Returns whether ESAPI should log the server IP. This might be clutter in some
+ * single-server environments.
+ *
+ * @return True if ESAPI should log the server IP and port, False otherwise
+ * @deprecated Use SecurityConfiguration.getBooleanProp("appropriate_esapi_prop_name") instead.
+ */
+ @Deprecated
+ boolean getLogServerIP();
+
+ /**
+ * Models a simple threshold as a count and an interval, along with a set of actions to take if
+ * the threshold is exceeded. These thresholds are used to define when the accumulation of a particular event
+ * has met a set number within the specified time period. Once a threshold value has been met, various
+ * actions can be taken at that point.
+ */
+ class Threshold {
+
+ /** The name of this threshold. */
+ public String name = null;
+
+ /** The count at which this threshold is triggered. */
+ public int count = 0;
+
+ /**
+ * The time frame within which 'count' number of actions has to be detected in order to
+ * trigger this threshold.
+ */
+ public long interval = 0;
+
+ /**
+ * The list of actions to take if the threshold is met. It is expected that this is a list of Strings, but
+ * your implementation could have this be a list of any type of 'actions' you wish to define.
+ */
+ public List actions = null;
+
+ /**
+ * Constructs a threshold that is composed of its name, its threshold count, the time window for
+ * the threshold, and the actions to take if the threshold is triggered.
+ *
+ * @param name The name of this threshold.
+ * @param count The count at which this threshold is triggered.
+ * @param interval The time frame within which 'count' number of actions has to be detected in order to
+ * trigger this threshold.
+ * @param actions The list of actions to take if the threshold is met.
+ */
+ public Threshold(String name, int count, long interval, List actions) {
+ this.name = name;
+ this.count = count;
+ this.interval = interval;
+ this.actions = actions;
+ }
+ }
+
+ /**
+ * Returns the default working directory for executing native processes with Runtime.exec().
+ */
+ File getWorkingDirectory();
+}
diff --git a/src/main/java/org/owasp/esapi/StringUtilities.java b/src/main/java/org/owasp/esapi/StringUtilities.java
new file mode 100644
index 000000000..ef95a91ce
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/StringUtilities.java
@@ -0,0 +1,200 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+/**
+ * String utilities used in various filters.
+ *
+ * @author Jeff Williams (jeff.williams .at. aspectsecurity.com) Aspect Security
+ * @since June 1, 2007
+ */
+public class StringUtilities {
+
+ private static final Pattern p = Pattern.compile( "\\s");
+ public static String replaceLinearWhiteSpace( String input ) {
+ return p.matcher(input).replaceAll( " " );
+ }
+
+ /**
+ * Removes all unprintable characters from a string
+ * and replaces with a space.
+ * @param input
+ * @return the stripped value
+ */
+ public static String stripControls( String input ) {
+ StringBuilder sb = new StringBuilder();
+ for ( int i=0; i 0x20 && c < 0x7f ) {
+ sb.append( c );
+ } else {
+ sb.append( ' ' );
+ }
+ }
+ return sb.toString();
+ }
+
+
+ /**
+ * Union multiple character arrays.
+ *
+ * @param list the char[]s to union
+ * @return the union of the char[]s
+ */
+ public static char[] union(char[]... list) {
+ StringBuilder sb = new StringBuilder();
+
+ for (char[] characters : list) {
+ for ( char c : characters ) {
+ if ( !contains( sb, c ) )
+ sb.append( c );
+ }
+ }
+
+ char[] toReturn = new char[sb.length()];
+ sb.getChars(0, sb.length(), toReturn, 0);
+ Arrays.sort(toReturn);
+ return toReturn;
+ }
+
+
+ /**
+ * Returns true if the character is contained in the provided StringBuilder.
+ * @param input The input
+ * @param c The character to check for to see if {@code input} contains.
+ * @return True if the specified character is contained; false otherwise.
+ */
+ public static boolean contains(StringBuilder input, char c) {
+ for (int i = 0; i < input.length(); i++) {
+ if (input.charAt(i) == c)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns {@code replace} if {@code test} is null, "null" (case-insensitive), or blank, otherwise {@code test}
+ *
+ * @param test The value to test
+ * @param replace The replacement value
+ * @return The correct value
+ */
+ public static String replaceNull( String test, String replace ) {
+ return test == null || "null".equalsIgnoreCase( test.trim() ) || "".equals( test.trim() ) ? replace : test;
+ }
+
+ /**
+ * Calculate the Edit Distance between 2 Strings as a measure of similarity.
+ *
+ * For example, if the strings GUMBO and GAMBOL are passed in, the edit distance
+ * is 2, since GUMBO transforms into GAMBOL by replacing the 'U' with an 'A' and
+ * adding an 'L'.
+ *
+ * Original Implementation of this algorithm by Michael Gilleland, adapted by
+ * Chas Emerick for the Apache-Commons project
+ * http://www.merriampark.com/ldjava.htm
+ *
+ * @param s The source string
+ * @param t The target String
+ * @return The edit distance between the 2 strings
+ */
+ public static int getLevenshteinDistance (String s, String t) {
+ if (s == null || t == null) {
+ throw new IllegalArgumentException("Strings must not be null");
+ }
+
+ int n = s.length(); // length of s
+ int m = t.length(); // length of t
+
+ if (n == 0) {
+ return m;
+ } else if (m == 0) {
+ return n;
+ }
+
+ int p[] = new int[n+1]; //'previous' cost array, horizontally
+ int d[] = new int[n+1]; // cost array, horizontally
+ int _d[]; //placeholder to assist in swapping p and d
+
+ // indexes into strings s and t
+ int i; // iterates through s
+ int j; // iterates through t
+
+ char t_j; // jth character of t
+
+ int cost; // cost
+
+ for (i = 0; i<=n; i++) {
+ p[i] = i;
+ }
+
+ for (j = 1; j<=m; j++) {
+ t_j = t.charAt(j-1);
+ d[0] = j;
+
+ for (i=1; i<=n; i++) {
+ cost = s.charAt(i-1)==t_j ? 0 : 1;
+ // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
+ d[i] = Math.min(Math.min(d[i-1]+1, p[i]+1), p[i-1]+cost);
+ }
+
+ // copy current distance counts to 'previous row' distance counts
+ _d = p;
+ p = d;
+ d = _d;
+ }
+
+ // our last action in the above loop was to switch d and p, so p now
+ // actually has the most recent cost counts
+ return p[n];
+ }
+
+ /**
+ * Check to ensure that a {@code String} is not null or empty (after optional
+ * trimming of leading and trailing whitespace). Usually used with
+ * assertions, as in
+ *
+ * assert StringUtils.notNullOrEmpty(cipherXform, true) :
+ * "Cipher transformation may not be null or empty!";
+ *
+ * or an equivalent runtime check that throws an {@code IllegalArgumentException}.
+ *
+ * @param str The {@code String} to be checked.
+ * @param trim If {@code true}, the string is first trimmed before checking
+ * to see if it is empty, otherwise it is not.
+ * @return True if the string is null or empty (after possible
+ * trimming); otherwise false.
+ * @since 2.0
+ */
+ public static boolean notNullOrEmpty(String str, boolean trim) {
+ if ( trim ) {
+ return !( str == null || str.trim().equals("") );
+ } else {
+ return !( str == null || str.equals("") );
+ }
+ }
+
+ /**
+ * Returns true if String is empty ("") or null.
+ */
+ public static boolean isEmpty(String str) {
+ return str == null || str.length() == 0;
+ }
+}
diff --git a/src/main/java/org/owasp/esapi/User.java b/src/main/java/org/owasp/esapi/User.java
new file mode 100644
index 000000000..fc5ca980c
--- /dev/null
+++ b/src/main/java/org/owasp/esapi/User.java
@@ -0,0 +1,760 @@
+/**
+ * OWASP Enterprise Security API (ESAPI)
+ *
+ * This file is part of the Open Web Application Security Project (OWASP)
+ * Enterprise Security API (ESAPI) project. For details, please see
+ * http://www.owasp.org/index.php/ESAPI.
+ *
+ * Copyright (c) 2007 - The OWASP Foundation
+ *
+ * The ESAPI is published by OWASP under the BSD license. You should read and accept the
+ * LICENSE before you use, modify, and/or redistribute this software.
+ *
+ * @author Jeff Williams Aspect Security
+ * @created 2007
+ */
+package org.owasp.esapi;
+
+import org.owasp.esapi.errors.AuthenticationException;
+import org.owasp.esapi.errors.AuthenticationHostException;
+import org.owasp.esapi.errors.EncryptionException;
+
+import javax.servlet.http.HttpSession;
+import java.io.Serializable;
+import java.security.Principal;
+import java.util.*;
+
+/**
+ * The User interface represents an application user or user account. There is quite a lot of information that an
+ * application must store for each user in order to enforce security properly. There are also many rules that govern
+ * authentication and identity management.
+ *
+ * A user account can be in one of several states. When first created, a User should be disabled, not expired, and
+ * unlocked. To start using the account, an administrator should enable the account. The account can be locked for a
+ * number of reasons, most commonly because they have failed login for too many times. Finally, the account can expire
+ * after the expiration date has been reached. The User must be enabled, not expired, and unlocked in order to pass
+ * authentication.
+ *
+ * @author Jeff Williams at Aspect Security
+ * @author Chris Schmidt (chrisisbeef .at. gmail.com) Digital Ritual Software
+ * @since June 1, 2007
+ */
+
+public interface User extends Principal, Serializable {
+ /**
+ * @return the locale
+ */
+ Locale getLocale();
+
+ /**
+ * @param locale the locale to set
+ */
+ void setLocale(Locale locale);
+
+ /**
+ * Adds a role to this user's account.
+ *
+ * @param role
+ * the role to add
+ *
+ * @throws AuthenticationException
+ * the authentication exception
+ */
+ void addRole(String role) throws AuthenticationException;
+
+ /**
+ * Adds a set of roles to this user's account.
+ *
+ * @param newRoles
+ * the new roles to add
+ *
+ * @throws AuthenticationException
+ * the authentication exception
+ */
+ void addRoles(Set newRoles) throws AuthenticationException;
+
+ /**
+ * Sets the user's password, performing a verification of the user's old password, the equality of the two new
+ * passwords, and the strength of the new password.
+ *
+ * @param oldPassword
+ * the old password
+ * @param newPassword1
+ * the new password
+ * @param newPassword2
+ * the new password - used to verify that the new password was typed correctly
+ *
+ * @throws AuthenticationException
+ * if newPassword1 does not match newPassword2, if oldPassword does not match the stored old password, or if the new password does not meet complexity requirements
+ * @throws EncryptionException
+ */
+ void changePassword(String oldPassword, String newPassword1, String newPassword2) throws AuthenticationException, EncryptionException;
+
+ /**
+ * Disable this user's account.
+ */
+ void disable();
+
+ /**
+ * Enable this user's account.
+ */
+ void enable();
+
+ /**
+ * Gets this user's account id number.
+ *
+ * @return the account id
+ */
+ long getAccountId();
+
+ /**
+ * Gets this user's account name.
+ *
+ * @return the account name
+ */
+ String getAccountName();
+
+ /**
+ * Gets the CSRF token for this user's current sessions.
+ *
+ * @return the CSRF token
+ */
+ String getCSRFToken();
+
+ /**
+ * Returns the date that this user's account will expire.
+ *
+ * @return Date representing the account expiration time.
+ */
+ Date getExpirationTime();
+
+ /**
+ * Returns the number of failed login attempts since the last successful login for an account. This method is
+ * intended to be used as a part of the account lockout feature, to help protect against brute force attacks.
+ * However, the implementor should be aware that lockouts can be used to prevent access to an application by a
+ * legitimate user, and should consider the risk of denial of service.
+ *
+ * @return the number of failed login attempts since the last successful login
+ */
+ int getFailedLoginCount();
+
+ /**
+ * Returns the last host address used by the user. This will be used in any log messages generated by the processing
+ * of this request.
+ *
+ * @return the last host address used by the user
+ */
+ String getLastHostAddress();
+
+ /**
+ * Returns the date of the last failed login time for a user. This date should be used in a message to users after a
+ * successful login, to notify them of potential attack activity on their account.
+ *
+ * @return date of the last failed login
+ *
+ * @throws AuthenticationException
+ * the authentication exception
+ */
+ Date getLastFailedLoginTime() throws AuthenticationException;
+
+ /**
+ * Returns the date of the last successful login time for a user. This date should be used in a message to users
+ * after a successful login, to notify them of potential attack activity on their account.
+ *
+ * @return date of the last successful login
+ */
+ Date getLastLoginTime();
+
+ /**
+ * Gets the date of user's last password change.
+ *
+ * @return the date of last password change
+ */
+ Date getLastPasswordChangeTime();
+
+ /**
+ * Gets the roles assigned to a particular account.
+ *
+ * @return an immutable set of roles
+ */
+ Set getRoles();
+
+ /**
+ * Gets the screen name (alias) for the current user.
+ *
+ * @return the screen name
+ */
+ String getScreenName();
+
+ /**
+ * Adds a session for this User.
+ *
+ * @param s
+ * The session to associate with this user.
+ */
+ void addSession( HttpSession s );
+
+ /**
+ * Removes a session for this User.
+ *
+ * @param s
+ * The session to remove from being associated with this user.
+ */
+ void removeSession( HttpSession s );
+
+ /**
+ * Returns a Set containing the sessions associated with this User.
+ * @return The Set of sessions for this User.
+ */
+ Set getSessions();
+
+ /**
+ * Increment failed login count.
+ */
+ void incrementFailedLoginCount();
+
+ /**
+ * Checks if user is anonymous.
+ *
+ * @return true, if user is anonymous
+ */
+ boolean isAnonymous();
+
+ /**
+ * Checks if this user's account is currently enabled.
+ *
+ * @return true, if account is enabled
+ */
+ boolean isEnabled();
+
+ /**
+ * Checks if this user's account is expired.
+ *
+ * @return true, if account is expired
+ */
+ boolean isExpired();
+
+ /**
+ * Checks if this user's account is assigned a particular role.
+ *
+ * @param role
+ * the role for which to check
+ *
+ * @return true, if role has been assigned to user
+ */
+ boolean isInRole(String role);
+
+ /**
+ * Checks if this user's account is locked.
+ *
+ * @return true, if account is locked
+ */
+ boolean isLocked();
+
+ /**
+ * Tests to see if the user is currently logged in.
+ *
+ * @return true, if the user is logged in
+ */
+ boolean isLoggedIn();
+
+ /**
+ * Tests to see if this user's session has exceeded the absolute time out based
+ * on ESAPI's configuration settings.
+ *
+ * @return true, if user's session has exceeded the absolute time out
+ */
+ boolean isSessionAbsoluteTimeout();
+
+ /**
+ * Tests to see if the user's session has timed out from inactivity based
+ * on ESAPI's configuration settings.
+ *
+ * A session may timeout prior to ESAPI's configuration setting due to
+ * the servlet container setting for session-timeout in web.xml. The
+ * following is an example of a web.xml session-timeout set for one hour.
+ *
+ *
+ * 60
+ *
+ *
+ * @return true, if user's session has timed out from inactivity based
+ * on ESAPI configuration
+ */
+ boolean isSessionTimeout();
+
+ /**
+ * Lock this user's account.
+ */
+ void lock();
+
+ /**
+ * Login with password.
+ *
+ * @param password
+ * the password
+ * @throws AuthenticationException
+ * if login fails
+ */
+ void loginWithPassword(String password) throws AuthenticationException;
+
+ /**
+ * Logout this user.
+ */
+ void logout();
+
+ /**
+ * Removes a role from this user's account.
+ *
+ * @param role
+ * the role to remove
+ * @throws AuthenticationException
+ * the authentication exception
+ */
+ void removeRole(String role) throws AuthenticationException;
+
+ /**
+ * Returns a token to be used as a prevention against CSRF attacks. This token should be added to all links and
+ * forms. The application should verify that all requests contain the token, or they may have been generated by a
+ * CSRF attack. It is generally best to perform the check in a centralized location, either a filter or controller.
+ * See the verifyCSRFToken method.
+ *
+ * @return the new CSRF token
+ *
+ * @throws AuthenticationException
+ * the authentication exception
+ */
+ String resetCSRFToken() throws AuthenticationException;
+
+ /**
+ * Sets this user's account name.
+ *
+ * @param accountName the new account name
+ */
+ void setAccountName(String accountName);
+
+ /**
+ * Sets the date and time when this user's account will expire.
+ *
+ * @param expirationTime the new expiration time
+ */
+ void setExpirationTime(Date expirationTime);
+
+ /**
+ * Sets the roles for this account.
+ *
+ * @param roles
+ * the new roles
+ *
+ * @throws AuthenticationException
+ * the authentication exception
+ */
+ void setRoles(Set roles) throws AuthenticationException;
+
+ /**
+ * Sets the screen name (username alias) for this user.
+ *
+ * @param screenName the new screen name
+ */
+ void setScreenName(String screenName);
+
+ /**
+ * Unlock this user's account.
+ */
+ void unlock();
+
+ /**
+ * Verify that the supplied password matches the password for this user. This method
+ * is typically used for "reauthentication" for the most sensitive functions, such
+ * as transactions, changing email address, and changing other account information.
+ *
+ * @param password
+ * the password that the user entered
+ *
+ * @return true, if the password passed in matches the account's password
+ *
+ * @throws EncryptionException
+ */
+ boolean verifyPassword(String password) throws EncryptionException;
+
+ /**
+ * Set the time of the last failed login for this user.
+ *
+ * @param lastFailedLoginTime the date and time when the user just failed to authenticate correctly.
+ */
+ void setLastFailedLoginTime(Date lastFailedLoginTime);
+
+ /**
+ * Set the last remote host address used by this user.
+ *
+ * @param remoteHost The address of the user's current source host.
+ */
+ void setLastHostAddress(String remoteHost) throws AuthenticationHostException;
+
+ /**
+ * Set the time of the last successful login for this user.
+ *
+ * @param lastLoginTime the date and time when the user just successfully logged in.
+ */
+ void setLastLoginTime(Date lastLoginTime);
+
+ /**
+ * Set the time of the last password change for this user.
+ *
+ * @param lastPasswordChangeTime the date and time when the user just successfully changed his/her password.
+ */
+ void setLastPasswordChangeTime(Date lastPasswordChangeTime);
+
+ /**
+ * Returns the hashmap used to store security events for this user. Used by the
+ * IntrusionDetector.
+ */
+ HashMap getEventMap();
+
+
+ /**
+ * The ANONYMOUS user is used to represent an unidentified user. Since there is
+ * always a real user, the ANONYMOUS user is better than using null to represent
+ * this.
+ */
+ final User ANONYMOUS = new User() {
+
+ private static final long serialVersionUID = -1850916950784965502L;
+
+ private String csrfToken = "";
+ private Set